Nginx 499错误代码

时间:2012-10-19 11:28:52

标签: nginx http-headers uwsgi

我收到了很多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没有任何问题。我正在接受它的面子价值......这不是我的问题......客户问题。

谢谢

16 个答案:

答案 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上

Nginx doc

答案 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中的设置如下:

  • nginx_proxy
  • nginx
  • 运行实际应用的php_fpm。

症状是在应用程序登录提示符下显示“ 502网关超时”。检查发现的日志:

  • 该按钮通过HTTP RcvMsgDataPOST起作用...如此……
  • nginx-proxy收到了/login请求,并最终报告了超时。
  • nginx返回了/login响应,这当然意味着“主机已死。”
  • 499请求根本没有出现在FPM服务器的日志中!!
  • FPM中没有回溯或错误消息……nada,零,zippo,无。

事实证明,问题是无法连接到数据库以验证登录名。但是如何弄清楚结果却是纯粹的猜测。

完全没有应用程序回溯日志……甚至没有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 + 2'表示超时到负载均衡器
  • CDN超时
  • n+3秒。

如果您无法设置某些超时(例如CDN),请找出它的超时,然后根据该超时进行调整(nn-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“如果一个域名解析为多个地址,则所有这些地址都将以循环方式使用。” 一种解决方法是将其声明为avoidproxy_read_timeout(其ipv4地址)到ipv6和ipv4。然后将其视为“仅单个服务器”行为。

您可以调整一些不同的设置来解决这个“少”的问题。像增加超时或使其超时,这样服务器在超时时不会将服务器标记为“已禁用” ...或修复列表,使其只有大小1,请参见上文:)

另请参阅:https://serverfault.com/a/783624/27813

答案 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字段