From f64ec8c9056437bb1b822fc4e99f05f784d36e32 Mon Sep 17 00:00:00 2001 From: doujiang24 Date: Thu, 20 Sep 2018 23:46:24 +0800 Subject: [PATCH] bugfix: tcpsock:setkeepalive: worker processes might take too long to gracefully shut down when the keep alive connections take a long max idle time. Now we avoid putting any new connections into the pool when nginx is already shutting down. Signed-off-by: Yichun Zhang (agentzh) --- src/ngx_http_lua_socket_tcp.c | 10 ++++ t/157-socket-keepalive-hup.t | 91 +++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 t/157-socket-keepalive-hup.t diff --git a/src/ngx_http_lua_socket_tcp.c b/src/ngx_http_lua_socket_tcp.c index 0717c46d50..54b749326e 100644 --- a/src/ngx_http_lua_socket_tcp.c +++ b/src/ngx_http_lua_socket_tcp.c @@ -4690,6 +4690,14 @@ ngx_http_lua_socket_tcp_setkeepalive(lua_State *L) return 2; } + if (ngx_terminate || ngx_exiting) { + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0, + "lua tcp socket set keepalive while process exiting, " + "closing connection %p", c); + + goto finalize; + } + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0, "lua tcp socket set keepalive: saving connection %p", c); @@ -4854,6 +4862,8 @@ ngx_http_lua_socket_tcp_setkeepalive(lua_State *L) } } +finalize: + #if 1 ngx_http_lua_socket_tcp_finalize(r, u); #endif diff --git a/t/157-socket-keepalive-hup.t b/t/157-socket-keepalive-hup.t new file mode 100644 index 0000000000..5f59ec1c45 --- /dev/null +++ b/t/157-socket-keepalive-hup.t @@ -0,0 +1,91 @@ +# vim:set ft= ts=4 sw=4 et fdm=marker: + +our $SkipReason; + +BEGIN { + if ($ENV{TEST_NGINX_CHECK_LEAK}) { + $SkipReason = "unavailable for the hup tests"; + + } else { + $ENV{TEST_NGINX_USE_HUP} = 1; + undef $ENV{TEST_NGINX_USE_STAP}; + } +} + +use Test::Nginx::Socket::Lua $SkipReason ? (skip_all => $SkipReason) : (); + +repeat_each(2); + +plan tests => repeat_each() * (blocks() * 8); + +#no_diff(); +no_long_string(); + +worker_connections(1024); +run_tests(); + +__DATA__ + +=== TEST 1: exiting +--- config + location /t { + set $port $TEST_NGINX_SERVER_PORT; + + content_by_lua_block { + local f, err = io.open("t/servroot/logs/nginx.pid", "r") + if not f then + ngx.say("failed to open nginx.pid: ", err) + return + end + + local pid = f:read() + -- ngx.say("master pid: [", pid, "]") + + f:close() + + local i = 0 + local port = ngx.var.port + + local function f(premature) + print("timer prematurely expired: ", premature) + + local sock = ngx.socket.tcp() + + local ok, err = sock:connect("127.0.0.1", port) + if not ok then + print("failed to connect: ", err) + return + end + + local ok, err = sock:setkeepalive() + if not ok then + print("failed to setkeepalive: ", err) + return + end + + print("setkeepalive successfully") + end + local ok, err = ngx.timer.at(3, f) + if not ok then + ngx.say("failed to set timer: ", err) + return + end + ngx.say("registered timer") + os.execute("kill -HUP " .. pid) + } + } +--- request +GET /t + +--- response_body +registered timer + +--- wait: 0.3 +--- no_error_log +[error] +[alert] +[crit] +--- error_log +timer prematurely expired: true +setkeepalive successfully +lua tcp socket set keepalive while process exiting, closing connection