我们在Tomcat 6和Apache mod_proxy 2.2.3上运行Web应用程序。看到很多像这样的502错误:
坏网关! 代理服务器从上游服务器收到无效响应。
代理服务器无法处理请求GET /the/page.do。
原因:从远程服务器读取错误
如果您认为这是服务器错误,请与网站管理员联系。
错误502
Tomcat有很多线程,所以它不受线程限制。我们正在通过JMeter推动2400名用户对抗该应用。所有的盒子都位于我们的防火墙内快速卸载的网络上,所以不应该有任何网络问题。
任何人都有任何建议可以查看或尝试?接下来我们将前往tcpdump。
2008年10月21日更新:仍然没有想到这一点。只看到极少数这些负载。下面的答案还没有提供任何神奇的答案。 :)
答案 0 :(得分:42)
只是添加一些特定的设置,我有类似的设置(使用Apache 2.0.63反向代理到Tomcat 5.0.27)。
对于某些URL,Tomcat服务器可能需要20分钟才能返回页面。
我最终修改了Apache配置文件中的以下设置,以防止它通过代理操作超时(如果Tomcat花费更长时间返回页面,则会出现大量溢出因素):
Timeout 5400
ProxyTimeout 5400
我发现如果我将Timeout设置保留为默认值(300秒),那么如果对Tomcat的代理请求花费的时间超过300秒以获得响应,则浏览器将显示“502 Proxy Error”页面。我相信这条消息是由Apache生成的,知道它在充当反向代理之前,它关闭了与浏览器的连接(这是我目前的理解 - 它可能有缺陷)。
代理错误页面显示:
代理错误
代理服务器收到无效 来自上游服务器的响应。该 代理服务器无法处理 请求GET。
原因:从远程服务器读取错误
...这表明它的ProxyTimeout设置太短,而调查显示Apache的Timeout设置(Apache和客户端之间的超时)也会影响这一点。
答案 1 :(得分:13)
所以,在这里回答我自己的问题。我们最终确定,由于Tomcat线程超时,我们在负载均衡器中看到502和503错误。在短期内,我们增加了超时。从长远来看,我们首先修复了导致超时的应用程序问题。为什么Tomcat超时被认为是负载均衡器上的502和503错误仍然有点神秘。
答案 2 :(得分:8)
你可以使用 代理初始未合并
请参阅http://httpd.apache.org/docs/2.2/mod/mod_proxy_http.html:
如果设置了此变量,则如果客户端连接是初始连接,则不会重用池化连接。这避免了由代理进行连接检查后以及代理发送的数据到达后端之前后端服务器关闭池连接的竞争条件导致的“代理:从远程服务器读取错误状态行”错误消息。必须记住,设置此变量会降低性能,尤其是对于HTTP / 1.0客户端。
我们也有这个问题。我们通过添加
来修复它SetEnv proxy-nokeepalive 1
SetEnv proxy-initial-not-pooled 1
并关闭所有服务器上的keepAlive
。
mod_proxy_http在大多数情况下都很好,但是我们在负载很重的情况下运行它,我们仍然遇到一些我们不理解的超时问题。
但看看上述指令是否符合您的需求。
答案 3 :(得分:3)
来自apache conf的示例:
#Default值为2分钟
超时600
ProxyRequests off
ProxyPass / app balancer:// MyApp stickysession = JSESSIONID lbmethod = bytraffic nofailover = On
ProxyPassReverse / app balancer:// MyApp
ProxyTimeout 600
<代理平衡器:// MyApp>
BalancerMember http://node1:8080/ route = node1 retry = 1 max = 25 timeout = 600
.........
< /代理>
答案 4 :(得分:2)
我猜你正在使用mod_proxy_http(或代理平衡器)。
查看您的tomcat日志(localhost.log或catalina.log)我怀疑您在Web堆栈中看到异常,并且关闭了tomcat worker连接到的套接字。
答案 5 :(得分:2)
您应该能够通过将timeout和proxyTimeout参数设置为600秒来解决此问题。在战斗了一段时间后,它对我有用。
答案 6 :(得分:2)
您可以通过在ProxyPass指令中指定代理超时来避免全局超时或拥有虚拟主机,如下所示:
ProxyPass /svc http://example.com/svc timeout=600
ProxyPassReverse /svc http://example.com/svc timeout=600
注意timeout=600
秒。
但是,当您有负载均衡器时,这并不总是有效。在这种情况下,您必须在两个地方添加超时(在Apache 2.2.31中测试)
Load Balancer示例:
<Proxy "balancer://mycluster">
BalancerMember "http://member1:8080/svc" timeout=600
BalancerMember "http://member2:8080/svc" timeout=600
</Proxy>
ProxyPass /svc "balancer://mycluster" timeout=600
ProxyPassReverse /svc "balancer://mycluster" timeout=600
附注:当Chrome是客户端时我不需要timeout=600
上的ProxyPass
(我不知道原因)但是ProxyPass
Internet Explorer上没有此超时(11)中止说服务器重置连接。
我的理论是:
在客户端(浏览器)和Apache之间使用 ProxyPass
超时。
BalancerMember
超时。
对于使用Tomcat或其他支持的用户,您可能还需要注意HTTP连接器的超时。
答案 7 :(得分:1)
最有可能的是你应该在apache conf中增加Timeout参数(默认值为120秒)
答案 8 :(得分:0)
我知道这不能回答这个问题,但是我之所以来到这里是因为我在nodeJS服务器上遇到了同样的错误。我被困了很长时间,直到找到解决方案。我的解决方案只是在proxyreserve apache末尾添加了斜杠或/
。
我的旧代码是:
ProxyPass / http://192.168.1.1:3001
ProxyPassReverse / http://192.168.1.1:3001
正确的代码是:
ProxyPass / http://192.168.1.1:3001/
ProxyPassReverse / http://192.168.1.1:3001/
答案 9 :(得分:0)
如果要使用apache负载平衡器处理webapp的超时,则首先必须了解timeout
的不同含义。
我试图浓缩在这里找到的讨论::
看来
mod_proxy
仅在以下情况下才将后端视为失败的: 与该后端的传输层连接失败。除非使用failonstatus/failontimeout
。 ...
因此,必须设置failontimeout
才能使apache将Web应用程序的超时(例如,由tomcat服务)视为失败(并连续切换到热备用服务器)。为了进行正确的配置,请注意以下错误配置:
ProxyPass / balancer:// localbalance / failontimeout = on timeout = 10 failonstatus = 50
这是一个错误的配置,因为:
您在此处定义
balancer
,因此timeout
参数与balancer
(与其他两个一样)。 但是对于balancer
,timeout
参数不是连接 超时(例如与BalancerMember
一起使用的超时),但最长时间 等待空闲的员工/成员(例如,当所有员工都忙时 或处于错误状态,默认为不等待。
因此,可以像这样完成正确的配置
timeout
级设置BalanceMember
: <Proxy balancer://mycluster>
BalancerMember http://member1:8080/svc timeout=6
... more BalanceMembers here
</Proxy>
failontimeout
上设置balancer
ProxyPass /svc balancer://mycluster failontimeout=on
重新启动Apache。