现象
nginx 在reload时,会对http keepalive的连接进行close操作。
抓包可以看见client收到了一个fin报文。
nginx 的worker也不会长时间留着shutdown状态,而是立刻退出。
4层的tcp监听上的连接,会使worker一直保留在shutdown状态。直到连接断开后,进程退出。
代码分析
一
见函数:ngx_worker_process_cycle,
所有idle的连接,会调用一次read的handler,然后将连接标记为close,最后在处理流程里根据这个标记,调用ngx_http_close_connection。关闭连接。
二
http keepalive过程
keepalive的连接会在每个request处理完的时候ngx_http_finalize_request调用连接关闭ngx_http_finalize_connection
在这个函数里,如果连接设了keepalive,就会进入 ngx_http_set_keepalive 函数
上述调用ngx_http_set_keepalive 函数的过程干三个事:
1 rev->handler = ngx_http_keepalive_handler;
2 c->idle = 1;
3 在2936行直接返回,跳过后面的connection close操作,所以连接还开着。
当 nginx reload的时候,2930或2931导致 ngx_http_set_keepalive 不会被调用,所以连接被关闭了,
抓包就看见了一个nginx到client的fin报文。
三
最后在函数ngx_worker_process_cycle,里。所有连接都关闭了,于是进程退出。
四
另外有个配置叫 worker_shutdown_timeout
https://nginx.org/en/docs/ngx_core_module.html#worker_shutdown_timeout
就是到时间之后,不管什么连接(包括tcp)全部断开进程退出,实现如下:将所有连接全部标记为close,然后再handler流程里close。
五
connection close的时候,会删掉read write timer,所有(三)里边的exit逻辑分支,再所有连接都断开了以后,就使进程退出了。
参考
https://github.com/alibaba/tengine/issues/1074
标签:http,nginx,reload,close,ngx,连接,keepalive From: https://www.cnblogs.com/hugetong/p/18605553