Java Apache mod_proxy 和 Tomcat 的 Bad Gateway 502 错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/169453/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Bad Gateway 502 error with Apache mod_proxy and Tomcat
提问by Alex Miller
We're running a web app on Tomcat 6 and Apache mod_proxy 2.2.3. Seeing a lot of 502 errors like this:
我们正在 Tomcat 6 和 Apache mod_proxy 2.2.3 上运行一个 Web 应用程序。看到很多这样的502错误:
Bad Gateway! The proxy server received an invalid response from an upstream server.
The proxy server could not handle the request GET /the/page.do.
Reason: Error reading from remote server
If you think this is a server error, please contact the webmaster.
Error 502
错误的网关!代理服务器收到来自上游服务器的无效响应。
代理服务器无法处理请求 GET /the/page.do。
原因:从远程服务器读取错误
如果您认为这是服务器错误,请联系网站管理员。
错误 502
Tomcat has plenty of threads, so it's not thread-constrained. We're pushing 2400 users via JMeter against the app. All the boxes are sitting inside our firewall on a fast unloaded network, so there shouldn't be any network problems.
Tomcat 有很多线程,所以它不受线程限制。我们正在通过 JMeter 向应用推送 2400 名用户。所有的盒子都位于我们的防火墙内,位于一个快速卸载的网络上,所以不应该有任何网络问题。
Anyone have any suggestions for things to look at or try? We're heading to tcpdump next.
任何人有什么建议看或尝试的东西?接下来我们将前往 tcpdump。
UPDATE 10/21/08: Still haven't figured this out. Seeing only a very small number of these under load. The answers below haven't provided any magical answers...yet. :)
2008 年 10 月 21 日更新:仍然没有弄清楚这一点。在负载下只看到非常少的这些。下面的答案还没有提供任何神奇的答案……还没有。:)
采纳答案by Alex Miller
So, answering my own question here. We ultimately determined that we were seeing 502 and 503 errors in the load balancer due to Tomcat threads timing out. In the short term we increased the timeout. In the longer term, we fixed the app problems that were causing the timeouts in the first place. Why Tomcat timeouts were being perceived as 502 and 503 errors at the load balancer is still a bit of a mystery.
所以,在这里回答我自己的问题。我们最终确定,由于 Tomcat 线程超时,我们在负载平衡器中看到了 502 和 503 错误。在短期内,我们增加了超时时间。从长远来看,我们首先修复了导致超时的应用程序问题。为什么 Tomcat 超时在负载均衡器上被视为 502 和 503 错误仍然有点神秘。
回答by Dave Cheney
I'm guessing your using mod_proxy_http (or proxy balancer).
我猜你在使用 mod_proxy_http(或代理平衡器)。
Look in your tomcat logs (localhost.log, or catalina.log) I suspect your seeing an exception in your web stack bubbling up and closing the socket that the tomcat worker is connected to.
查看您的 tomcat 日志(localhost.log 或 catalina.log),我怀疑您在 Web 堆栈中看到异常冒泡并关闭了 tomcat 工作程序连接到的套接字。
回答by Janning
You can use proxy-initial-not-pooled
您可以使用 proxy-initial-not-pooled
See http://httpd.apache.org/docs/2.2/mod/mod_proxy_http.html:
请参阅http://httpd.apache.org/docs/2.2/mod/mod_proxy_http.html:
If this variable is set no pooled connection will be reused if the client connection is an initial connection. This avoids the "proxy: error reading status line from remote server" error message caused by the race condition that the backend server closed the pooled connection after the connection check by the proxy and before data sent by the proxy reached the backend. It has to be kept in mind that setting this variable downgrades performance, especially with HTTP/1.0 clients.
如果设置了此变量,则如果客户端连接是初始连接,则不会重用池连接。这避免了由于在代理检查连接后、代理发送的数据到达后端之前后端服务器关闭池连接的竞争条件而导致的“proxy: error reading status line from remote server”错误信息。必须记住,设置此变量会降低性能,尤其是对于 HTTP/1.0 客户端。
We had this problem, too. We fixed it by adding
我们也有这个问题。我们通过添加修复它
SetEnv proxy-nokeepalive 1
SetEnv proxy-initial-not-pooled 1
and turning keepAlive
on all servers off.
并关闭keepAlive
所有服务器。
mod_proxy_http is fine in most scenarios but we are running it with heavy load and we still got some timeout problems we do not understand.
mod_proxy_http 在大多数情况下都很好,但我们在高负载下运行它,我们仍然遇到一些我们不明白的超时问题。
But see if the above directive fits your needs.
但是看看上面的指令是否符合您的需求。
回答by sibnick
Most likely you should increase Timeout parameter in apache conf (default value 120 sec)
很可能你应该在 apache conf 中增加 Timeout 参数(默认值 120 秒)
回答by sibnick
Sample from apache conf:
来自 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>
回答by Neil Salter
Just to add some specific settings, I had a similar setup (with Apache 2.0.63 reverse proxying onto Tomcat 5.0.27).
只是为了添加一些特定的设置,我有一个类似的设置(使用 Apache 2.0.63 反向代理到 Tomcat 5.0.27)。
For certain URLs the Tomcat server could take perhaps 20 minutes to return a page.
对于某些 URL,Tomcat 服务器可能需要 20 分钟才能返回页面。
I ended up modifying the following settings in the Apache configuration file to prevent it from timing out with its proxy operation (with a large over-spill factor in case Tomcat took longer to return a page):
我最终修改了 Apache 配置文件中的以下设置,以防止它的代理操作超时(如果 Tomcat 需要更长的时间来返回页面,则有很大的溢出因素):
Timeout 5400
ProxyTimeout 5400
Some backgound
一些背景
ProxyTimeoutalone wasn't enough. Looking at the documentation for TimeoutI'm guessing(I'm not sure) that this is because while Apache is waiting for a response from Tomcat, there is no traffic flowing between Apache and the Browser (or whatever http client) - and so Apache closes down the connection to the browser.
仅ProxyTimeout是不够的。查看超时的文档我猜(我不确定)这是因为当 Apache 正在等待来自 Tomcat 的响应时,Apache 和浏览器(或任何 http 客户端)之间没有流量流动 - 所以Apache 关闭与浏览器的连接。
I found that if I left the Timeout setting at its default (300 seconds), then if the proxied request to Tomcat took longer than 300 seconds to get a response the browser would display a "502 Proxy Error" page. I believe this message is generated by Apache, in the knowledge that it's acting as a reverse proxy, before it closes down the connection to the browser (this is my current understanding - it may be flawed).
我发现如果我将超时设置保留为默认值(300 秒),那么如果对 Tomcat 的代理请求花费的时间超过 300 秒才能获得响应,浏览器将显示“502 代理错误”页面。我相信这条消息是由 Apache 生成的,因为它知道它在关闭与浏览器的连接之前充当反向代理(这是我目前的理解 - 它可能有缺陷)。
The proxy error page says:
代理错误页面说:
Proxy Error
The proxy server received an invalid response from an upstream server. The proxy server could not handle the request GET.
Reason: Error reading from remote server
代理错误
代理服务器收到来自上游服务器的无效响应。代理服务器无法处理请求 GET。
原因:从远程服务器读取错误
...which suggests that it's the ProxyTimeout setting that's too short, while investigation shows that Apache's Timeout setting (timeout between Apache and the client) that also influences this.
...这表明 ProxyTimeout 设置太短,而调查表明 Apache 的超时设置(Apache 和客户端之间的超时)也会影响这一点。
回答by tallguy
you should be able to get this problem resolved through a timeout and proxyTimeout parameter set to 600 seconds. It worked for me after battling for a while.
您应该能够通过将超时和 proxyTimeout 参数设置为 600 秒来解决此问题。经过一段时间的战斗后,它对我有用。
回答by bhantol
You can avoid global timeouts or having to virtual hosts by specifying the proxy timeouts in the ProxyPass directive as follows:
您可以通过在 ProxyPass 指令中指定代理超时来避免全局超时或必须虚拟主机,如下所示:
ProxyPass /svc http://example.com/svc timeout=600
ProxyPassReverse /svc http://example.com/svc timeout=600
Notice timeout=600
seconds.
注意timeout=600
秒。
However this does not always work when you have load balancer. In that case you must add the timeouts in both the places (tested in Apache 2.2.31)
但是,当您有负载平衡器时,这并不总是有效。在这种情况下,您必须在两个地方添加超时(在 Apache 2.2.31 中测试)
Load Balancer example:
负载均衡器示例:
<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
A side note: the timeout=600
on ProxyPass
was not required when Chrome was the client (I don;t know why) but without this timeout on ProxyPass
Internet Explorer (11) aborts saying connection reset by server.
旁注:在timeout=600
上ProxyPass
时,Chrome浏览器为客户端(我不;知道为什么)是不是必需的,但如果没有这个超时上ProxyPass
的Internet Explorer(11)中止说通过服务器连接复位。
My theory is that the :
我的理论是:
ProxyPass
timeout is used between the client(browser) and the Apache.
ProxyPass
客户端(浏览器)和 Apache 之间使用超时。
BalancerMember
timeout is used between the Apache and the backend.
BalancerMember
超时用于 Apache 和后端之间。
To those who use Tomcat or other backed you may also want to pay attention to the HTTP Connector timeouts.
对于那些使用 Tomcat 或其他支持的人,您可能还需要注意 HTTP 连接器超时。
回答by Muhammad Dyas Yaskur
I know this does not answer this question, but I came here because I had the same error with nodeJS server. I am stuck a long time until I found the solution. My solution just adds slash or /
in end of proxyreserve apache.
我知道这不能回答这个问题,但我来到这里是因为我在使用 nodeJS 服务器时遇到了同样的错误。我被困了很长时间,直到找到解决方案。我的解决方案只是/
在proxyreserve apache 的末尾添加斜杠或。
my old code is:
我的旧代码是:
ProxyPass / http://192.168.1.1:3001
ProxyPassReverse / http://192.168.1.1:3001
the correct code is:
正确的代码是:
ProxyPass / http://192.168.1.1:3001/
ProxyPassReverse / http://192.168.1.1:3001/