Apache mod_proxy和Tomcat出现Bad Gateway 502错误

时间:2008-10-04 00:51:54

标签: java apache tomcat mod-proxy

我们在Tomcat 6和Apache mod_proxy 2.2.3上运行Web应用程序。看到很多像这样的502错误:

  

坏网关!   代理服务器从上游服务器收到无效响应。

     

代理服务器无法处理请求GET /the/page.do。

     

原因:从远程服务器读取错误

     

如果您认为这是服务器错误,请与网站管理员联系。

     

错误502

Tomcat有很多线程,所以它不受线程限制。我们正在通过JMeter推动2400名用户对抗该应用。所有的盒子都位于我们的防火墙内快速卸载的网络上,所以不应该有任何网络问题。

任何人都有任何建议可以查看或尝试?接下来我们将前往tcpdump。

2008年10月21日更新:仍然没有想到这一点。只看到极少数这些负载。下面的答案还没有提供任何神奇的答案。 :)

10 个答案:

答案 0 :(得分:42)

只是添加一些特定的设置,我有类似的设置(使用Apache 2.0.63反向代理到Tomcat 5.0.27)。

对于某些URL,Tomcat服务器可能需要20分钟才能返回页面。

我最终修改了Apache配置文件中的以下设置,以防止它通过代理操作超时(如果Tomcat花费更长时间返回页面,则会出现大量溢出因素):

Timeout 5400
ProxyTimeout 5400

一些背景

仅凭ProxyTimeout还不够。查看Timeout的文档我是猜测(我不确定)这是因为当Apache等待Tomcat的响应时,Apache和之间没有流量浏览器(或任何http客户端) - 因此Apache关闭了与浏览器的连接。

我发现如果我将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超时。

在Apache和后端之间使用

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的不同含义。 我试图浓缩在这里找到的讨论:enter image description here

看来mod_proxy仅在以下情况下才将后端视为失败的: 与该后端的传输层连接失败。除非使用failonstatus/failontimeout。 ...

因此,必须设置failontimeout才能使apache将Web应用程序的超时(例如,由tomcat服务)视为失败(并连续切换到热备用服务器)。为了进行正确的配置,请注意以下错误配置:

ProxyPass / balancer:// localbalance / failontimeout = on timeout = 10 failonstatus = 50

这是一个错误的配置,因为:

您在此处定义balancer,因此timeout参数与 balancer(与其他两个一样)。 但是对于balancertimeout参数不是连接 超时(例如与BalancerMember一起使用的超时),但最长时间 等待空闲的员工/成员(例如,当所有员工都忙时 处于错误状态,默认为不等待。

因此,可以像这样完成正确的配置

  1. timeout级设置BalanceMember
 <Proxy balancer://mycluster>
     BalancerMember http://member1:8080/svc timeout=6 
 ... more BalanceMembers here
</Proxy>
  1. failontimeout上设置balancer
ProxyPass /svc balancer://mycluster failontimeout=on

重新启动Apache。