Zero-downtime reload Nginx: ошибки и рабочие приёмы
Reload Nginx не равен перезапуску сервиса: мастер запускает новые worker-процессы, а старые завершают текущие соединения. Разбираем безопасную последовательность, типичные сбои и случаи, когда zero-downtime всё же не получается.

Безостановочный reload Nginx занимает секунды, но ошибка в одном шаге превращает его либо в недоступность сайта, либо в очередь старых worker-процессов, которые не хотят завершаться. Для Nginx Open Source 1.24–1.27 безопасная схема выглядит так: проверить весь активный конфиг, отправить master-процессу сигнал reload, затем убедиться, что новые worker-процессы приняли конфигурацию, а старые действительно ушли. Ниже — два рабочих способа, цена каждого и ситуации, в которых graceful-перезапуск не спасает.
Что именно происходит во время reload
Nginx не перечитывает конфигурацию внутри уже работающих worker-процессов. Master-процесс сначала проверяет новый конфиг, затем запускает новый набор worker-процессов с обновлёнными настройками. Старым worker он сообщает, что больше не нужно принимать новые соединения, но текущие запросы они должны завершить.
Слушающие сокеты при этом не закрываются. Поэтому новые подключения не должны попадать в короткое окно недоступности, как это бывает при полном stop/start. Однако zero-downtime относится к перезапуску самого Nginx, а не к любому изменению системы: если новый upstream не отвечает, сертификат не читается или приложение за nginx перезапустили отдельно, пользователи всё равно увидят ошибки.
Reload без проверки конфига — это не автоматизация, а перенос ошибки из терминала в продакшен.
Три процесса, которые важно различать
- Master принимает управляющие сигналы, читает конфигурацию и запускает worker-процессы.
- Worker обслуживает HTTP-, HTTPS-, proxy- и другие соединения.
- Старый worker после reload перестаёт принимать новые запросы, но может жить долго из-за загрузки, WebSocket или долгого upstream-запроса.
Сноска. Graceful shutdown — мягкое завершение процесса: он прекращает брать новые соединения и ждёт окончания уже начатых операций. Если ожидание ограничить директивой worker_shutdown_timeout, после истечения времени Nginx принудительно закроет оставшиеся соединения.
Два способа выполнить reload
Для установки из системного пакета предпочтителен systemd: он знает PID master-процесса и учитывает unit-файл дистрибутива. Прямой вызов Nginx удобен в контейнере или при собственной установке, но требует правильно определённого PID-файла.
| Способ | Когда выбирать | Цена и риск |
|---|---|---|
systemctl reload nginx | Debian, Ubuntu, RHEL и другие системы с systemd | Меньше ручной работы; поведение зависит от unit-файла пакета |
nginx -s reload | Контейнер, ручная установка, отдельный master-процесс | Нужно попасть в правильный конфиг и PID; ошибка окружения остановит операцию |
systemctl restart nginx | Только когда требуется полностью остановить и запустить сервис | Есть окно недоступности и риск оборвать активные соединения |
В production-пайплайне различие между reload и restart должно быть явным. Команда, которая случайно вызывает restart, может оборвать загрузку файла, WebSocket-сессию или длинный запрос даже при корректном новом конфиге.
Рабочая последовательность для systemd
Ниже приведён минимальный сценарий для Nginx Open Source 1.24–1.27 на Linux с systemd. Команды требуют прав root или доступа через sudo.
- Проверьте конфигурацию. Выполните
sudo nginx -t. Команда должна закончиться сообщениями о том, что синтаксис корректен и тест прошёл успешно. Если проверка завершилась ошибкой, reload не запускайте. - Посмотрите, какой конфиг реально читает процесс. Выполните
sudo nginx -Tи убедитесь, что изменённый файл подключён черезinclude. В выводе должна присутствовать нужная директива или блокserver, а не только файл, который вы редактировали. - Отправьте reload. Выполните
sudo systemctl reload nginx. Команда должна завершиться без ошибки. Это не перезапускает сервис с закрытием слушающих сокетов. - Проверьте журнал. Выполните
sudo journalctl -u nginx --since -2min. Ищите сообщения о перезагрузке worker-процессов и ошибки открытия файлов, сертификатов, upstream или разрешений. - Проверьте ответ снаружи. Выполните
curl -I https://example.com, заменив домен на свой. Должен вернуться ожидаемый HTTP-статус и нужные заголовки, а не ошибка соединения или ответ от старого маршрута.
Почему порядок важен: nginx -t проверяет не отдельный фрагмент, а собранную конфигурацию со всеми подключёнными файлами. Обычный редактор не покажет, что ошибка находится в другом include.
Прямой reload без systemd
Если Nginx запущен в контейнере или установлен вручную, используйте управляющий сигнал через сам бинарник:
nginx -t
nginx -s reload
Команды должны выполняться в том же окружении, где запущен master-процесс: с тем же конфигурационным файлом и доступом к его PID-файлу. Если используется нестандартный путь к конфигу, передайте его явно в обе команды, например nginx -c /etc/nginx/nginx.conf -t и затем nginx -c /etc/nginx/nginx.conf -s reload. Путь должен совпадать с тем, который использует работающий master.
Типичные ошибки и как их находить
Reload заменили на restart
Самая дорогая ошибка — использовать restart для обычного изменения маршрута, заголовка или сертификата. Сервис остановится и запустится заново, а уже открытые соединения будут разорваны. Оставляйте restart для случаев, когда нужно изменить параметры запуска, бинарник или исправить состояние процесса. Для конфигурации сначала используйте test и reload.
Проверили только синтаксис, но не поведение
Успешный nginx -t не означает, что приложение за Nginx доступно. Конфигурация может быть синтаксически верной, но указывать на неправильный порт, недоступное имя сервиса или несуществующий сертификат в окружении запуска. После reload проверьте конкретные URL, статус upstream-приложения и свежие записи error log.
Редактировали не тот конфиг
На сервере могут сосуществовать системный Nginx, контейнер и ручная сборка. nginx -V показывает параметры сборки, включая путь к основному конфигу, а nginx -T — итоговую конфигурацию. Если изменения не видны в выводе nginx -T, reload не мог их применить.
Старые worker-процессы не завершаются
Это ожидаемо при долгих запросах, больших загрузках, Server-Sent Events и WebSocket. Проверьте список процессов и время их жизни. Если старые worker остаются после завершения обычных запросов, ищите соединения, которые удерживает клиент или upstream. Не добавляйте маленький worker_shutdown_timeout вслепую: он может оборвать легитимную загрузку.
Конфигурацию перезагружают слишком часто
Частые reload сами по себе не дают нулевой стоимости. При каждом изменении появляются новые worker-процессы, а старые должны завершить работу. Если деплой отправляет несколько сигналов подряд, накопление процессов и расход памяти становится заметным именно во время пикового трафика. Объединяйте изменения и делайте один reload после полной проверки.
Что выбирать в разных сценариях
- Изменили location, proxy_pass или заголовки. Выполните
nginx -t, затем reload и проверку реального URL. - Заменили сертификат. Проверьте пути, права на чтение и срок действия сертификата, затем reload. Отдельно проверьте TLS снаружи, потому что HTTP-тест не проверяет сертификат.
- Изменили переменные окружения приложения. Reload Nginx не перезапускает upstream-приложение и не обновляет его окружение. Изменение нужно применить к тому сервису, который эти переменные читает.
- Обновили бинарник Nginx. Обычный reload не равен обновлению процесса. Для пакетного обновления следуйте процедуре дистрибутива и документации Nginx, затем отдельно проверьте, какие процессы работают.
Где zero-downtime ломается
Безостановочный reload не гарантирует отсутствие ошибок при неверном upstream, несовместимом изменении схемы приложения, истёкшем сертификате или закрытии внешнего балансировщика. Он также не синхронизирует несколько серверов: если конфиг раскатывается на десять узлов, каждый узел нужно проверить отдельно, а порядок обновления — согласовать с балансировщиком.
Для измерения результата не придумывайте среднее время ответа по одному запросу. Сравните долю ответов 5xx до и после reload, число активных соединений, количество старых worker-процессов и ошибки в error log на одном и том же интервале. Важны и длинные запросы: именно они чаще всего показывают, что graceful-завершение не закончилось.
Что делать дальше
Добавьте в deploy-пайплайн последовательность nginx -t, один reload и проверку health endpoint через внешний адрес. Отдельно настройте наблюдение за 5xx, временем ответа, количеством worker-процессов и незавершёнными соединениями. Следующий практический шаг — проверить процедуру на стенде с долгим запросом или WebSocket: только такой тест покажет, как именно ваша версия Nginx и приложение ведут себя во время graceful reload.
Инфографика для маркетплейса: Три главных преимущества товара короткими фразами, выноски в безопасной зоне превью, точный размер площадки.
Спросить за 60 ₽Источники: Nginx documentation: Controlling nginx, Nginx documentation: nginx command-line parameters
Частые вопросы
Нужно ли перезапускать Nginx после изменения конфигурации?
Почему после reload старые worker-процессы ещё видны?
Что делать, если nginx -t завершился ошибкой?
Почему reload прошёл, но сайт продолжает работать по старому маршруту?
Сломаются ли WebSocket и долгие загрузки во время reload?
Можно ли считать reload полностью безопасным?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.