我有两个 Tomcat 服务器需要保持持久连接以减少 SSL 握手。一台服务器(代理)位于 DMZ 中,而另一台服务器安全地位于另一个防火墙后面。代理基本上只是运行一个简单的 servlet,它在将请求转发到安全机器之前进行一些健全性检查。根据初始请求,机器在执行实际工作之前交换证书。因此,我想保持几分钟超时的持久连接。
为了与安全服务器对话,代理上的 servlet 使用 HttpsUrlConnection
。我已经设置了 WireShark,我注意到无论我为安全机器上的连接器设置什么 keepAliveTimeout
值,TCP 连接都会在大约 5 或 10 秒后关闭。这个数字似乎与我读到的默认超时以及 Java 如何处理 HTTP Keep-Alive 相符。这link解释说如果服务器发送超时,Java 会遵守 Keep-Alive
超时,否则它会在关闭连接之前使用 5 秒(直接连接)或 10 秒(代理连接)。
我想弄清楚的是如何强制 Tomcat 发送 Keep-Alive header 。不是,Connection: Keep-Alive
,而是Keep-Alive: timeout=x
。
我试验过 Apache HTTP 服务器,修改 httpd.conf 中的 keepAliveTimeout
确实会导致 Keep-Alive header 更改其超时值。此外,Java 确实遵守此超时。
更新(2011 年 12 月 23 日): 在进行了更多实验后,我尝试使用 Apache 的 HttpClient (3.1) 而不是 HttpsUrlConnection
编写一些快速而肮脏的代码.似乎 HttpClient 在设置为使用 Keep-Alive 时只是等待服务器关闭连接。虽然不知道要等多久。我打算让 HTTP 连接保持 Activity 状态 3 到 5 分钟。
最佳答案
通过将 Tomcat 连接器中的 keepAliveTimeout 设置为 300000,我能够使用 HttpClient 3.1 将 HTTP 连接保持打开状态 5 分钟。我使用 WireShark 验证了服务器将终止连接,而 HttpClient 将只是等待。通过 HttpClient 的后续请求会重用现有的 TCP 连接(避免任何进一步的 SSL 握手)。那里的关键是有一个 HttpClient 实例(即不是每次都创建一个)。这对大多数人来说可能是显而易见的,但我不确定 HTTPClient 的 API 机制是什么。简而言之,创建一个 HttpClient 实例并为每个请求(POST、GET 等)创建一个新的 PostMethod、GetMethod 等。这将导致 TCP 连接被重用。
关于java - Tomcat、HTTP Keep-Alive 和 Java 的 HttpsUrlConnection,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8607700/