我收到了很多499个nginx错误代码。我看到这是客户端问题。这不是Nginx或我的uWSGI堆栈的问题。我注意到当获得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没有任何问题。我正在接受它的面子价值......这不是我的问题......客户问题。
谢谢
答案 0 :(得分:131)
Nginx中的HTTP 499表示客户端在服务器应答请求之前关闭了连接。根据我的经验,通常是由客户端超时引起的。据我所知,这是一个特定于Nginx的错误代码。
答案 1 :(得分:51)
在我的情况下,我很不耐烦,最后误解了日志。
实际上真正的问题是nginx和uwsgi之间的通信,而不是浏览器和nginx之间的通信。如果我在浏览器中加载了网站,并且等待了足够长的时间,我就会得到一个“504 - Bad Gateway”。但是花了这么长时间,我一直在尝试,然后在浏览器中刷新。所以我从来没有等到足以看到504错误。在浏览器中刷新时,即上一个请求关闭时,Nginx将其作为499写入日志中。
在这里,我将假设当我开始玩游戏时,读者会像我一样知道。
我的设置是反向代理,nginx服务器和应用服务器,它背后的uWSGI服务器。来自客户端的所有请求都将转到nginx服务器,然后转发到uWSGI服务器,然后以相同的方式发送响应。我认为这是每个人使用nginx / uwsgi的方式,并且应该使用它。
我的nginx工作正常,但是uwsgi服务器出了问题。有两种方式(可能更多)uwsgi服务器无法响应nginx服务器。
1)uWSGI说,“我正在处理,只是等待,你很快就会收到回复”。 nginx有一段时间,它愿意等待,fx 20秒。之后它将响应客户端,出现504错误。2)uWSGI已经死了,或者uWSGi在nginx等待它时死亡。 nginx马上就看到了,在这种情况下它会返回499错误。
我通过在客户端(浏览器)中发出请求来测试我的设置。在浏览器中没有发生任何事情,它只是一直挂着。在大概10秒(小于超时)之后我得出结论:某些东西不对(这是真的),并从命令行关闭了uWSGI服务器。然后我将转到uWSGI设置,尝试新的,然后重新启动uWSGI服务器。当我关闭uWSGI服务器时,nginx服务器将返回499错误。
所以我继续调试499错误,这意味着谷歌搜索499错误。但如果我等了足够长的时间,我就会得到504错误。如果我得到504错误,我本来能够更好地理解问题,然后能够调试。
所以结论是,问题出在uWGSI上,它一直悬挂着(“再等一会儿,再多一点,然后我会给你答案......”)。
我如何修复那个问题,我不记得了。我想这可能是由很多事情引起的。
答案 2 :(得分:16)
客户关闭了连接并不代表它是一个浏览器问题!?完全没有!
如果在Web服务器(nginx)前面有一个LB(负载均衡器),可以在AWS或haproxy(自定义)中找到499个错误。这就是LB将充当nginx的客户端。
如果您运行haproxy默认值:
timeout client 60000
timeout server 60000
这意味着如果没有来自nginx的响应,LB将在60000ms后超时。对于需要更多时间执行的繁忙网站或脚本,可能会发生超时。您需要找到适合您的超时。例如,将其扩展为:
timeout client 180s
timeout server 180s
你可能会被设定。
根据您的设置,您可能会在浏览器中看到504网关超时错误,表明php-fpm出现了问题,但日志文件中的499错误情况并非如此。
答案 3 :(得分:5)
对于我来说,当客户端的API在获得任何响应之前关闭连接时,我得到了499。从字面上发送一个POST,并立即关闭连接。 这可以通过选项解决:
proxy_ignore_client_abort上
答案 4 :(得分:3)
使用php-fpm标准的nginx配置很容易重现此错误。
在页面上保持F5按钮将向服务器创建数十个刷新请求。浏览器在刷新时取消每个先前的请求。在我的情况下,我在客户的在线商店日志文件中找到了数十个499。从nginx的角度来看:如果在下一次刷新请求之前没有将响应传递给客户端,nginx会记录499错误。
mydomain.com.log:84.240.77.112 - - [19/Jun/2018:09:07:32 +0200] "GET /(path) HTTP/2.0" 499 0 "-" (user-agent-string)
mydomain.com.log:84.240.77.112 - - [19/Jun/2018:09:07:33 +0200] "GET /(path) HTTP/2.0" 499 0 "-" (user-agent-string)
mydomain.com.log:84.240.77.112 - - [19/Jun/2018:09:07:33 +0200] "GET /(path) HTTP/2.0" 499 0 "-" (user-agent-string)
mydomain.com.log:84.240.77.112 - - [19/Jun/2018:09:07:33 +0200] "GET /(path) HTTP/2.0" 499 0 "-" (user-agent-string)
mydomain.com.log:84.240.77.112 - - [19/Jun/2018:09:07:33 +0200] "GET /(path) HTTP/2.0" 499 0 "-" (user-agent-string)
mydomain.com.log:84.240.77.112 - - [19/Jun/2018:09:07:34 +0200] "GET /(path) HTTP/2.0" 499 0 "-" (user-agent-string)
mydomain.com.log:84.240.77.112 - - [19/Jun/2018:09:07:34 +0200] "GET /(path) HTTP/2.0" 499 0 "-" (user-agent-string)
mydomain.com.log:84.240.77.112 - - [19/Jun/2018:09:07:34 +0200] "GET /(path) HTTP/2.0" 499 0 "-" (user-agent-string)
mydomain.com.log:84.240.77.112 - - [19/Jun/2018:09:07:34 +0200] "GET /(path) HTTP/2.0" 499 0 "-" (user-agent-string)
mydomain.com.log:84.240.77.112 - - [19/Jun/2018:09:07:35 +0200] "GET /(path) HTTP/2.0" 499 0 "-" (user-agent-string)
mydomain.com.log:84.240.77.112 - - [19/Jun/2018:09:07:35 +0200] "GET /(path) HTTP/2.0" 499 0 "-" (user-agent-string)
如果php-fpm处理需要更长的时间(比如重的WP页面),它当然可能会导致问题。例如,我听说过php-fpm崩溃,但我相信可以阻止他们正确配置服务,就像处理对xmlrpc.php的调用一样。
答案 5 :(得分:2)
...来自谷歌搜索
我在这里找到了答案 - > https://stackoverflow.com/a/15621223/1093174
这是为了提高我的AWS弹性负载均衡器的连接空闲超时!
(我已经设置了一个带有nginx / apache反向代理的Django站点,而且一个非常真实的日志后端作业/视图已超时)
答案 6 :(得分:1)
我知道这是一个旧线程,但是它与最近发生在我身上的事情完全匹配,我认为我将在这里进行记录。 Docker中的设置如下:
症状是在应用程序登录提示符下显示“ 502网关超时”。检查发现的日志:
RcvMsgData
到POST
起作用...如此……/login
请求,并最终报告了超时。/login
响应,这当然意味着“主机已死。” 499
请求根本没有出现在FPM服务器的日志中!! 事实证明,问题是无法连接到数据库以验证登录名。但是如何弄清楚结果却是纯粹的猜测。
完全没有应用程序回溯日志……甚至没有FPM接收到请求的记录……令我完全惊讶(并且毁灭性的……)。是的,该应用程序应该记录故障,但是在这种情况下,FPM工作进程似乎因运行时错误而终止,从而导致nginx发出/login
响应。现在,这显然是我们应用程序中的一个问题。但是我想记录下发生的细节,以使下一个面对这样的事情的人受益。
答案 7 :(得分:0)
一旦我 499"防病毒" 禁止请求作为AJAX http响应(卡巴斯基互联网安全部门使用轻启发式分析误报,深度启发式分析正确地知道那里没错。)
答案 8 :(得分:0)
此行为的原因之一可能是您使用http
代替uwsgi
代替socket
。如果直接使用uwsgi
,请使用以下命令。
uwsgi --socket :8080 --module app-name.wsgi
.ini文件中的相同命令是
chdir = /path/to/app/folder
socket = :8080
module = app-name.wsgi
答案 9 :(得分:0)
我遇到了这个问题,原因是浏览器上的Kaspersky Protection插件。如果您遇到此问题,请尝试停用您的插件,看看是否能解决您的问题。
答案 10 :(得分:0)
当您指向499
时,nginx记录了连接中断。 但是通常这是由于后端服务器速度太慢而产生的,并且另一个代理先超时或用户软件中止连接。因此,请检查uWSGI是否正在快速响应,或者uWSGI /数据库服务器上是否有负载。
在许多情况下,用户和nginx之间还有其他一些代理。有些可以在您的基础结构中,例如CDN,Load Balacer,Varnish缓存等。其他则可以在用户端,例如缓存代理等。
如果您身边有代理,例如LoadBalancer / CDN ...,则应将超时设置为先使后端超时,然后将其他代理逐渐超时。
如果您有:
user >>> CDN >>> Load Balancer >>> Nginx >>> uWSGI
我建议您设置:
n
秒到uWSGI超时n+1
秒到nginx超时n+3
秒。如果您无法设置某些超时(例如CDN),请找出它的超时,然后根据该超时进行调整(n
,n-1
...)。
这提供了正确的超时链。您会发现真正的超时原因是谁,并向用户返回正确的响应代码。
答案 11 :(得分:0)
结果证明499确实意味着“客户端中断连接”。
我的客户端读取超时为60s(nginx也有默认的proxy_read_timeout为60s)。因此,在我的情况下,nginx会出错。登录upstream timed out (110: Connection timed out) while reading upstream
,然后nginx
重试“您配置的后端服务器组中的下一个代理服务器”。那就是如果您有多个。
然后,它尝试下一个和下一个直到(default)用尽所有这些。每次超时时,也会将它们从“活动的”后端服务器列表中删除。精疲力尽之后,它返回一个504 gateway timeout.
因此,在我的情况下,nginx将服务器标记为“不可用”,在下一个服务器上重试该服务器,然后发生了我的客户端的60s
超时,因此我会立即看到upstream timed out (110: Connection timed out) while reading upstream
,随后是日志中的499。
如果该组中的所有服务器都标记为当前不可用,则它还会返回502 Bad Gateway.
10秒钟。请参见here max_fails
和fail_timeout。在日志中显示“连接上游时无上游上游”。
如果您的服务器组中只有一个代理后端,则仅尝试使用一台服务器,然后返回504 Gateway Time-out
,并且不会从“实时”服务器列表中删除单个服务器,如果{{ 1}}被超过。请参阅here“如果组中只有一台服务器,则将忽略max_fails,fail_timeout和slow_start参数,这样的服务器将永远不会被视为不可用。”
真正棘手的部分是,如果您将proxy_pass指定为“ localhost”,并且您的包装盒上同时还同时具有ipv6和ipv4“位置版本”(默认情况下,大多数包装盒都将这样做)如果您在服务器组中有多个服务器的“列表”,这意味着即使您只列出one server,也可以进入上述情况,使其返回“ 502 for 10s”。请参阅here“如果一个域名解析为多个地址,则所有这些地址都将以循环方式使用。”
一种解决方法是将其声明为avoid的proxy_read_timeout
(其ipv4地址)到ipv6和ipv4。然后将其视为“仅单个服务器”行为。
您可以调整一些不同的设置来解决这个“少”的问题。像增加超时或使其超时,这样服务器在超时时不会将服务器标记为“已禁用” ...或修复列表,使其只有大小1,请参见上文:)
答案 12 :(得分:0)
这不能回答OP的问题,但是由于我在疯狂寻找答案后来到这里,所以我想分享我们发现的内容。
在我们的案例中,事实证明这是499个。例如,当用户在某些搜索框中使用预输入功能时,我们会在日志中看到类似的内容。
GET /api/search?q=h [Status 499]
GET /api/search?q=he [Status 499]
GET /api/search?q=hel [Status 499]
GET /api/search?q=hell [Status 499]
GET /api/search?q=hello [Status 200]
因此,在我们的案例中,我认为使用proxy_ignore_client_abort on
是安全的,这在先前的答案中已经建议过。谢谢你!
答案 13 :(得分:0)
就我而言,我启用了ufw
,但是我忘记了暴露上游端口._。
答案 14 :(得分:0)
就我而言,我的设置类似于
AWS ELB >> ECS(nginx) >> ECS(php-fpm).
我为ECS(php-fpm)服务配置了错误的AWS安全组,因此Nginx无法联系到php-fpm任务容器。 这就是为什么我在nginx任务日志中出现错误
499 0 - elb-healthchecker/2.0
运行状况检查配置为检查php-fpm服务并确认其启动并返回响应。
答案 15 :(得分:-4)
许多情况导致499错误,我的一个案例是,来自pocco客户端的http请求中错过了Content-Length字段