Tomcat,HTTP Keep-Alive和Java的HttpsUrlConnection

时间:2011-12-22 17:31:55

标签: java tomcat httpurlconnection keep-alive

我有两台Tomcat服务器需要维持持久连接以减少SSL握手。一台服务器(代理)位于DMZ中,而另一台服务器安全地位于另一台防火墙后面。代理基本上只运行一个简单的servlet,在将请求转发到安全机器之前进行一些健全性检查。在初始请求中,机器在执行实际工作之前交换证书。因此,我希望在几分钟的超时时间内保持持久连接。

要与安全服务器通信,代理上的servlet使用HttpsUrlConnection。我已经设置了WireShark,我注意到无论我在安全机器上为连接器设置了什么keepAliveTimeout值,TCP连接在大约5或10秒后关闭。这个数字似乎与我所读到的是默认超时以及Java如何处理HTTP Keep-Alive。这个link解释说,如果服务器发送了Java,{@ 1}}超时,否则它会在关闭连接之前使用5秒(直接连接)或10秒(代理连接)。

我想弄清楚的是如何强制Tomcat发送Keep-Alive标头。不是Keep-Alive,而是Connection: Keep-Alive

我已经尝试过Apache HTTP服务器并修改httpd.conf中的Keep-Alive: timeout=x会导致Keep-Alive标头更改其超时值。此外,Java确实遵守此超时。

更新(12/23/11):在运行了几个实验后,我尝试使用Apache的HttpClient(3.1)而不是keepAliveTimeout来编写一些快速而脏的代码。看来HttpClient在设置为使用Keep-Alive时,只是等待服务器关闭连接。我不知道它会等多久。我正在拍摄以保持HTTP连接活动3到5分钟。

3 个答案:

答案 0 :(得分:8)

我可以使用HttpClient 3.1通过将Tomcat连接器中的keepAliveTimeout设置为300000来保持HTTP连接打开5分钟。我使用WireShark验证了服务器将终止连接,而HttpClient只是等待。通过HttpClient的后续请求重用现有的TCP连接(避免任何进一步的SSL握手)。但关键是要有一个HttpClient实例(即每次都不创建一个)。这对大多数人来说可能是显而易见的,但我不确定HTTPClient的API机制是什么。简而言之,创建一个HttpClient实例,并为每个请求(POST,GET等)创建一个新的PostMethod,GetMethod等。这将导致重用TCP连接。

答案 1 :(得分:5)

在Tomcat中,我设法使用HttpServletResponse.addHeader()在我的HttpServelet中设置标题:

  response.addHeader("Connection", "Keep-Alive");
  response.addHeader("Keep-Alive", "timeout=60000");

我与WireShark确认这可以在客户端使用HttpUrlConnection。如果您没有设置“连接”标题,则它不起作用,因此您需要同时设置它们。

答案 2 :(得分:2)

Java API Http(s)UrlConnection无缝地尊重Keep-Alive信息,并根据following detailed explanation管理每个服务器主机的连接池(仔细阅读 - 每个细节都很重要)。

在这种情况下,如果IOException,您的代码必须完全读取缓冲区,关闭流和读取错误。

当然HttpClient的约束较少,但处理您情况的最佳方法是使用MultiThreadedHttpConnectionManager来使用following guidelines