2012-05-29 64 views
6

我們使用Apache Camel作爲編排引擎。典型地,存在以下情況:Apache Camel:爲什麼在接收200 OK後TCP連接沒有關閉

客戶端發送的HTTP請求< - > CAMEL代碼< - >外部服務器(S)

球啓動時我們的客戶端發送一個HTTP請求到我們的CAMEL代碼滾動。 駱駝代碼將通過REST HTTP調用觸發外部服務器。 最終,駱駝代碼會將回復發送回客戶端。

在將響應發送回客戶端之前的最後一個操作是,駱駝代碼向外部服務器發送HTTP GET。所以首先要設置TCP連接,然後發送數據。一段時間後(這可能需要5到10秒),外部服務器回覆200 OK。

問題:在收到200 OK後,駱駝不會向外部服務器發送TCP FIN。因此,TCP連接保持打開狀態(外部服務器在超過200秒後關閉TCP連接本身,但這意味着在200秒內丟失TCP資源)。

所以,在TCP層,它是這樣的:

駱駝< ---------->外部服務器

TCP SYN --> 
    <-- TCP SYN,ACK 
    TCP ACK --> 

    HTTP GET --> 
    <-- 200 OK 
    TCP ACK --> 

    <200 seconds later> 
    <-- TCP FIN,ACK 
    TCP ACK --> 

任何想法,我怎麼會有駱駝關閉它已經收到200 OK後的TCP連接?

注:我試着添加「連接:關閉」標題,但駱駝沒有添加標題?!它似乎忽略它...

這是添加頁眉代碼:

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

我使用駱駝2.9.1與Eclipse IDE的一個Spring框架。

+0

你使用哪一種駱駝http組件? –

+0

嗨,我正在使用駱駝2.9.2(不是2.9.1,正如我前面提到的:()和駱駝 - http-2.9.2.jar(和commons-httpclient-3.1.jar)。 – opstalj

+0

您可以重現此行爲與任何HTTP服務器?或客戶端的服務器是唯一一個不關閉連接? –

回答

4

不幸的是,我沒有看到另一個解決方案,而不是創建一個自定義的HttpHeaderFilterStrategy類,它不會過濾出Connection頭。 然後在將請求發送到外部服務器之前,我將標題設置爲「Connection:close」。只要這個請求得到答覆,駱駝代碼就會發送一個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

出於性能原因,HTTP1.1連接將被視爲在第一條消息之後保持活動狀態,以允許在一個TCP會話中傳遞多個文件。 Normlly,http服務器可能會在幾秒鐘後斷開連接以保存線程,同時允許下載多個文件。 Camel http組件可能會以相同的方式運行。 其中駱駝依賴於http://en.wikipedia.org/wiki/HTTP_persistent_connection

官方HTTP客戶端可以配置使用或不使用永久連接,但默認情況下是正確的: 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> 

請注意,我還沒有嘗試過。如果你使它工作,聽到結果會很高興!

+0

太糟糕了,試過了,但它似乎沒有任何影響...應該有辦法告訴駱駝應用程序所有需要的信息都已收到,因此TCP連接可以關閉,對吧? – opstalj

+0

嘗試將它設置爲系統屬性然後在Java中的HTTP4客戶端應該選擇這個 –

+0

難道這就是區別:我正在使用plainHTTP組件,而不是HTTP4之一...? – opstalj