我已经将 Apache 设置为 Java 应用程序服务器(GlassFish)的反向代理,并且我注意到即使在空闲的开发系统上也有大约 100 个连接处于 CLOSE_WAIT 状态:
sudo netstat -n -e -p -a -t | grep httpd | grep CLOSE_WAIT | wc -l
我正在使用以下 HTTP 代理设置:
ProxyPass /myapp http://localhost:8080/myapp ttl=20 max=1 smax=0
ProxyPassReverse /myapp http://localhost:8080/myapp
为什么所有这些连接都挂起?我已设置“ttl=20 max=1 smax=0”,因此我认为空闲系统上的所有连接都会被清除。应用服务器没有尽其所能清除连接吗?
答案1
这是一个mod_proxy 的已知问题,自 2011 年起。
ttl 需要比应用程序的 keepalive 短,以便 apache 总是首先发送 FIN。
另一个困难是没有定义什么时候连接才会真正关闭。
ttl - 不活动连接和相关连接池条目的生存时间(以秒为单位)。一旦达到此限制,连接将不再使用;它将在以下时间关闭:稍后。
答案2
我遇到了类似的问题,正在寻找与 Apache 相关的原因。我怀疑是 Apache 的预分叉。
至于解决方案,我使用了 Nginx,解决了 CLOSE_WAIT 问题。但是 TIME_WAIT 的数量(大约 20,000)表明 Java 应用程序处理连接的方式存在问题。使用 Nginx 服务器和应用程序的性能要好得多。
我希望有人能够从技术深度上改进这个答案。
答案3
这些 CLOSE_WAIT 连接已失效,服务器只是将它们保存在 tcp 堆栈中,以防其他数据包到达它们。在“过去的美好时光”中,如果文件描述符太大,Solaris 服务器就会用完文件描述符,系统就会崩溃。我们必须增加内核中允许的总文件描述符数量,并减少 CLOSE_WAIT 连接的清理间隔。
如今,默认的文件描述符数量通常足够大,可以忽略此问题。但可以减少清理配置,因此 CLOSE_WAIT 连接的数量将减少。
这些 (Glassfish、Tomcat、JBoss 等) 的本质就是使用“大量”连接,并且不重复使用它们。在大多数情况下,您可以放心地忽略它们。