среда, 18 сентября 2019 г.

Балансировщик нагрузки nginx не реагирует на ошибку 502 Bad gateway.

Я поддерживаю сайт, сервисы которого располагаются на 4 серверах. Сервер 1 - балансировщик запросов на основе nginx. Сервер 2 и Сервер 3 - ноды с установленными nginx+php-fpm для обработки веб-запросов. Сервер 4 - база данных Mysql.

Однажды была высокая нагрузка на сайт. Сервер 2 и 3 перестали отвечать, т.к. такое количество запросов php-fpm не мог обработать. В конфиге nginx-балансировщика стали появляться сообщения:

upstream server temporarily disabled while reading response header from upstream

В браузере появлялась ошибка 502 Bad gateway. Пришлось оптимизировать конфиг php-fpm. Для этого я поменял process manager опцию со pm=static на pm = ondemand и увеличил количество pm.max_children до максимального в соответствии с ограничениями ОЗУ. Ноды стали корректно обрабатывать запросы. Я попытался проверить работу балансировщика при выключеннии одной ноды. Выключил сервер 3 и сайт стал выдавать 502 Bad gateway. Выходит, что в случае http-ошибки 502 балансировщик не перенаправляет запрос на работающую ноду. Фрагмент конфига nginx.conf на балансировщике:

   upstream blablasite.ru {  
     least_conn;  
     server 192.168.4.18:80;  
     server 192.168.4.80:80;  
   }  
 ...  
   server {  
     listen 443 ssl;  
     server_name blablasite.ru;  
 ...  
     location / {  
       proxy_pass http://blablasite.ru;  
       proxy_redirect off;  
       proxy_max_temp_file_size 0;  
       proxy_set_header Host $host;  
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  
       proxy_set_header X-Real-IP $remote_addr;  
     }  

Почему же в случае ошибки 502 с одной ноды балансировщик не перенаправляет запрос на другую ноду? Почитав документацию я понял, что требуется введение дополнительной настройки proxy_next_upstream, которая и указывает, при каких ошибках следует перенаправлять запрос.

В итоге, добавил в конфиг эту строчку с указанием обрабатывать http-ошибки 500, 502, 503, 403. Обновленный конфиг:

   upstream blablasite.ru {  
     least_conn;  
     server 192.168.4.18:80;  
     server 192.168.4.80:80;  
   }  
 ...  
   server {  
     listen 443 ssl;  
     server_name blablasite.ru;  
 ...  
     location / {  
       proxy_pass http://blablasite.ru;  
       proxy_redirect off;  
       proxy_max_temp_file_size 0;  
       proxy_set_header Host $host;  
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  
       proxy_set_header X-Real-IP $remote_addr;  
       proxy_next_upstream error timeout http_500 http_502 http_503 http_403;  
     }   

После этого, балансировщик стал корректно обрабатывать ошибки.

Каталог блогов Blogolist