Как перезапустить nginx только после успешной проверки конфигурации в Ubuntu?

111

Когда я перезапускаю службу nginx в командной строке на сервере Ubuntu, служба вылетает из-за ошибок в файле конфигурации nginx. На многосайтовом сервере это отключает все сайты, даже те, которые не содержат ошибок конфигурации.

Чтобы предотвратить это, я сначала запускаю тест конфигурации nginx:

nginx -t

После успешного прохождения теста я мог перезапустить службу:

/etc/init.d/nginx restart

Или только перезагрузите конфиги сайта nignx без перезагрузки:

nginx -s reload

Есть ли способ объединить эти две команды, если команда перезапуска зависит от результата теста конфигурации?

Я не смог найти это в Интернете, и официальная документация по этому поводу довольно проста. Я не так хорошо разбираюсь в Linux, поэтому не знаю, есть ли то, что я ищу, прямо передо мной или вообще невозможно.

Я использую nginx v1.1.19.

январь
источник
Как насчет небольшого сценария оболочки, который проверяет статус возврата nginx -t (с $?), А затем выполняет перезапуск в зависимости от состояния возврата?
TeTeT 03

Ответы:

49

На самом деле, насколько я знаю, nginx будет показывать пустое сообщение и не перезапускается, если конфигурация плохая.

Единственный способ облажаться - это остановить nginx, а затем начать заново. Остановить удалось бы, но не начать.

Мохаммад Абу-Шади
источник
1
О какой версии nginx вы говорите? Я работаю с версией 1.1.19, и она попытается перезагрузиться независимо от ошибок в файлах конфигурации. Он сообщит мне , что есть проблема, но тогда это уже слишком поздно
джан
5
Хорошо, я только что протестировал его, на моем ноутбуке есть nginx 1.2, и он работал, как я описал, мой VPS имеет 1.1.19, как ваш, и он сделал то же, что вы описали в своем вопросе. Итак, я думаю, это было обработано в 1.2
Мохаммад Абу-Шади
Большой! Спасибо, что разобрались для меня. Я оставлю вопрос открытым еще немного, чтобы увидеть, нет ли ответа для nginx <v1.2
янв.
1
Я предполагаю , что я должен буду обновить то :-) нужен был повод в любом случае
джан
1
service nginx reloadничего не показывает, правильно ли была загружена конфигурация, поэтому бесполезно, если вы подозреваете, что конфигурация может быть неправильной. service nginx restartостановит сервер, если в конфиге есть ошибка!
Дэн Даскалеску
80

Начиная с nginx 1.8.0, правильным решением является

sudo nginx -t && sudo service nginx reload

Обратите внимание, что из-за ошибки configtestвсегда возвращается нулевой код выхода, даже если в файле конфигурации есть ошибка.

Дэн Даскалеску
источник
3
nginx -t && sudo nginx -s reload
MechanisM
5
@MechanisM: nginx -tбез sudo почти наверняка выйдет из строя из-за ошибок разрешения.
Дэн Даскалеску
Я хотел показать в основном последнюю часть для перезарядки. В моем случае я скомпилировал nginx на заказ, и у меня даже нет никаких скриптов в /etc/init.d и так далее, поэтому в моем случае «перезагрузка службы nginx» ничего не сделает
MechanisM
39

Я использую следующую команду для перезагрузки Nginx (версия 1.5.9), только если тест конфигурации прошел успешно:

/etc/init.d/nginx configtest && sudo /etc/init.d/nginx reload

Если вам нужно делать это часто, вы можете использовать псевдоним. Я использую следующее:

alias n='/etc/init.d/nginx configtest && sudo /etc/init.d/nginx reload'

Уловка здесь выполняется с помощью «&&», который выполняет вторую команду только в том случае, если первая была успешной. Вы можете увидеть здесь более подробное объяснение использования оператора «&&».

Вы можете использовать «перезапуск» вместо «перезагрузки», если действительно хотите перезапустить сервер.

