Jak ponownie uruchomić Nginx dopiero po pomyślnym zakończeniu testu konfiguracji w systemie Ubuntu?

111

Kiedy ponownie uruchamiam usługę Nginx w wierszu poleceń na serwerze Ubuntu, usługa ulega awarii, gdy plik konfiguracyjny Nginx zawiera błędy. Na serwerze z wieloma lokacjami powoduje to wyłączenie wszystkich witryn, nawet tych bez błędów konfiguracji.

Aby temu zapobiec, najpierw uruchamiam test konfiguracji nginx:

nginx -t

Po pomyślnym zakończeniu testu mogłem ponownie uruchomić usługę:

/etc/init.d/nginx restart

Lub tylko przeładuj konfiguracje witryny nignx bez ponownego uruchamiania:

nginx -s reload

Czy istnieje sposób na połączenie tych dwóch poleceń, w których polecenie restartu jest uzależnione od wyniku testu konfiguracji?

Nie mogłem znaleźć tego w Internecie, a oficjalna dokumentacja na ten temat jest raczej podstawowa. Nie znam tak dobrze Linuksa, więc nie wiem, czy to, czego szukam, jest tuż przede mną, czy w ogóle niemożliwe.

Używam nginx v1.1.19.

sty
źródło
A co z małym skryptem powłoki, który sprawdza stan powrotu nginx -t (z $?), A następnie uruchamia się ponownie w zależności od stanu powrotu?
TeTeT

Odpowiedzi:

49

Właściwie, o ile wiem, nginx wyświetli pusty komunikat i nie uruchomi się ponownie, jeśli konfiguracja jest zła.

Jedynym sposobem, aby to schrzanić, jest zatrzymanie nginx, a następnie ponowne rozpoczęcie. Udało się zatrzymać, ale nie uruchomić.

Mohammad AbuShady
źródło
1
O jakiej wersji Nginx mówisz? Pracuję z wersją 1.1.19 i spróbuję restartować bez względu na jakiekolwiek błędy w plikach konfiguracyjnych. Powiadomi mnie, że jest problem, ale wtedy jest już za późno
sty
5
Ok, właśnie to przetestowałem, mój laptop ma nginx 1.2 i działał tak, jak opisałem, mój VPS ma 1.1.19 jak twój i zrobił to samo, co opisałeś w swoim pytaniu. Więc myślę, że zostało to rozwiązane w 1.2
Mohammad AbuShady,
Wspaniały! Dzięki, że się o tym przekonałeś. Zostawię to pytanie trochę dłużej, aby zobaczyć, czy nikt nie ma odpowiedzi na nginx <v1.2
sty
1
Myślę, że będę musiał to ulepszyć :-) I tak potrzebowałem wymówki
sty,
1
service nginx reloadnie pokazuje nic, czy konfiguracja została załadowana poprawnie, czy nie, więc jest to bezużyteczne, jeśli podejrzewasz, że konfiguracja może być niepoprawna. service nginx restartzatrzyma serwer, jeśli konfiguracja zawiera błąd!
Dan Dascalescu
80

Od wersji Nginx 1.8.0 poprawnym rozwiązaniem jest

sudo nginx -t && sudo service nginx reload

Zauważ, że z powodu błędu configtestzawsze zwraca zerowy kod zakończenia, nawet jeśli plik konfiguracyjny zawiera błąd.

Dan Dascalescu
źródło
3
nginx -t && sudo nginx -s reload
MechanisM
5
@MechanisM: nginx -tbez sudo prawie na pewno zakończy się niepowodzeniem z powodu błędów uprawnień.
Dan Dascalescu
Chciałem pokazać głównie ostatnią część do przeładowania. W moim przypadku mam niestandardowy skompilowany nginx i nie mam nawet żadnych skryptów w /etc/init.d itd., Więc w moim przypadku "service nginx reload" nic nie da
MechanisM
39

Używam następującego polecenia, aby ponownie załadować Nginx (wersja 1.5.9) tylko wtedy, gdy test konfiguracji zakończył się pomyślnie:

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

