Nginx状态码499
1、问题描述
140.207.202.187 - - [18/May/2016:10:30:58 +0800] "POST/v3/violations HTTP/1.1" 499 0 "-" "-"
42.236.10.71 - - [18/May/2016:10:30:59 +0800] "POST /v3/violationsHTTP/1.1" 499 0 "-" "-"
2、问题分析
499 / ClientClosed Request
An Nginx HTTP server extension. This codeis introduced to log the case when the connection is closed by client whileHTTP server is processing its request, making server unable to send the HTTP header back
维基百科
499Client Closed Request (Nginx)
Used in Nginx logs to indicate when the connection has been closed by client while the server is still processing itsrequest, making server unable to send a status code back
nginx源码
./src/http/ngx_http_core_module.c: if (status == NGX_ERROR || status == 499) {
./src/http/ngx_http_request.h:#define NGX_HTTP_CLIENT_CLOSED_REQUEST 499
./src/http/ngx_http_special_response.c: ngx_null_string, /* 499, client has closed connection */
这是nginx定义的一个状态码,用于表示这样的错误:服务器返回http头之前,客户端就提前关闭了http连接,这很有可能是因为服务器端处理的时间过长,客户端“不耐烦”了。
进一步查找
查找“NGX_HTTP_CLIENT_CLOSED_REQUEST”
./src/http/ngx_http_upstream.c: NGX_HTTP_CLIENT_CLOSED_REQUEST);
./src/http/ngx_http_upstream.c: NGX_HTTP_CLIENT_CLOSED_REQUEST);
./src/http/ngx_http_upstream.c: NGX_HTTP_CLIENT_CLOSED_REQUEST);
./src/http/ngx_http_upstream.c: NGX_HTTP_CLIENT_CLOSED_REQUEST);
./src/http/ngx_http_upstream.c: NGX_HTTP_CLIENT_CLOSED_REQUEST);
./src/http/ngx_http_upstream.c: NGX_HTTP_CLIENT_CLOSED_REQUEST);
./src/http/ngx_http_request.c: || rc == NGX_HTTP_CLIENT_CLOSED_REQUEST
./src/http/ngx_http_spdy.c: NGX_HTTP_CLIENT_CLOSED_REQUEST);
./src/http/ngx_http_spdy.c: ngx_http_spdy_finalize_connection(sc, NGX_HTTP_CLIENT_CLOSED_REQUEST);
./src/http/ngx_http_spdy.c: ngx_http_spdy_finalize_connection(sc, NGX_HTTP_CLIENT_CLOSED_REQUEST);
./src/http/ngx_http_spdy.c: ngx_http_spdy_finalize_connection(sc, NGX_HTTP_CLIENT_CLOSED_REQUEST);
./src/http/modules/tfs/ngx_http_tfs_server_handler.c: return NGX_HTTP_CLIENT_CLOSED_REQUEST;
./src/http/modules/tfs/ngx_http_tfs.c: if (rc == NGX_HTTP_CLIENT_CLOSED_REQUEST
./src/http/modules/tfs/ngx_http_tfs.c: NGX_HTTP_CLIENT_CLOSED_REQUEST);
./src/http/modules/lua/ngx_http_lua_socket_tcp.c: if (rc == NGX_HTTP_CLIENT_CLOSED_REQUEST) {
./src/http/modules/lua/ngx_http_lua_control.c: && rc != NGX_HTTP_CLIENT_CLOSED_REQUEST)
./src/http/modules/lua/ngx_http_lua_control.c: && rc != NGX_HTTP_CLIENT_CLOSED_REQUEST
./src/http/modules/lua/ngx_http_lua_subrequest.c: && rc != NGX_HTTP_CLIENT_CLOSED_REQUEST))
./src/http/modules/lua/ngx_http_lua_util.c: return NGX_HTTP_CLIENT_CLOSED_REQUEST;
./src/http/modules/lua/ngx_http_lua_util.c: return NGX_HTTP_CLIENT_CLOSED_REQUEST;
./src/http/modules/lua/ngx_http_lua_util.c: return NGX_HTTP_CLIENT_CLOSED_REQUEST;
./src/http/ngx_http_spdy_v3.c: NGX_HTTP_CLIENT_CLOSED_REQUEST);
./src/http/ngx_http_spdy_v3.c: ngx_http_spdy_finalize_connection(sc, NGX_HTTP_CLIENT_CLOSED_REQUEST);
./src/http/ngx_http_spdy_v3.c: ngx_http_spdy_finalize_connection(sc, NGX_HTTP_CLIENT_CLOSED_REQUEST);
./src/http/ngx_http_spdy_v3.c: ngx_http_spdy_finalize_connection(sc, NGX_HTTP_CLIENT_CLOSED_REQUEST);
./src/http/ngx_http_request.h:#define NGX_HTTP_CLIENT_CLOSED_REQUEST 499
第一处显示
#if (NGX_HAVE_KQUEUE) if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { if (!ev->pending_eof) {
return;
} ev->eof = 1;
c->error = 1; if (ev->kq_errno) {
ev->error = 1;
} if (!u->cacheable && u->peer.connection) {
ngx_log_error(NGX_LOG_INFO, ev->log, ev->kq_errno,
"kevent() reported that client prematurely closed "
"connection, so upstream connection is closed too");
ngx_http_upstream_finalize_request(r, u,
NGX_HTTP_CLIENT_CLOSED_REQUEST);
return;
} ngx_log_error(NGX_LOG_INFO, ev->log, ev->kq_errno,
"kevent() reported that client prematurely closed "
"connection"); if (u->peer.connection == NULL) {
ngx_http_upstream_finalize_request(r, u,
NGX_HTTP_CLIENT_CLOSED_REQUEST);
} return;
}
KQUEUE 这个是在unix下使用的网络模型,这里可以略过
第二处显示
static void
ngx_http_upstream_check_broken_connection(ngx_http_request_t *r,
ngx_event_t *ev)
{
int n;
char buf[1];
ngx_err_t err;
ngx_int_t event;
ngx_connection_t *c;
ngx_http_upstream_t *u; ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ev->log, 0,
"http upstream check client, write event:%d, \"%V\"",
ev->write, &r->uri); c = r->connection;
u = r->upstream; if (c->error) {
if ((ngx_event_flags & NGX_USE_LEVEL_EVENT) && ev->active) { event = ev->write ? NGX_WRITE_EVENT : NGX_READ_EVENT; if (ngx_del_event(ev, event, 0) != NGX_OK) {
ngx_http_upstream_finalize_request(r, u,
NGX_HTTP_INTERNAL_SERVER_ERROR);
return;
}
} if (!u->cacheable) {
ngx_http_upstream_finalize_request(r, u,
NGX_HTTP_CLIENT_CLOSED_REQUEST);
} return;
}
第三处显示
void
ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
{
ngx_connection_t *c;
ngx_http_request_t *pr;
ngx_http_core_loc_conf_t *clcf; c = r->connection; ngx_log_debug5(NGX_LOG_DEBUG_HTTP, c->log, 0,
"http finalize request: %d, \"%V?%V\" a:%d, c:%d",
rc, &r->uri, &r->args, r == c->data, r->main->count); if (rc == NGX_DONE) {
ngx_http_finalize_connection(r);
return;
} if (rc == NGX_OK && r->filter_finalize) {
c->error = 1;
} if (rc == NGX_DECLINED) {
r->content_handler = NULL;
r->write_event_handler = ngx_http_core_run_phases;
ngx_http_core_run_phases(r);
return;
} if (r != r->main && r->post_subrequest) {
rc = r->post_subrequest->handler(r, r->post_subrequest->data, rc);
} if (rc == NGX_ERROR
|| rc == NGX_HTTP_REQUEST_TIME_OUT
|| rc == NGX_HTTP_CLIENT_CLOSED_REQUEST
|| c->error)
{
if (ngx_http_post_action(r) == NGX_OK) {
return;
} if (r->main->blocked) {
r->write_event_handler = ngx_http_request_finalizer;
} ngx_http_terminate_request(r, rc);
return;
}
在收到读写事件处理之前时连接不可用
1、在一个upstream出错,执行next_upstream时也会判断连接是否可用,不可用则返回499
2、server处理请求未结束,而client提前关闭了连接
3、故障排除
nginx配置中加上
proxy_ignore_client_abort on; #表示代理服务端不要主要主动关闭客户端连接。
默认 proxy_ignore_client_abort 是关闭的,
关闭时:如果客户端端主动关闭请求或者客户端网络断掉, Nginx 会记录 499,同时 request_time 是「后端已经处理」的时间,而upstream_response_time 为“-“ (已验证)。
开启时:如果客户端端主动关闭请求或者客户端网络断掉,Nginx 会等待后端处理完(或者超时),然后记录「后端的返回信息」到日志。所以,如果后端返回 200,就记录 200 ;如果后端放回 5XX ,那么就记录 5XX 。
如果超时(默认60s,可以用 proxy_read_timeout 设置),Nginx 会主动断开连接,记录 504
注:只在做反向代理的时候加入,作为其他服务器的时候,关闭为好,默认设置是关闭的!
参考文章
http://blog.hexu.org/archives/1085.shtml
http://stackoverflow.com/questions/12973304/nginx-499-error-codes
https://httpstatuses.com/499
http://wmcxy.iteye.com/blog/2026835
http://ju.outofmemory.cn/entry/228858
http://www.90arther.net/jekyll/update/2015/11/19/repeat-request.html
Nginx状态码499的更多相关文章
- 08 . Nginx状态码
HTTP状态码 本篇文章主要介绍运维过程中经常遇到的状态码,并通过业界流行的Nginx进行模拟实现. 2XX状态码 2XX类型状态码表示一个HTTP请求成功,最典型的就是200 # 200状态码 # ...
- nginx状态码
200:服务器成功返回网页 403:服务器拒绝请求.404:请求的网页不存在 499:客户端主动断开了连接.500:服务器遇到错误,无法完成请求.502:服务器作为网关或代理,从上游服务器收到无效响应 ...
- Nginx状态码和日志
目录 一.Nginx状态返回码 二.Nginx日志统计 一.Nginx状态返回码 http返回状态码(Status-Code), 以3位数字组成 200 成功 301 永久重定向(redirect) ...
- nginx 状态码整理
状态代码 状态信息 含义 100 Continue 初始的请求已经接受,客户应当继续发送请求的其余部分.(HTTP 1.1新)101 Switching Protocols 服务器将遵从 ...
- zabbix监控nginx日志状态码
监控需求 监控Nginx常见的状态码并对其进行监控,对常见的错误状态码创建相对应的触发器以下按照分钟对数据进行抓取 Zabbix_Agentd创建监控脚本 1)创建脚本之前核对Nginx日志格式我这里 ...
- HTTP状态码面试必知
typora-root-url: ./HTTPCODE HTTP状态码必知必会 这里主要介绍运维过程中经常遇到的状态码.并通过业界流行的Nginx进行模拟实现,让大家能有一种所见即所得的感觉.希望大家 ...
- HTTP状态码分类及异常状态码处理
1xx:表示临时响应100:(继续)请求者应当继续提出请求.服务器返回此代码表示已收到请求的第一部分,正在等待其余部分101:(切换协议)请求者已要求服务器切换协议,服务器已确认并准备切换 2xx:表 ...
- nginx 499 状态码优化
在grafana界面中发现不少499的状态码,在网上了解到出现499的原因大体都是说服务端处理时间过长,客户端主动关闭了连接. 既然原因可能是服务端处理时间太长了,看一下upstream_resp ...
- Nginx_HTTP 499 状态码 nginx下 499错误
日志记录中HTTP状态码出现499错误有多种情况,我遇到的一种情况是nginx反代到一个永远打不开的后端,就这样了,日志状态记录是499.发送字节数是0. 老是有用户反映网站系统时好时坏,因为线上的产 ...
随机推荐
- Firemonkey Bitmap 设定像素颜色 Pixel
VCL 和 Firemonkey 的 Bitmap 处理像素的方式不相同,下例为将图片内不是「白色」的像素全部改成「黑色」: procedure TForm1.Button1Click(Sender: ...
- 2015暑假多校联合---Mahjong tree(树上DP 、深搜)
题目链接 http://acm.split.hdu.edu.cn/showproblem.php?pid=5379 Problem Description Little sun is an artis ...
- Scalaz(20)-Monad: Validation-Applicative版本的Either
scalaz还提供了个type class叫Validation.乍看起来跟\/没什么分别.实际上这个Validation是在\/的基础上增加了Applicative功能,就是实现了ap函数.通过Ap ...
- python tornado websocket 多聊天室(返回消息给部分连接者)
python tornado 构建多个聊天室, 多个聊天室之间相互独立, 实现服务器端将消息返回给相应的部分客户端! chatHome.py // 服务器端, 渲染主页 --> 聊天室建立web ...
- Mac 连接阿里云服务器
1. 通过命令行连接 Server 并设置 1.1 连接 Server #: ssh root@hctec.top ssh: 远程连接工具 root: 远程服务器用户名, 此处我用的是: root 用 ...
- CentOS6.5安装telnet命令
安装好memcache之后想进入连接测试,telnet localhost 11211发现竟然提示没有telnet这个命令,于是需要自己进行安装. 一.查看本机是否安装telnet #rpm -qa ...
- Java经典实例:纪元秒和本地日期时间互换
Java版本:1.8开始 import java.time.Instant; import java.time.ZoneId; import java.time.ZonedDateTime; /** ...
- Java继承中成员方法的overload(重载/过载)
如果Java基础类有一个方法名被"过载"使用多次,在衍生类里对那个方法名的重新定义就不会隐藏任何基础类的版本.所以无论方法在这一级还是在一个基础类中定义,过载都会生效. publi ...
- 高性能javascript学习笔记系列(4) -算法和流程控制
参考高性能javascript for in 循环 使用它可以遍历对象的属性名,但是每次的操作都会搜索实例或者原型的属性 导致使用for in 进行遍历会产生更多的开销 书中提到不要使用for in ...
- SQLMAP使用笔记
-u #注入点-f #指纹判别数据库类型-b #获取数据库版本信息-p #指定可测试的参数(?page=1&id=2 -p “page,id”)-D “” #指定数据库名-T “” #指定表名 ...