Nginx reload + Websockets

Maxim Dounin mdounin на mdounin.ru
Чт Апр 8 15:38:46 UTC 2021


Hello!

On Thu, Apr 08, 2021 at 03:28:25AM -0400, Vladislavik wrote:

> Добрый день, есть 200k websocket соединений на проксируемый сервер, после
> изменения в конфиге и попытке reload nginx появляются новые процессы nginx и
> зависают прошлые в статусе "nginx shutting down", которые так и не
> завершаются, тк клиенты могут висеть онлайн долго, эти старые процессы можно
> убить kill -9 pid каждый, но в этом случае nginx продолжает в /nginx_status
> показывать счетчик коннектов с учетом старых соединений из убитых процессов
> плюс заново переподключившиеся (количество коннектов после каждого reload
> растет в геометрической прогрессии), хотя в работе после kill старых nginx
> процессов остаются только новые процессы. Полностью сбросить счетчик
> коннектов получается только через restart nginx, но в этом случае все
> websocket клиенты одновременно начинают заново стучаться на сервер, чего
> тоже не хотелось бы, вопрос: как мягко применять новый конфиг nginx и
> переподключать websocket соединения хотя бы пачками, а не все одним
> моментом?

Самое простое и наиболее правильное решение - периодически 
переоткрывать соединения со стороны клиента и/или закрывать их со 
стороны websocket-сервера.  Такой подход, в частности, гарантирует 
отсутствие race'ов, если внутри websocket-соединений делается 
что-то неидемпотентное.  Это, однако, требуется реализовывать на 
клиенте и/или на стороне websocket-сервера.

Если этого не сделано, то существует ручка 
worker_shutdown_timeout, убивающая все оставшиеся соединения по 
истечении заданного таймаута.

Если при этом нужно ещё и убивать соединения плавно - можно это 
делать руками, то есть смотреть на списки соединений конкретных 
старых процессов и использовать tcpdrop(8).  Вроде бы даже на 
Линуксе сейчас доступен аналог.

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


Подробная информация о списке рассылки nginx-ru