nginx499 body_bytes_sent 为0 的情况

发现线上有大量499的请求,然后看见有的499的请求body_bytes_sent 为0,所以就此情况查看一番。

复现场景:192.168.60.128 上面请求192.168.60.150的机器,150上的应用接口执行时间30秒,128上面的超时时间2秒,此时nginx返回了499,body_bytes_sent为0。

1、128请求模拟

>>> requests.get('http://192.168.226.150/', timeout=2)

2、150 nginx配置

worker_processes  1;
events {
    worker_connections  1024;
}
http {
    lua_package_path "/usr/local/openresty/lualib/myapp/lua/?.lua;;";
    init_by_lua_block {
       require "hello"
    }

    log_format main '{"@timestamp":"$time_iso8601",'
                   '"host":"$server_addr",'
                   '"remote_addr":"$remote_addr",'
                   '"body_bytes_sent":"$body_bytes_sent",'
                   '"request_time":"$request_time",'
                   '"upstreamtime":"$upstream_response_time",'
                   '"upstream_addr":"$upstream_addr",'
                   '"http_host":"$host",'
                   '"url":"$uri",'
                   '"request":"$request",'
                   '"request_for_keyword":"$request",'
                   #'"request_body":"$request_body",'
                   '"domain":"$host",'
                   '"http_x_forwarded_for":"$http_x_forwarded_for",'
                   '"user-agent":"$http_user_agent",'
                   '"http_referer":"$http_referer",'
                   '"status":"$status"}';

    access_log  /usr/local/openresty/nginx/logs/access.log  main;


    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    server {
        listen       80;
        server_name  localhost;
        location / {
        #content_by_lua_block {
            #    local hello = require "hello"
            #    hello.greet("a Lua module")
            #}
            #root index.html;
            proxy_pass http://127.0.0.1:8123;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}
View Code

3、150接口

from flask import Flask
import time

app = Flask(__name__) 
@app.route('/') 
def hello():
    for i in range(30):
        time.sleep(1)
    return 'Hello World'

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=8123,debug=True)
View Code

4、请求之后日志情况

{"@timestamp":"2022-06-17T15:49:42+08:00","host":"192.168.226.150","remote_addr":"192.168.226.128","body_bytes_sent":"0","request_time":"2.007","upstreamtime":"2.007","upstream_addr":"127.0.0.1:8123","http_host":"192.168.226.150","url":"/","request":"GET / HTTP/1.1","request_for_keyword":"GET / HTTP/1.1","domain":"192.168.226.150","http_x_forwarded_for":"-","user-agent":"python-requests/2.24.0","http_referer":"-","status":"499"}

 

5、抓包对比

 

 上面是请求超时返回499的情况,客户端未等服务端返回主动断开连接,下面是请求超时返回200的情况。上图为啥不是四次挥手?网上各种解释乱七八糟的,说是第二次和第三次都放在了第二次。

 

6、nginx 源码,这个需要细品。

static ngx_int_t
ngx_http_variable_body_bytes_sent(ngx_http_request_t *r,
    ngx_http_variable_value_t *v, uintptr_t data)
{
    off_t    sent;
    u_char  *p;

    sent = r->connection->sent - r->header_size;

    if (sent < 0) {
        sent = 0;
    }

    p = ngx_pnalloc(r->pool, NGX_OFF_T_LEN);
    if (p == NULL) {
        return NGX_ERROR;
    }

    v->len = ngx_sprintf(p, "%O", sent) - p;
    v->valid = 1;
    v->no_cacheable = 0;
    v->not_found = 0;
    v->data = p;

    return NGX_OK;
}

 

posted @ 2022-06-17 17:39  JvvYou  阅读(1896)  评论(0编辑  收藏  举报