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