【问题标题】:Bad Gateway 502 error with Apache mod_proxy and TomcatApache mod_proxy 和 Tomcat 出现 Bad Gateway 502 错误
【发布时间】:2010-09-15 05:30:18
【问题描述】:

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

网关错误! 代理服务器收到来自上游服务器的无效响应。

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

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

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

错误 502

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

有人对要查看或尝试的内容有任何建议吗?接下来我们将前往 tcpdump。

2008 年 10 月 21 日更新:仍然没有弄清楚这一点。仅看到其中极少数处于负载状态。下面的答案还没有提供任何神奇的答案……还没有。 :)

【问题讨论】:

  • 我在运行应用程序期间遇到了这个问题一段时间

标签: java apache tomcat mod-proxy


【解决方案1】:

如果你想用 apache 负载均衡器来处理你的 webapp 的超时,你首先要了解timeout 的不同含义。 我试图浓缩我在这里找到的讨论:http://apache-http-server.18135.x6.nabble.com/mod-proxy-When-does-a-backend-be-considered-as-failed-td5031316.html

似乎mod_proxy 仅在 到该后端的传输层连接失败。除非使用failonstatus/failontimeout。 ...

因此,设置failontimeout 是 apache 将 webapp(例如由 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. balancer 上设置failontimeout
ProxyPass /svc balancer://mycluster failontimeout=on

重启apache。

【讨论】:

    【解决方案2】:

    来自 apache conf 的示例:

    #Default value is 2 minutes
    **Timeout 600**
    ProxyRequests off
    ProxyPass /app balancer://MyApp stickysession=JSESSIONID lbmethod=bytraffic nofailover=On
    ProxyPassReverse /app balancer://MyApp
    ProxyTimeout 600
    <Proxy balancer://MyApp>
        BalancerMember http://node1:8080/ route=node1 retry=1 max=25 timeout=600
        .........
    </Proxy>
    

    【讨论】:

      【解决方案3】:

      我知道这不能回答这个问题,但我来到这里是因为我在 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/
      

      【讨论】:

      • 感谢分享帮助我解决了类似的问题。
      • 也适合我。所以现在这让我更加困惑,是语法问题 [1] 还是超时问题? [1]:ProxyPass /192.168.1.1:3001 [1]:ProxyPassReverse /192.168.1.1:3001
      【解决方案4】:

      你可以使用 代理初始未池化

      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 在大多数情况下都很好,但是我们在负载很重的情况下运行它,我们仍然遇到一些我们不理解的超时问题。

      但是看看上面的指令是否符合你的需要。

      【讨论】:

      • 这对我有用。我使用 SetEnv proxy-nokeepalive 1 和 SetEnv force-proxy-request-1.0 1 纠正了不一致的保持活动设置。
      【解决方案5】:

      您可以通过在 ProxyPass 指令中指定代理超时来避免全局超时或必须虚拟主机,如下所示:

      ProxyPass /svc http://example.com/svc timeout=600
      ProxyPassReverse /svc http://example.com/svc timeout=600
      

      通知timeout=600 秒。

      但是,当您有负载平衡器时,这并不总是有效。在这种情况下,您必须在两个地方添加超时(在 Apache 2.2.31 中测试)

      负载均衡器示例:

      <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 是客户端时,ProxyPass 上的 timeout=600 不是必需的(我不知道为什么),但在 ProxyPass 上没有此超时 Internet Explorer (11) 中止说连接被服务器重置.

      我的理论是:

      ProxyPass 超时用于客户端(浏览器)和 Apache 之间。

      BalancerMember 超时用于 Apache 和后端之间。

      对于那些使用 Tomcat 或其他支持的人,您可能还需要注意 HTTP 连接器超时。

      【讨论】:

        【解决方案6】:

        您应该能够通过将超时和 proxyTimeout 参数设置为 600 秒来解决此问题。经过一段时间的战斗,它对我有用。

        【讨论】:

          【解决方案7】:

          只是为了添加一些特定设置,我有一个类似的设置(使用 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 代理错误”页面。我相信这条消息是由 Apache 生成的,知道它充当反向代理,然后关闭与浏览器的连接(这是我目前的理解 - 它可能有缺陷)。

          代理错误页面显示:

          代理错误

          代理服务器收到一个无效的 来自上游服务器的响应。这 代理服务器无法处理 请求 GET。

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

          ...这表明 ProxyTimeout 设置太短了,而调查显示 Apache 的 Timeout 设置(Apache 和客户端之间的超时)也会影响这一点。

          【讨论】:

          • 超时设置的语法是什么?超时 5400 或超时 5400? (小 o 与大写 O)
          • 配置指令区分大小写不区分大小写(但参数可能区分大小写):httpd.apache.org/docs/2.4/configuring.html
          • 您好,我比较新鲜,不知道在哪里以及如何设置上面的属性,请详细解释一下。我可以在哪里找到这个配置文件,我必须在那个配置文件中写这个属性。
          • 在我的情况下,浏览器的控制台开发人员显示给我............ 502(代理错误)......我在文件中的 中添加了 Timeout 5400 ProxyTimeout 5400 httpd.conf 和工作!谢谢!
          • 在大多数情况下不需要添加ProxyTimeout 指令,因为它将Timeout 指令值作为默认值。见httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxytimeout
          【解决方案8】:

          您很可能应该在 apache conf 中增加 Timeout 参数(默认值 120 秒)

          【讨论】:

            【解决方案9】:

            所以,在这里回答我自己的问题。我们最终确定,由于 Tomcat 线程超时,我们在负载均衡器中看到了 502 和 503 错误。在短期内,我们增加了超时。从长远来看,我们首先修复了导致超时的应用程序问题。为什么 Tomcat 超时在负载均衡器上被视为 502 和 503 错误仍然是一个谜。

            【讨论】:

            • 你有什么想法吗,如果 tomcat 超时,为什么负载均衡器会抛出错误的网关?
            • 在 Janning 的回答 (stackoverflow.com/a/1287662/385571) 中引用的文档中,解释是在后端 WAS 关闭连接和 mod_proxy_http 检查它之间存在竞争条件。如果一个新客户端在没有设置proxy-initial-not-pooled 的情况下连接,它可能会被发送到这个已失效的线程。
            【解决方案10】:

            我猜你正在使用 mod_proxy_http(或代理平衡器)。

            查看您的 tomcat 日志(localhost.log 或 catalina.log)我怀疑您在 web 堆栈中看到异常冒泡并关闭 tomcat 工作程序连接到的套接字。

            【讨论】:

            • 用您在日志中找到的任何内容更新问题。还要检查 apache 错误日志,这应该可以为您提供关闭套接字(apache 或 tomcat)的线索。默认情况下,apache 代理响应的超时时间为 300 秒
            猜你喜欢
            • 2012-04-13
            • 1970-01-01
            • 2021-08-03
            • 1970-01-01
            • 2018-11-12
            • 1970-01-01
            • 2018-04-23
            • 2016-10-23
            • 2021-03-31
            相关资源
            最近更新 更多