我得到了很多499 NGINX错误码。我知道这是客户端的问题。这不是NGINX或我的uWSGI堆栈的问题。当a得到499时,我注意到uWSGI日志中的相关性。
address space usage: 383692800 bytes/365MB} {rss usage: 167038976
bytes/159MB} [pid: 16614|app: 0|req: 74184/222373] 74.125.191.16 ()
{36 vars in 481 bytes} [Fri Oct 19 10:07:07 2012] POST /bidder/ =>
generated 0 bytes in 8 msecs (HTTP/1.1 200) 1 headers in 59 bytes (1
switches on core 1760)
SIGPIPE: writing to a closed pipe/socket/fd (probably the client
disconnected) on request /bidder/ (ip 74.125.xxx.xxx) !!!
Fri Oct 19 10:07:07 2012 - write(): Broken pipe [proto/uwsgi.c line
143] during POST /bidder/ (74.125.xxx.xxx)
IOError: write error
我正在寻找一个更深入的解释,希望我的NGINX配置uwsgi没有问题。我只看表面。好像是客户的问题。
“客户端关闭连接”中的“客户端”不一定是Web浏览器!
如果你在你的用户和你的Nginx之间有负载平衡服务——使用AWS或haproxy,你可能会在Nginx日志文件中发现499个错误。在这个配置中,负载均衡器服务将充当Nginx服务器的客户端和Web浏览器的服务器,来回代理数据。
对于haproxy,连接到上游和从上游(Nginx)或下游(Web浏览器)读取的某些适用超时的默认值约为60秒。
这意味着如果代理在大约60秒后还没有连接到上游进行写入,或者如果它还没有分别从下游(Web浏览器)或上游(Nginx)接收到任何数据作为HTTP请求或响应的一部分,它将关闭相应的连接,这将被Nginx视为错误,至少,如果后者当时正在处理请求(花了太长时间)。
对于繁忙的网站或需要更多时间执行的脚本,可能会发生超时。您可能需要找到一个适合您的超时值。例如,将它扩展到更大的数字,比如180秒。那也许能帮你解决问题。
根据您的设置,您可能会在浏览器中看到一个504网关超时HTTP错误,这可能表明php-fpm有问题。但是,如果日志文件中有499个错误,情况就不是这样了。
就我而言,我没有耐心,最终误解了日志。
事实上,真正的问题是nginx和uwsgi之间的通信,而不是浏览器和nginx之间的通信。如果我在浏览器中加载了这个网站,并且等了足够长的时间,我就会得到一个“504 -坏网关”。但花了很长时间,我一直在尝试,然后在浏览器中刷新。所以我没有等待足够长的时间来看到504错误。当在浏览器中刷新时,也就是关闭前一个请求时,Nginx将其写入日志为499。
细化
在这里,我假设读者知道的和我刚开始玩游戏时一样少。
我的设置是一个反向代理,nginx服务器,和一个应用服务器,后面是uWSGI服务器。来自客户端的所有请求都将发送到nginx服务器,然后转发到uWSGI服务器,然后以同样的方式返回响应。我认为这是每个人使用nginx/uwsgi和应该使用它的方式。
我的nginx正常工作,但是uwsgi服务器出了问题。uwsgi服务器无法响应nginx服务器有两种(也许更多)方式。
1) uWSGI说:“我正在处理,请稍等,您很快就会得到回复”。Nginx有一段时间,它愿意等待,fx 20秒。之后,它将响应客户端,并返回一个504错误。
2) uWSGI死了,或者在nginx等待它的时候uWSGI死了。Nginx马上就看到了,在这种情况下,它返回一个499错误。
我通过在客户端(浏览器)中发出请求来测试我的设置。在浏览器中什么都没有发生,它只是一直挂着。大约10秒钟之后(比超时时间还短),我得出结论,有些地方不太对(这是真的),并从命令行关闭uWSGI服务器。然后我将转到uWSGI设置,尝试一些新的设置,然后重新启动uWSGI服务器。当我关闭uWSGI服务器时,nginx服务器将返回一个499错误。
所以我一直在调试499错误,这意味着在谷歌上搜索499错误。但是如果我等了足够长的时间,就会得到504错误。如果我得到504错误,我就能够更好地理解问题,然后能够调试。
所以结论是,问题出在uWGSI上,它一直挂着(“再等一会儿,再等一会儿,然后我就会给你一个答案……”)。
我不记得我是怎么解决这个问题的。我想这可能是由很多事情引起的。
“客户端关闭连接”中的“客户端”不一定是Web浏览器!
如果你在你的用户和你的Nginx之间有负载平衡服务——使用AWS或haproxy,你可能会在Nginx日志文件中发现499个错误。在这个配置中,负载均衡器服务将充当Nginx服务器的客户端和Web浏览器的服务器,来回代理数据。
对于haproxy,连接到上游和从上游(Nginx)或下游(Web浏览器)读取的某些适用超时的默认值约为60秒。
这意味着如果代理在大约60秒后还没有连接到上游进行写入,或者如果它还没有分别从下游(Web浏览器)或上游(Nginx)接收到任何数据作为HTTP请求或响应的一部分,它将关闭相应的连接,这将被Nginx视为错误,至少,如果后者当时正在处理请求(花了太长时间)。
对于繁忙的网站或需要更多时间执行的脚本,可能会发生超时。您可能需要找到一个适合您的超时值。例如,将它扩展到更大的数字,比如180秒。那也许能帮你解决问题。
根据您的设置,您可能会在浏览器中看到一个504网关超时HTTP错误,这可能表明php-fpm有问题。但是,如果日志文件中有499个错误,情况就不是这样了。
事实证明499确实意味着“客户端连接中断”。
我有一个客户端“读超时”设置为60s (nginx也有一个默认的proxy_read_timeout为60s)。因此,在我的情况下发生的是nginx将error.log上游超时(110:连接超时),而读取上游,然后nginx重试“下一个代理服务器在后端服务器组中配置”。如果你有不止一个。
然后它尝试下一个,下一个,直到(默认情况下)耗尽所有。当每个服务器超时时,它也会从“活动”后端服务器列表中删除它们。在耗尽所有资源后,它返回一个504网关超时。
所以在我的情况下,nginx标记服务器为“不可用”,在下一个服务器上重新尝试,然后我的客户端60s超时(立即)发生,所以我看到一个上游超时(110:连接超时),同时读取上游日志,紧随其后的是499日志。但这只是时间上的巧合。
相关:
如果组中的所有服务器都标记为当前不可用,则返回502 Bad Gateway。10秒也一样。参见这里的max_fails和fail_timeout。在日志中,当连接到上游时,它会说没有实时上游。
如果您的服务器组中只有一个代理后端,它只尝试使用一个服务器,并返回一个504网关超时,如果超过proxy_read_timeout,它不会从“活动”服务器列表中删除单个服务器。参见这里“如果组中只有一台服务器,max_fails, fail_timeout和slow_start参数将被忽略,这样的服务器将永远不会被认为不可用。”
The really tricky part is that if you specify proxy_pass to "localhost" and your box happens to also have ipv6 and ipv4 "versions of localhost" on it at the same time (most boxes do by default), it will count as if you had a "list" of multiple servers in your server group, which means you can get into the situation above of having it return "502 for 10s" even though you list only one server. See here "If a domain name resolves to several addresses, all of them will be used in a round-robin fashion."
One workaround is to declare it as proxy_pass http://127.0.0.1:5001; (its ipv4 address) to avoid it being both ipv6 and ipv4. Then it counts as "only a single server" behavior.
有一些不同的设置,你可以调整,使这个“少”的问题。比如增加超时时间,或者在服务器超时时不将其标记为“禁用”……或者修复列表,使它只有大小1,见上面:)
参见:https://serverfault.com/a/783624/27813