我们使用Apache Camel作为编排引擎。通常,以下情形:
客户端发送HTTP请求< - > CAMEL代码< - >外部服务器
当我们的客户向我们的CAMEL代码发送HTTP请求时,球开始滚动。 Camel代码将通过REST HTTP调用触发外部服务器。 最终,Camel代码会将回复发送回客户端。
在将响应发送回客户端之前的最后一个操作,Camel代码向外部服务器发送HTTP GET。因此首先设置TCP连接,然后发送数据。一段时间后(这可能需要5到10秒),外部服务器回复200 OK。
问题:收到200 OK后,Camel不会向外部服务器发送TCP FIN。结果,TCP连接保持打开状态...(外部服务器然后在超时200秒后关闭TCP连接,但这意味着TCP资源在200秒内丢失)。
所以,在TCP级别,它是这样的:
Camel< ---------->外部服务器
TCP SYN -->
<-- TCP SYN,ACK
TCP ACK -->
HTTP GET -->
<-- 200 OK
TCP ACK -->
<200 seconds later>
<-- TCP FIN,ACK
TCP ACK -->
任何想法如何让Camel在收到200 OK之后关闭TCP连接?
注意:我尝试添加“Connection:close”标题,但是Camel没有添加标题?!它似乎忽略了它......
这是添加标题的代码:
exchange.getOut().setHeader("Connection","Close");
我在使用Eclipse IDE的Spring框架中使用Camel 2.9.1。
答案 0 :(得分:5)
不幸的是,除了创建一个不过滤掉Connection头的自定义HttpHeaderFilterStrategy类之外,我没有看到另一个解决方案。 然后在将请求发送到外部服务器之前,我设置标题“Connection:close”。一旦该请求得到回复,Camel代码就会发送TCP FIN,ACK以关闭TCP连接。
更多详情:
1)创建一个自定义的HttpHeaderFilterStrategy类,例如:CustomHttpHeaderFilterStrategy
2)调整applicationContext.xml,使其指向该类,例如:
<bean id="http" class="org.apache.camel.component.http.HttpComponent">
<property name="camelContext" ref="camel"/>
<property name="headerFilterStrategy" ref="myHeaderFilterStrategy"/>
</bean>
<bean id="myHeaderFilterStrategy" class="com.alu.iptc.com.CustomHttpHeaderFilterStrategy">
</bean>
3)调整你的代码,以便设置Connection:close标头,例如:
exchange.getOut().setHeader("Connection","close");
答案 1 :(得分:1)
HTTP1.1连接被认为在第一个消息暂停一段时间后保持活动状态,以便出于性能原因允许在一个TCP会话中传递多个文件。 Normlly,http服务器可能会在几秒钟后切断连接以保存线程,同时允许下载多个文件。 Camel http组件可能会以相同的方式运行。 http://en.wikipedia.org/wiki/HTTP_persistent_connection
Camel所依赖的官方HTTP客户端可以配置为使用或不使用持久连接,但默认为true: http://docs.oracle.com/javase/1.5.0/docs/guide/net/http-keepalive.html
虽然我没有尝试过,但应该可以设置系统属性来配置这个
http.keepAlive=<boolean>
如果你想要
,你应该可以在驼峰上下文中设置它<camelContext>
<properties>
<property key="http.keepAlive" value="false"/>
</properties>
</camelContext>
请注意,我还没试过。如果你使它工作,听到结果会很高兴!