Tomcat、HTTP保活及Java的HttpUrl连接

6qfn3psc  于 2023-03-12  发布在  Java
关注(0)|答案(4)|浏览(134)

我有两个Tomcat服务器,它们需要保持持久连接以减少SSL握手。(代理)位于DMZ中,而另一个安全地位于另一个防火墙后面。代理基本上只是运行一个简单的servlet,在将请求转发到安全机器之前,它会进行一些健全性检查。在初始请求时,机器会在执行真实的工作之前交换证书。因此,我“我想保持一个超时几分钟的持久连接。
为了与安全服务器通信,代理上的servlet使用HttpsUrlConnection。我设置了WireShark,并注意到无论为安全机器上的connector设置什么keepAliveTimeout值,TCP连接在大约5或10秒后关闭。这个数字似乎与我读到的默认超时和Java处理HTTP保持活动的方式相匹配。link解释了如果Keep-Alive超时是由服务器发送的,那么Java会遵守它,否则它会在关闭连接之前使用5秒(直接连接)或10秒(代理连接)。
我想弄明白的是如何强制Tomcat发送Keep-Alive头,不是Connection: Keep-Alive,而是Keep-Alive: timeout=x
我曾经用Apache HTTP服务器做过实验,修改httpd.conf中的keepAliveTimeout确实会导致Keep-Alive头改变它的超时值,而且Java也会荣誉这个超时。

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

nkoocmlb

nkoocmlb1#

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

lfapxunr

lfapxunr2#

在Tomcat中,我设法使用HttpServletResponse.addHeader()在我的HttpServelet中设置头,如下所示:

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

我向WireShark确认了这确实可以在客户端与HttpUrlConnection一起工作。如果不设置“Connection”头,它就不工作,所以需要同时设置这两个头。

vmdwslir

vmdwslir3#

Java API Http(s)UrlConnection无缝地处理Keep-Alive信息,并根据following detailed explanation管理每个服务器主机的连接池(仔细阅读-每个细节都很重要)。
在这种情况下,您的代码必须完全读取缓冲区,关闭流,并在IOException的情况下读取错误。
当然,HttpClient的约束较少,但处理这种情况的最佳方法是使用它的MultiThreadedHttpConnectionManager,这要归功于following guidelines

rsl1atfo

rsl1atfo4#

如果可以将第一个(外部)服务器升级到Java 19或更高版本,则可以使用此Java系统属性,该属性在服务器未指定客户端保持活动时间时设置客户端保持活动时间:

http.keepAlive.time.server=60

默认值为5秒。上面将其设置为1分钟。在连接的客户端将其更改为更高的值将解决您的问题(注意:仅适用于Java 19及更高版本)。

相关问题