7

Bottom Line: I'm trying to understand if ColdFusion is able to make use of a persistent http connection outside of a single request via the CFHTTP tag. Some of this post is "what have I found/tried."

My system: CF10 IIS7.5 Windows 7

I am currently hooking into ElasticSearch via an HTTP Rest interface which will have a magnitude of cfhttp calls. In this case, ColdFusion is the Client and ElasticSearch is the server. As recommended, I passed the keep-alive header along with the cfhttp request, but found the CFHTTP seemed to always add a close right after it resulting in this header:

<!--- Calling tag --->
<cfhttp url="loc.mysite.com?endpoint" 
    method="POST"
    result="ret">
<cfhttpparam type="HEADER" name="Keep-Alive" value="300">
<cfhttpparam type="HEADER" name="Connection" value="keep-alive">
<cfhttpparam type="xml" value="#body#" />
</cfhttp>
<!--- Results in this  header. (dumping getHTTPrequestdata() on a dummy page) --->
connection: keep-alive,closed

First, I cannot figure out how to prevent the close from occurring.

Second, I cannot figure out if ColdFusion would reuse the connection, even if it is sent without the close during the same request or outside of this request. Clearly this has to do with how Java is interacting with the OS at this point. Initially, I thought it would be handled by the magic of ColdFusion, but I'm beginning to think that it is not using any of the fancy Java pooling magic.

Third, I cannot find any documentation on http connection pooling in ColdFusion. It does DB connection pooling just fine, but http pooling is probably a relatively new requirement.

Fourth, I have found the CFX_http5 is still working in ColdFusion 10 with Tomcat (what are the chances). While it is good at multithreading requests, there is little mention of how the keep-alive is used. Without purchasing it, I can't test it inside a loop. It does not add the close header. It sends keep alive as I would expect.

Sixth (edited heavily since initial post) Sixth, Windows has a default number of temporary or "ephemeral" ports that it can make use of to spawn new outbound TCP connections. By default, once a connection is opened, Windows will keep it alive for two minutes (although it's just abandoned and taking up space at this point). This is a TCP configuration, so http headers aren't directly at play here. The default number of ports available is 5,000 less 1024 = 3076 ports. This means all ColdFusion instances on a box could make up to 3076 http requests in any given two minute window without being choked waiting on an available connection port. If too many requests are flooded (I have no idea at what point), you will receive a "connection closed" error. This reminds me of garbage collection at a primitive level. So, up the level in the registry (see post) below and you avoid these chokes, but you are still experiencing connection setup/tear down delays and this solution will not scale.

Update: CFX_HTTP5 does support keep-alive and persistent connections as expected within a single ColdFusion request. My 150K query test to my ElasticSearch endpoint previously ran in 15 minutes. With CFX_HTTP5, it ran in 4 minutes. In addition, I was able to switch the registry back to the default number of ports. The next step is to figure out if HTTPComponents will work. I have that nearly working.

Update 2:: Built out a custom http call using the HTTPcomponents suggested below. I used a basic connection pool manager with default settings. I have not attempted to tune it yet. The process finished in 5 minutes which is a tad slower than cfx_http5, but still a lot faster than cfhttp. In addition, I have not done tests involving multiple ColdFusion requests to really test the connection pool.

Update 3: I verified that HTTPComponents is indeed setting up a proper connection pool. However, with this comes a responsibility to properly manage those connections and the pool itself to ensure it is a good steward of system resources. I was able to run several million HTTP requests from several different simultaneous requests while only opening a small handful of HTTP connections. From the logs, I was able to see how many connections were being used, idle, or spun-up. It's really not that much code either, the people behind the project have great documentation.

HTTPComponents Connection Pool:
Single request, unlimited CFHTTP to same connection = single open TCP connection
N-requests = <N open TCP connections. 

CFHTTP
N-CFHTTP calls + N-CFHTTP calls in previous 60 seconds = open TCP connections

Reference: I did find that Java has this available, which shows that it's in the realm of possibility, but who knows how Adobe has implemented CFHTTP Persistent Http client connections in java

CFX_http5 custom tag uses C++ for custom http connections, so it's possible that it understands connection pooling. http://www.cftagstore.com/tags/cfxhttp5.cfm

A related question: Maintain Outbound TCP Connection Pool in ColdFusion

About Windows Max Connections/Ephemeral ports http://kb.globalscape.com/KnowledgebaseArticle10438.aspx

4

2 回答 2

2

我 99% 确定 CFHTTP 不支持持久连接,它只是没有设置来处理它。我认为你真的需要一个不同的 API 来处理连接和单个请求。我手头没有CF10,但CF9有一个2001年的HTTPClient版本,所以我希望CF团队更新CF10!

我希望使用基于 Java 的 HTTP 库,例如HTTPClient。从功能列表中:“连接管理支持在多线程应用程序中使用。支持设置最大总连接数以及每台主机的最大连接数。检测并关闭陈旧的连接”

于 2013-07-03T08:53:30.983 回答
0

几年前我能看到的是 Ben Nadel 的 CFHTTPSession.cfc

http://www.bennadel.com/projects/cfhttp-session.htm

就在我发现这一点时,我从事的项目的需求发生了变化,所以我从来没有真正尝试过,但可能值得一看

于 2013-07-21T06:25:19.070 回答