7

我们使用 Apache Camel 作为编排引擎。通常,以下场景:

客户端发送 HTTP 请求 <-> CAMEL 代码 <-> 外部服务器

当我们的客户端向我们的 CAMEL 代码发送 HTTP 请求时,球开始滚动。Camel 代码将通过 REST HTTP 调用触发外部服务器。最终,Camel 代码会将回复发送回客户端。

在将响应发送回客户端之前的最后一个操作,Camel 代码向外部服务器发送 HTTP GET。因此,首先建立 TCP 连接,然后发送数据。一段时间后(这可能需要 5 到 10 秒),外部服务器回复 200 OK。

问题:Camel在收到200 OK后没有向外部服务器发送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 连接吗?

注意:我尝试添加“连接:关闭”标题,但骆驼没有添加标题?!它似乎忽略了它......

这是添加标题的代码:

exchange.getOut().setHeader("Connection","Close");

我在带有 Eclipse IDE 的 Spring 框架中使用 Camel 2.9.1。

4

2 回答 2

4

不幸的是,除了创建一个不过滤掉 Connection 标头的自定义 HttpHeaderFilterStrategy 类之外,我没有看到其他解决方案。然后在将我的请求发送到外部服务器之前,我设置了标题“连接:关闭”。一旦这个请求得到回复,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");
于 2012-06-04T13:02:10.183 回答
1

HTTP1.1 连接被认为在第一条消息之后保持活动一段时间,以允许出于性能原因在一个 TCP 会话中传递多个文件。通常,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>

请注意,我还没有尝试过。如果你让它工作,很高兴听到结果!

于 2012-05-31T06:37:52.567 回答