uwsgi+nginx结构下的nginx日志异常

我的小项目是django+uwsgi+nginx这样的结构,nginx的配置如下:

upstream myapp.test.com{
        server 10.*.*.*:8080;
        keepalive 768;
}

server {
        listen       443 ssl;
        server_name  myapp.test.com;
        access_log   /data/log/nginx/access.log main;
        error_log    /data/log/nginx/error.log;
        server_tokens off;

        ssl on;
        ssl_certificate ca256.crt;
        ssl_certificate_key ca256.key;
        ssl_session_timeout 30m;

        ssl_protocols TLSv1.2 TLSv1.1  TLSv1;
        ssl_ciphers ******;

        ssl_prefer_server_ciphers on;

        location ~* .*\.svn.* {
            return 404;
        }

        location / {
             include uwsgi_params;
             proxy_redirect off;
             proxy_store off;

             proxy_http_version 1.1;
             proxy_set_header Connection "";

             proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
             proxy_set_header X-Real-IP $remote_addr;
             proxy_set_header Host $http_host;

             proxy_pass http://myapp.test.com;

             proxy_connect_timeout 300;
             proxy_read_timeout 600;
             proxy_send_timeout 300;
        }

        location ~.*\.(html|htm|gif|jpg|bmp|png|ico|txt|js|css)$ {
             proxy_pass http://myapp.test.com;
        }
        location /static/ {
             alias /data/MyServer;
        }
}

另外还配置了

    # 当一个连接送达的请求数超过该值后,该连接就会被关闭
    keepalive_requests 8192;
    keepalive_timeout 65;

在执行过程中,nginx异常日志中会出现一些问题:

  1. recv() failed (104: Connection reset by peer) while reading response header from upstream

查阅资料的时候,看到不少答案说是因为客户端发送的请求头比较大,uwsgi默认接受的buffer不足以接受,需要增加buffer-size的值。我是在并发10000请求的情况下发生的这个问题,且虽然Nginx的错误日志中有异常记录,访问日志中的状态码全是200。
追寻该问题的时候,发现这个问题涉及到了nginx的长连接。

我配置了upstream的keepalive为768,官方解释:

  1. The connections parameter sets the maximum number of idle keepalive connections to upstream servers connections(设置到upstream服务器的空闲keepalive连接的最大数量)
  2. When this number is exceeded, the least recently used connections are closed. (当这个数量被突破时,最近使用最少的连接将被关闭)
  3. It should be particularly noted that the keepalive directive does not limit the total number of connections to upstream servers that an nginx worker process can open.(特别提醒:keepalive指令不会限制一个nginx worker进程到upstream服务器连接的总数量)

意思就是,当请求到达时,会使用长连接池中的长连接向后端转发请求,如果长连接池没有空闲的连接可用,那么会创建一个新的长连接去处理该请求,后端执行一段时间后,一些长连接空闲了下来,如果空闲的长连接数量多于keepalive的设置,那么会将最近最少使用的长连接关闭。nginx错误日志中出现recv() failed (104: Connection reset by peer)”和”upstream prematurely closed connection”这两个错误记录,但是访问日志中却没有出现错误的状态码,是因为nginx关闭了最近最少使用的长连接导致的。当我将配置中的以下行去除之后,该问题就消失了。

        keepalive 768;
        ........
             proxy_http_version 1.1;
             proxy_set_header Connection "";

http1.1协议是默认使用长连接的,去除”proxy_http_version”和”proxy_set_header”后将使用http1.0协议;去除”keepalive 768;”的将不再使用长连接。

长连接是比较有效率的,能够节省tcp三次握手的开销。不使用长连接虽然有效减少了nginx的错误日志,但是这并不是一个好的解决方案。

参考资料

  1. 【Nginx Upstream Keepalive 分析】
  2. 【nginx访问日志,错误日志参数说明】
  3. 【nginx - KeepAlive详细解释】
  4. 【nginx配置长连接—keepalive相关】

猜你喜欢

转载自blog.csdn.net/lj1404536198/article/details/81538844
今日推荐