我们在负载均衡器后面运行两个独立的 tomcat 服务器 (tomcat 7),并在同一个主机上运行一个作为代理的 Apache (v. 2.2)。每个服务器运行大约 70 个微服务,这些微服务可从远程 Liferay 系统和另一个包含业务逻辑服务的服务器集群访问。
问题:大约每隔一到两天,接受负载均衡器请求并将其传递给 tomcat 的 apache 似乎突然无法连接,因此会不断生成工作进程,直到达到其极限。然后 tomcat 就完全无法访问了。
错误消息httpd/错误日志看起来像这样(重复多次):
[.... 2018] [error] (70007)The timeout specified has expired:
ajp_ilink_receive() can't receive header
我们还观察到数百个 TCP 连接处于 CLOSE-WAIT 状态。奇怪的是,我们在 catalina.out 中没有观察到任何错误消息。服务器的 CPU 和内存使用率在安全限度内。
我们认为问题可能与某个微服务未能正确处理连接有关(正如我们在线程转储中观察到的许多线程使用处于 WAITING 状态的 HttpClient)。
无论如何,问题仍然是这是否也可能是 Tomcat 或 Apache 的配置问题,或者是否可以以某种方式更改配置以使服务器更具弹性。
有什么建议吗?相关配置信息如下:
tomcat 服务器.xml
<Connector port="8080"
protocol="HTTP/1.1"
connectionTimeout="20000"
compression="on"
noCompressionUserAgents="gozilla, traviata"
compressableMimeType="text/html,text/xml,text/css,text/javascript,text/plain"
redirectPort="8443"
URIEncoding="UTF-8"
maxThreads="200"
acceptCount="800"
maxHttpHeaderSize="8192"
maxKeepAliveRequests="-1" />
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443"/>
Apache httpd.conf 文件
Timeout 60
RLimitCPU max
RLimitMEM max
KeepAlive Off
MaxKeepAliveRequests 100
KeepAliveTimeout 5
<IfModule prefork.c>
StartServers 16
MinSpareServers 8
MaxSpareServers 20
ServerLimit 350
MaxClients 350
MaxRequestsPerChild 4000
</IfModule>
apache vhosts.conf
ProxyPass / ajp://localhost:8009/ keepalive=on retry=0 timeout=60 ping=120
connectiontimeout=120