Маурисио Санчес
источник
Остерегайтесь nginx 1.4.2, который я обнаружил pkill -1 nginx(фактически то, что делает моя перезагрузка init.d / nginx) НЕ перезагружается, если конфигурация терпит неудачу и ошибочно возвращает успех. Проверьте свои версии.
KCD
2
У меня это не работает. Обе команды выполняются, даже если тест не проходит.
Mario Campa
2
configtest всегда возвращает нулевой код выхода , по крайней мере, в nginx 1.8.0. nginx -tВместо этого используйте .
Дэн Даскалеску
8
alias nginx.start='sudo nginx -c /etc/nginx/nginx.conf'
alias nginx.stop='sudo nginx -s stop'
alias nginx.reload='sudo nginx -s reload'
alias nginx.config='sudo nginx -t'
alias nginx.restart='nginx.config && nginx.stop && nginx.start'
alias nginx.errors='tail -250f /var/logs/nginx.error.log'
alias nginx.access='tail -250f /var/logs/nginx.access.log'
alias nginx.logs.default.access='tail -250f /var/logs/nginx.default.access.log'
alias nginx.logs.default-ssl.access='tail -250f /var/logs/nginx.default.ssl.log'

а затем используйте команды "nginx.reload" и т. д.

Механизм
источник
6

Вы можете перезагрузить, используя /etc/init.d/nginx reloadиsudo service nginx reload

Если nginx -tвыдает ошибку, он не перезагружается

поэтому используйте && для одновременного запуска обоих

лайк

nginx -t && /etc/init.d/nginx reload

Гокул Кандасамы
источник
Позвольте мне научить вас кое-чему о bash. && не run both at a same timeвыполняет команду справа, ЕСЛИ команда слева возвращает код выхода 0. Если вы nginx -tвыдаете ошибку, код выхода не будет равен 0, поэтому вторая команда не будет запущена. В nginx -s reloadлюбом случае
miknik 07
@miknik Я думаю, это то, что он хотел сказать, просто не получилось. Он говорит If nginx -t throws some error then it won't reload. Заявление run both at a same timeтакже можно интерпретировать как одну команду или одну строку. Я не интерпретирую его слова в данном случае in parallel.
matt
2

Вы можете использовать сигналы для управления nginx.

Согласно документации, вам необходимо отправить сигнал HUP в главный процесс nginx.

HUP - изменение конфигурации, соответствие измененному часовому поясу (только для FreeBSD и Linux), запуск новых рабочих процессов с новой конфигурацией, плавное завершение старых рабочих процессов

Смотрите документацию здесь: http://nginx.org/en/docs/control.html

Вы можете отправить сигнал HUP на PID главного процесса nginx следующим образом:

kill -HUP $( cat /var/run/nginx.pid )

Приведенная выше команда считывает PID nginx из /var/run/nginx.pid. По умолчанию в nginx записывается pid, /usr/local/nginx/logs/nginx.pidно его можно переопределить в config. Проверьте свой, nginx.configчтобы увидеть, где он сохраняет PID.

Hcristea
источник
1

По крайней мере, в Debian сценарий запуска nginx имеет функцию перезагрузки, которая:

reload)
  log_daemon_msg "Reloading $DESC configuration" "$NAME"
  test_nginx_config
  start-stop-daemon --stop --signal HUP --quiet --pidfile $PID \
   --oknodo --exec $DAEMON
  log_end_msg $?
  ;;

Похоже, все, что вам нужно сделать, это позвонить, service nginx reloadа не restartтак как он звонит test_nginx_config.

Daenney
источник
service nginx reloadне будет давать никаких указаний на то, была ли конфигурация проверена нормально или нет, и была ли она перезагружена или нет.
Дэн Даскалеску
Что test_nginx_configтогда делать в таком случае?
Daenney 02
1
Я думаю, вы оба правы. service nginx reloadдостаточно в командной строке, однако иногда вам может потребоваться захватить вывод stderr и вернуть его обратно в сценарий для устранения неполадок. nginx -tсообщит вам, в каком файле указан недопустимый параметр и в какой строке.
anastymous