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. [转]JavaScript程序编码规范

    原文:http://javascript.crockford.com/code.html 作者:Douglas Crockford 译文:http://www.yeeyan.com/articles/ ...

  2. Data Structures/Algorithms 小甲鱼99讲笔记系列(1~~15讲)

    参考资料地址: http://www.icoolxue.com/ 1.数据结构中四种逻辑结构. ① 集合 集合中任何两个数据元素之间都没有逻辑关系,组织形式松散. ② 线性结构 线性结构中的 结点按逻 ...

  3. java 克隆

    1. About Java中, 对于基本数据类型可以使用"=" 来克隆,此时两个对象除了相等是没有任何关系的; 而对于引用类型, 却不能简单地使用"="来克隆, ...

  4. 十大Intellij IDEA快捷键

    转载:http://blog.csdn.net/dc_726/article/details/42784275 Intellij IDEA中有很多快捷键让人爱不释手,stackoverflow上也有一 ...

  5. Hibernate(一)__简介

    一. hibernate是什么 (一)hibernate 是一个orm框架,orm (object relation mapping) 对象关系映射框架 o object -> 业务层(只对对象 ...

  6. [AngularJS] 使用AngularCSS动态加载CSS

    [AngularJS] 使用AngularCSS动态加载CSS 前言 使用AngularAMD动态加载Controller 使用AngularAMD动态加载Service 上列两篇文章里,介绍了如何如 ...

  7. MySQL之浅谈MySQL的存储引擎

    什么是MySql数据库 通常意义上,数据库也就是数据的集合,具体到计算机上数据库可以是存储器上一些文件的集合或者一些内存数据的集合.     我们通常说的MySql数据库,sql server数据库等 ...

  8. 根据网址把图片下载到服务器C#代码

    根据网址把图片下载到服务器C#代码 ASPX页面代码: <%@ Page Language="C#" AutoEventWireup="true" Cod ...

  9. 基于 Node.js 平台的web开发框架-----express

    express官网:---->传送门  express express框架有许多功能,比如路由配置,中间件,对于想配置服务器的前端来说,非常便捷 自从node发展之后,基于nodejs的开发框架 ...

  10. PyCharm使用(完全图解(最新经典))

    PyCharm使用 一.PyCharm设置(版本:PyCharm 2016.1.2)  1.python环境设置        1.1.pycharm新建程序自动补全编码和环境: pycharm设置在 ...