我让 Apache 在 3 个 Tomcat 服务器前充当负载平衡器。有时,Apache 会返回 503 响应,我想将其完全删除。就 CPU、内存或磁盘而言,所有 4 台服务器都没有承受很大的负载,所以我有点不确定是什么达到了它的限制或为什么。当所有工作人员都处于错误状态时返回 503 - 不管这意味着什么。以下是详细信息:
阿帕奇配置:
<IfModule mpm_prefork_module>
StartServers 30
MinSpareServers 30
MaxSpareServers 60
MaxClients 200
MaxRequestsPerChild 1000
</IfModule>
...
<Proxy *>
AddDefaultCharset Off
Order deny,allow
Allow from all
</Proxy>
# Tomcat HA cluster
<Proxy balancer://mycluster>
BalancerMember ajp://10.176.201.9:8009 keepalive=On retry=1 timeout=1 ping=1
BalancerMember ajp://10.176.201.10:8009 keepalive=On retry=1 timeout=1 ping=1
BalancerMember ajp://10.176.219.168:8009 keepalive=On retry=1 timeout=1 ping=1
</Proxy>
# Passes thru track. or api.
ProxyPreserveHost On
ProxyStatus On
# Original tracker
ProxyPass /m balancer://mycluster/m
ProxyPassReverse /m balancer://mycluster/m
Tomcat 配置:
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
<Listener className="org.apache.catalina.core.JasperListener" />
<Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Service name="Catalina">
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
<Engine name="Catalina" defaultHost="localhost">
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">
</Engine>
</Service>
</Server>
阿帕奇错误日志:
[2010 年 3 月 22 日星期一 18:39:47] [错误] (70007) 指定的超时已过期:代理:AJP:尝试连接到 10.176.201.10:8009 (10.176.201.10) 失败 [2010 年 3 月 22 日星期一 18:39:47] [错误] ap_proxy_connect_backend 禁用(10.176.201.10)的工作人员 [2010 年 3 月 22 日星期一 18:39:47] [错误] 代理:AJP:无法连接到后端:10.176.201.10 [2010 年 3 月 22 日星期一 18:39:47] [错误](70007)指定的超时已过期:代理:AJP:尝试连接到 10.176.201.9:8009(10.176.201.9)失败 [2010 年 3 月 22 日星期一 18:39:47] [错误] ap_proxy_connect_backend 禁用 (10.176.201.9) 的工作人员 [2010 年 3 月 22 日星期一 18:39:47] [错误] 代理:AJP:无法连接到后端:10.176.201.9 [2010 年 3 月 22 日星期一 18:39:47] [错误] (70007) 指定的超时已过期:代理:AJP:尝试连接到 10.176.219.168:8009 (10.176.219.168) 失败 [2010 年 3 月 22 日星期一 18:39:47] [错误] ap_proxy_connect_backend 禁用(10.176.219.168)的工作人员 [2010 年 3 月 22 日星期一 18:39:47] [错误] 代理:AJP:无法连接到后端:10.176.219.168 [2010 年 3 月 22 日星期一 18:39:47] [错误] 代理:BALANCER:(balancer://mycluster)。所有工作人员都处于错误状态 [2010 年 3 月 22 日星期一 18:39:47] [错误] 代理:BALANCER:(balancer://mycluster)。所有工作人员都处于错误状态 [2010 年 3 月 22 日星期一 18:39:47] [错误] 代理:BALANCER:(balancer://mycluster)。所有工作人员都处于错误状态 [2010 年 3 月 22 日星期一 18:39:47] [错误] 代理:BALANCER:(balancer://mycluster)。所有工作人员都处于错误状态 [2010 年 3 月 22 日星期一 18:39:47] [错误] 代理:BALANCER:(balancer://mycluster)。所有工作人员都处于错误状态 [2010 年 3 月 22 日星期一 18:39:47] [错误] 代理:BALANCER:(balancer://mycluster)。所有工作人员都处于错误状态
负载均衡器top
信息:
top - 23:44:11 up 210 天,4:32,1 个用户,平均负载:0.10、0.11、0.09 任务:总共 135 个,运行 2 个,睡眠 133 个,停止 0 个,僵尸 0 个 中央处理器:0.1%us、0.2%sy、0.0%ni、99.2%id、0.1%wa、0.0%hi、0.1%si、0.3%st 内存:总共 524508k,已使用 517132k,空闲 7376k,9124k 缓冲区 交换:总计 1048568k,已使用 352k,免费 1048216k,缓存 334720k
雄猫top
信息:
top - 23:47:12 up 210 天,3:07,1 个用户,平均负载:0.02、0.04、0.00 任务:总共 63 个,1 个正在运行,62 个正在睡眠,0 个停止,0 个僵尸 中央处理器:0.2%us、0.0%sy、0.0%ni、99.8%id、0.1%wa、0.0%hi、0.0%si、0.0%st 内存:总共 2097372k,已使用 2080888k,可用 16484k,21464k 缓冲区 交换:总计 4194296k,已使用 380k,免费 4193916k,缓存 1520912k
Catalina.out 中没有任何错误消息。
根据 Apache 的服务器状态,它似乎达到了 143 个请求/秒的最大值。我相信服务器可以处理比它们实际更多的负载,因此任何有关低默认限制或其他原因导致此设置最大化的提示将不胜感激。
这个问题的解决方案非常简单:
添加到代理通行证:
BalancerMember ajp://10.176.201.9:8009 keepalive=On ttl=60
添加到 Tomcats Server.xml:
连接器端口="8009" 协议="AJP/1.3" redirectPort="8443 connectionTimeout="60000"
在这些更改之后,一切都应该正常工作:-)
看起来 Apache 连接到池中的服务器时出现连接超时,这导致它无法为请求提供服务。您的超时值看起来非常低、间歇性的网络延迟,甚至是需要一些额外时间来生成的页面,都可能导致服务器从池中退出。我会尝试更高的超时和重试值,可能还有更高的 ping 值。
你也可以考虑切换到worker或者event mpm,prefork mpm一般性能最差。
专用代理/平衡器软件,例如squid,也可能是一个不错的选择。
鉴于 Apache 日志说明它无法连接到 Tomcat(从您的错误日志中),它似乎是 Tomcat 应用程序无法跟上。
当我作为一个大型 Tomcat 网站的系统管理员工作时,我注意到严重的性能限制,它们不是 CPU,而是线程之间的同步问题或查询后端 Web 服务的延迟。
后者是一个大问题,因为流行的 Java HTTP 接口默认将同时连接到另一个 Web 服务器的数量限制为 2(当我发现这一点时,我的下巴掉了下来)。见http://hc.apache.org/httpclient-3.x/threading.html
您的网络应用程序是否调用任何其他网络服务?
你的tomcat实例死锁了吗?我目睹了两个大型公司(不同公司)的 tomcat 项目陷入僵局 - 一个是由使用旧版本的 3rd-party 库引起的。
您仍然可以直接连接到本地的tomcat实例吗?那是:
然后输入:
(这里
\n
指的是 <enter> 键)。如果不是,那么您的 tomcat 实例似乎已经死亡或死锁。如果它已经死锁,那么是时候使用该
jstack
程序(使用 tomcat java 程序的 PID)获取您的 tomcat java 实例的堆栈转储了。考绩制度,
我没有在您粘贴的 Apache 日志中看到超时值。如果是 300,请尝试将其更改为 1200。我们遇到了同样的问题,将 Apache httpd.conf 文件的超时时间从 300 更改为 1200 修复了它。
我遇到了完全相同的问题。在问题发生时进行线程转储,您将知道哪个线程被阻塞,从而也阻塞其他线程。与此同时,所有 AJP 端口都被使用,最终 Apache 死掉了。但这个问题与 Apache 设置无关。问题在于应用程序(tomcat 级别)。
让我们在 6 年后回答这个问题 =D
那就是问题所在。超时和重试太短了。
如果服务器在 1 秒内没有响应,超时将认为服务器已死亡。处理一些请求的时间太短了(特别是如果您以 500 req/s 的速度进行负载测试)。
请注意,一旦服务器出现故障,剩下的 2 台服务器会收到 +50% 的请求,并且它们的响应时间会显着增加,以至于它们也可能会立即超时。典型的级联故障。
你得到 503 "Service Unavailable" 因为所有服务器都被 Apache 认为是死的,因为它们在负载下响应速度不够快,因为你的超时时间太短了。
删除这两个设置。一般来说,永远不要在任何地方配置低于 5 秒的超时。