Http2 idle connection and worker shutdown

Maxim Dounin mdounin at mdounin.ru
Thu Oct 20 21:19:13 UTC 2022


Hello!

On Thu, Oct 20, 2022 at 10:51:06AM -0700, Jojy Varghese via nginx-devel wrote:

> Hi
>   We noticed that the Http2 idle flag 
>   (https://github.com/nginx/nginx/blob/master/src/http/v2/ngx_http_v2.h#L126) 
>   is initialized to `1` 
>   (https://github.com/nginx/nginx/blob/master/src/http/v2/ngx_http_v2.c#L335) 
>   but not reset by  the http2 state machine. It also looks like 
>   Nginx does not set keep alive timer for http2 as the keep 
>   alive setter code path is short circuited for http2 
>   (https://github.com/nginx/nginx/blob/master/src/http/ngx_http_request.c#L2706). 
> 
>   During worker shutdown when idle connections are reaped 
>   (https://github.com/nginx/nginx/blob/master/src/core/ngx_connection.c#L1363), 
>   due to the fact that http2 connections are always `idle`,  
>   ongoing streams end up prematurely getting closed on the read 
>   side(sends GOAWAY frame). 

No streams are closed by the http2 connection read handler when 
it's called by ngx_close_idle_connections().  Consider re-checking 
the ngx_http_v2_read_handler() code:

http://hg.nginx.org/nginx/file/tip/src/http/v2/ngx_http_v2.c#l365

Instead, the handler closes the connection as long as there are no 
active streams.  If there are any active streams, it sends the 
GOAWAY frame to the connection, so the client will know that no 
additional streams will be accepted, and proceeds with normal 
handling of the remaining streams.

> It looks like the `idle` connection implementation as it is 
> today only answers the question - “Can nginx prematurely close 
> the streams when shutting down?”   Is the above behavior 
> intentional? 
> 
> It appears from the name of the flag (`idle`) that the intent is 
> to reflect the dynamic state of the connection (are reads and 
> writes happening for the connection for any of the streams) but 
> the implementation does not reflect that.
> 
> What is the intended behavior ? We would have liked a `idle` 
> flag with its corresponding timeout configuration that lets us 
> control the behavior during shutdown (and other flows).

The "idle" flag used to be a way to distinguish HTTP connections 
without active requests and therefore prepared to be closed during 
shutdown by calling c->read->handler() with c->close set.  With 
HTTP/2, essentially all connections are prepared to be closed 
during shutdown (in some cases this may take a while though), so 
all HTTP/2 connections have c->idle flag set.  While from 
linguistic point of view this isn't exactly correct, it's 
certainly correct from semantic point of view and believed to 
result in correct behaviour.

If you think that nginx does something wrong, you may want to 
elaborate on the details of the incorrect behaviour you observe 
(as well as why you think it's incorrect, and how would you like 
to improve it).

Hope this helps.

-- 
Maxim Dounin
http://mdounin.ru/



More information about the nginx-devel mailing list