Apache Camel: why the TCP connection does not close after receiving 200 OK

We use Apache Camel as an orchestration mechanism. Typically, the following scenario:

the client sends an HTTP request ↔ CAMEL code ↔ external server (s)

The ball starts to roll when our client sends an HTTP request to our CAMEL code. Camel code will start external servers through REST HTTP calls. In the end, the Camel code will send a response to the client.

The last action before sending a response back to the client, the Camel code sends an HTTP GET to an external server. Thus, a TCP connection is established first, then data is sent. After some time (this may take 5 to 10 seconds), the external server responds with 200 OK.

Problem: Camel does not send TCP FIN to an external server after receiving 200 OK. As a result, the TCP connection remains open ... (the external server then closes the TCP connection after 200 seconds, but this means that the TCP resource has been lost for 200 seconds).

So, at the TCP level, this happens as follows:

Camel <----------> external server

TCP SYN --> <-- TCP SYN,ACK TCP ACK --> HTTP GET --> <-- 200 OK TCP ACK --> <200 seconds later> <-- TCP FIN,ACK TCP ACK --> 

Any idea how I can get Camel to close the TCP connection after it got 200 OK?

Note. I tried to add the title β€œConnection: close”, but Camel did not add the title ?! It seemed to ignore it ...

This was the code to add the header:

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

I am using Camel 2.9.1 in a Spring framework with the Eclipse IDE.

+6
source share
2 answers

Unfortunately, I have not seen a solution other than creating a custom HttpHeaderFilterStrategy class that does not filter out the Connection header. Then, before sending my request to an external server, I set the "Connection: close" header. Once this request is answered, the Camel code will then send TCP FIN, ACK to close the TCP connection.

More details:

1) create your own class HttpHeaderFilterStrategy, for example: CustomHttpHeaderFilterStrategy

2) adapt applicationContext.xml so that it points to this class, for example:

 <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) adapt your code to set the Connection: close header, for example:

 exchange.getOut().setHeader("Connection","close"); 
+4
source

HTTP1.1 communications must be considered retained after the first message for some time to allow the delivery of multiple files in a single TCP session for performance reasons. Normlly, an http server can disconnect after a few seconds to save streams while allowing multiple files to be uploaded. The Camel http component is likely to behave the same. http://en.wikipedia.org/wiki/HTTP_persistent_connection

The official HTTP client Camel relies on can be configured to use or not use persistent connections, but this is true by default: http://docs.oracle.com/javase/1.5.0/docs/guide/net/http -keepalive.html

Although I have not tried it yet, it should be possible for it to set a system property to configure this

 http.keepAlive=<boolean> 

You can set it in the context of a camel if you want

 <camelContext> <properties> <property key="http.keepAlive" value="false"/> </properties> </camelContext> 

Please note that I have not tried. If you earn, it would be nice to hear the results!

+1
source

Source: https://habr.com/ru/post/916908/


All Articles