Jeśli musisz to robić często, możesz użyć aliasu. Używam następujących:

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

Sztuczka polega na tym, że „&&” wykonuje drugie polecenie tylko wtedy, gdy pierwsze się powiedzie. Możesz zobaczyć tutaj bardziej szczegółowe wyjaśnienie użycia operatora „&&”.

Możesz użyć opcji „restart” zamiast „reload”, jeśli naprawdę chcesz zrestartować serwer.

Mauricio Sánchez
źródło
Uważaj na nginx 1.4.2, który znalazłem pkill -1 nginx(skutecznie to, co robi moje przeładowanie init.d / nginx) NIE ładuje się ponownie, jeśli konfiguracja się nie powiedzie i zwróci błąd. Sprawdź swoje własne wersje.
KCD
2
To nie działa na mnie. Oba polecenia są wykonywane, nawet jeśli test się nie powiedzie.
Mario Campa
2
configtest zawsze zwraca zerowy kod zakończenia , przynajmniej w nginx 1.8.0. Użyj nginx -tzamiast tego.
Dan Dascalescu
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'

a następnie użyj poleceń „nginx.reload” itp.

Mechanizm
źródło
6

Możesz przeładować używając /etc/init.d/nginx reloadisudo service nginx reload

Jeśli nginx -tzgłosi jakiś błąd, nie załaduje się ponownie

więc użyj &&, aby uruchomić oba w tym samym czasie

lubić

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

gokul kandasamy
źródło
Nauczę cię czegoś o bash. && nie run both at a same timeuruchamia polecenia po prawej stronie JEŻELI polecenie po lewej zwraca kod zakończenia równy 0. Jeśli nginx -tzgłosi błąd, kod zakończenia nie będzie równy 0, więc drugie polecenie nie zostanie uruchomione. Tak nginx -s reloadczy inaczej
miknik
@miknik Myślę, że to właśnie chciał powiedzieć, po prostu nie wyszło dobrze. Mówi If nginx -t throws some error then it won't reload. Instrukcja run both at a same timemoże być również zinterpretowana jako pojedyncze polecenie lub jeden wiersz. W tym przypadku niekoniecznie interpretuję go, mówiąc in parallel.
Matt
2

Możesz użyć sygnałów do sterowania nginx.

Zgodnie z dokumentacją, musisz wysłać sygnał HUP do głównego procesu nginx.

HUP - zmiana konfiguracji, nadążanie za zmienioną strefą czasową (tylko dla FreeBSD i Linux), uruchamianie nowych procesów roboczych z nową konfiguracją, łagodne zamykanie starych procesów roboczych

Sprawdź dokumentację tutaj: http://nginx.org/en/docs/control.html

Możesz wysłać sygnał HUP do PID procesu głównego nginx w następujący sposób:

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

Powyższe polecenie odczytuje PID nginx z /var/run/nginx.pid. Domyślnie pid nginx jest zapisywany, /usr/local/nginx/logs/nginx.pidale można to zmienić w config. Sprawdź, nginx.configgdzie zapisuje PID.

hcristea
źródło
1

Przynajmniej na Debianie skrypt startowy nginx ma funkcję przeładowania, która wykonuje:

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 $?
  ;;

Wygląda na to, że wszystko, co musisz zrobić, to zadzwonić, service nginx reloada nie restartskoro dzwoni test_nginx_config.

Daenney
źródło
service nginx reloadnie da żadnego wskazania, czy konfiguracja została przetestowana poprawnie, czy nie, lub czy została ponownie załadowana, czy nie.
Dan Dascalescu
Co test_nginx_configwtedy robi w takim przypadku?
Daenney
1
Myślę, że oboje macie rację. service nginx reloadjest wystarczające w wierszu poleceń, jednak czasami możesz chcieć przechwycić wyjście stderr i zwrócić je z powrotem do skryptu w celu rozwiązania problemu. nginx -tpowie ci, który plik ma nieprawidłowy parametr iw której linii.
anastymous