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、问题分析

google

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的更多相关文章

  1. 08 . Nginx状态码

    HTTP状态码 本篇文章主要介绍运维过程中经常遇到的状态码,并通过业界流行的Nginx进行模拟实现. 2XX状态码 2XX类型状态码表示一个HTTP请求成功,最典型的就是200 # 200状态码 # ...

  2. nginx状态码

    200:服务器成功返回网页 403:服务器拒绝请求.404:请求的网页不存在 499:客户端主动断开了连接.500:服务器遇到错误,无法完成请求.502:服务器作为网关或代理,从上游服务器收到无效响应 ...

  3. Nginx状态码和日志

    目录 一.Nginx状态返回码 二.Nginx日志统计 一.Nginx状态返回码 http返回状态码(Status-Code), 以3位数字组成 200 成功 301 永久重定向(redirect) ...

  4. nginx 状态码整理

    状态代码    状态信息     含义 100 Continue 初始的请求已经接受,客户应当继续发送请求的其余部分.(HTTP 1.1新)101 Switching Protocols 服务器将遵从 ...

  5. zabbix监控nginx日志状态码

    监控需求 监控Nginx常见的状态码并对其进行监控,对常见的错误状态码创建相对应的触发器以下按照分钟对数据进行抓取 Zabbix_Agentd创建监控脚本 1)创建脚本之前核对Nginx日志格式我这里 ...

  6. HTTP状态码面试必知

    typora-root-url: ./HTTPCODE HTTP状态码必知必会 这里主要介绍运维过程中经常遇到的状态码.并通过业界流行的Nginx进行模拟实现,让大家能有一种所见即所得的感觉.希望大家 ...

  7. HTTP状态码分类及异常状态码处理

    1xx:表示临时响应100:(继续)请求者应当继续提出请求.服务器返回此代码表示已收到请求的第一部分,正在等待其余部分101:(切换协议)请求者已要求服务器切换协议,服务器已确认并准备切换 2xx:表 ...

  8. nginx 499 状态码优化

    在grafana界面中发现不少499的状态码,在网上了解到出现499的原因大体都是说服务端处理时间过长,客户端主动关闭了连接.   既然原因可能是服务端处理时间太长了,看一下upstream_resp ...

  9. Nginx_HTTP 499 状态码 nginx下 499错误

    日志记录中HTTP状态码出现499错误有多种情况,我遇到的一种情况是nginx反代到一个永远打不开的后端,就这样了,日志状态记录是499.发送字节数是0. 老是有用户反映网站系统时好时坏,因为线上的产 ...

随机推荐

  1. 在spring中使用webservice(Restful风格)

    我们一般都会用webservice来做远程调用,大概有两种方式,其中一种方式rest风格的简单明了. 记录下来作为笔记: 开发服务端: 具体的语法就不讲什么了,这个网上太多了,而且只要看一下代码基本上 ...

  2. jquery的ajax可以传入的三种参数类型

    在jquery的ajax函数中,可以传入3种类型的数据 1.文本:"uname=alice&mobileIpt=110&birthday=1983-05-12" 2 ...

  3. Eclipse功能集合

    大家好,这篇博客的目的是总结一下Eclipse这个软件中一些不为常用的功能.与大家分享.谢谢~ 1.利用one hour看了一下Eclipse的使用,用two hour写了这篇blog. 2.在现实项 ...

  4. 代码设置Shape和Selector

    开发中经常需要使用Shape和Selector,如果每个都用xml设置的话,会占用apk大小,同时命名多了也会混乱,使用代码来设置会方便很多. 需要用到2个类:GradientDrawable和Sta ...

  5. Properties+重温Map+本地计数器

    昨天想写一个记账本,发现并不能把项目名称与内容关联起来,于是乎我想到了map,可是又不知道map储存到文件中又怎么读出来,幸好今天遇到了properties Properties是Hashtable的 ...

  6. Vanilla Masker – 功能强大的输入过滤插件

    Vanilla Masker 是一个纯 JavaScript 实现的输入内容过滤和自动转换插件.现在你可以使用一个简单而纯粹的 JavaScript 库来控制你的 input 元素,而不需要加载 jQ ...

  7. [deviceone开发]-doSpace应用源码开源

    一.简介 这个是我们的一个门户App,能够动态加载示例,查看文档,视频,朋友圈聊天等功能.目前开源供大家参考学习,另外"讨论"里对应的BBS上有详细的文档说明,非常值得大家参考和学 ...

  8. Javascript的历史

    阅读了JavaScript dom简史,从网上看了下,学问很深啊. 首先简单说下网景公司(Netscape)的发展史:1993年,美国国家超级计算机应用中心(NCSA),发表了一个浏览器,命名为“Mo ...

  9. 如何对sharepoint图片库的文件夹的图片按照时间排序并分页显示

    /// <summary> /// 获取图片库第一层文件夹--根据文件夹名称排序 /// </summary> /// <param name="siteUrl ...

  10. GP服务将矢量数据加入到栅格数据中的方法

    1.如何将矢量数据加入栅格数据中 1.  Conversion Tools -->To Raster-->Polygon to Raster 2. Spatial Analyst Tool ...