Я поддерживаю сайт, сервисы которого располагаются на 4 серверах. Сервер 1 - балансировщик запросов на основе nginx. Сервер 2 и Сервер 3 - ноды с установленными nginx+php-fpm для обработки веб-запросов. Сервер 4 - база данных Mysql.
Однажды была высокая нагрузка на сайт. Сервер 2 и 3 перестали отвечать, т.к. такое количество запросов php-fpm не мог обработать. В конфиге nginx-балансировщика стали появляться сообщения:
В браузере появлялась ошибка 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;
}
После этого, балансировщик стал корректно обрабатывать ошибки.