什么是499状态
nginx源码中对499状态码的定义如下:
/*
* HTTP does not define the code for the case when a client closed
* the connection while we are processing its request so we introduce
* own code to log such situation when a client has closed the connection
* before we even try to send the HTTP header to it
*/
#define NGX_HTTP_CLIENT_CLOSED_REQUEST 499
总结:当客户端主动把连接断开时,HTTP 不为这种情形定义代码。同时我们处理它的请求时,我们引入了当一个客户端在我们尝试向其发送 HTTP 头之前关闭连接时,使用自己的代码(也就是 499
状态码)来记录这种情况。
-
499
状态码不是 HTTP 的标准代码 499
状态码是 Nginx 自己定义,用来 记录(你没看错,就是记录一下) 服务端向客户端发送 HTTP 请求头之前,客户端已经关闭连接的一种情况- 最常见的场景就是
timeout
设置不合理,Nginx 把请求转发上游服务器,上游服务器慢吞吞的处理,客户端等不及了主动断开链接,Nginx 就负责记录了499
什么情况Nginx记录499错误日志
这里我们使用 curl
模拟请求一下,更多 curl
的骚操作请访问 curl 的用法指南。
for i in $(seq 1 10); do curl -m 2 "http://api.example.test"; done
解释: curl -m 2 "http://api.example.test" 2秒没有响应则断开
tail -f /var/log/nginx/apiexample.access.log
172.19.0.1 - - [15/Nov/2019:06:32:19 +0000] "GET / HTTP/1.1" 499 0 "-" "curl/7.67.0"
172.19.0.1 - - [15/Nov/2019:06:32:22 +0000] "GET / HTTP/1.1" 499 0 "-" "curl/7.67.0"
172.19.0.1 - - [15/Nov/2019:06:32:24 +0000] "GET / HTTP/1.1" 499 0 "-" "curl/7.67.0"
172.19.0.1 - - [15/Nov/2019:06:32:26 +0000] "GET / HTTP/1.1" 499 0 "-" "curl/7.67.0"
172.19.0.1 - - [15/Nov/2019:06:32:28 +0000] "GET / HTTP/1.1" 499 0 "-" "curl/7.67.0"
172.19.0.1 - - [15/Nov/2019:06:32:30 +0000] "GET / HTTP/1.1" 499 0 "-" "curl/7.67.0"
172.19.0.1 - - [15/Nov/2019:06:32:32 +0000] "GET / HTTP/1.1" 499 0 "-" "curl/7.67.0"
172.19.0.1 - - [15/Nov/2019:06:32:34 +0000] "GET / HTTP/1.1" 499 0 "-" "curl/7.67.0"
172.19.0.1 - - [15/Nov/2019:06:32:36 +0000] "GET / HTTP/1.1" 499 0 "-" "curl/7.67.0"
172.19.0.1 - - [15/Nov/2019:06:32:38 +0000] "GET / HTTP/1.1" 499 0 "-" "curl/7.67.0"
如上所见,使用 Timeout
很容易模拟出 499
这种情形。
记录 499
的情形:
- 如上所示,数据传输的最大允许时间超时的话,Curl 断开了请求,而 Web 服务器如 Nginx 还在处理的话,则 Nginx 会记录
499
- 如果 Nginx 作为反向代理时,Nginx 将请求分发至对应的处理服务器时,有两对超时参数的设置:
proxy_send_timeout
和proxy_read_timeout
、fastcgi_send_timeout
和fastcgi_read_timeout
。两对参数默认的超时时间都是60s
。在 Nginx 出现499
的情况下,可以结合请求断开前的耗时和这两对设定的时间进行对比,看一下是不是在proxy_pass
或者fastcgi_pass
处理时,设置的超时时间短了 - 如果 PHP 操作超时。打开
php.ini
查看max_execution_time
和max_input_time
两个参数。两者分别是PHP
程序执行的最长时间和表单提交的最长时间 - 如果两次提交 POST 过快就会出现
499
的情况,Nginx 认为是不安全的连接,主动拒绝了客户端的连接 - 相关负载均衡配置等
如何有效防止Nginx记录499错误
综上所述,我们可以得出一个结论,HTTP 请求在指定的时间内没能拿到响应而关闭了连接,就会发生 Nginx 记录 499
错误的情况。这个涉及到两个重要的问题:时间问题 和 性能问题(性能问题太过宽泛就不提及了),所以解决这个问题也就从这两方面入手。
当然还有配置 proxy_ignore_client_abort
参数为 on
来解决的(让代理服务端不要主动关闭客户端的连接)。但是这样也有一定的风险,会拖垮服务器。发生这个错误,如果服务器 CPU 和 Memory 不算太高,一般是数据库和程序的问题,数据库处理较慢或者程序线程较低。结合情况调整,比如读写分离或者程序线程数调高。
(如果后端是fastcgi,比如php-fpm,配置fastcgi_ignore_client_abort on; //如果后端是fastcgi,比如php-fpm )
文档中对 proxy_ignore_client_abort
参数的说明:
Determines whether the connection with a proxied server should be closed when a client closes the connection without waiting for a response.文章来源:https://www.toymoban.com/news/detail-404996.html
翻译:当一个客户端关闭连接而不等待响应时,确定与代理服务器的连接是否应该关闭。文章来源地址https://www.toymoban.com/news/detail-404996.html
到了这里,关于http 状态码499的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!