Страницы

Поиск по вопросам

среда, 12 июня 2019 г.

nginx возвращает 502 Bad Gateway даже если приложение уже работает

На сервере настроена связка Nginx + Erlang. А именно - nginx слушает 80-й порт и проксирует запросы на порт 8738. Erlang с помощью Cowboy, принимает запросы с порта 8738 и отдаёт статику по http или обрабатывает сообщения по WebSocket. Вот кусок конфига, который за это отвечает:
# При запросе страниц бэковой части перебрасываем на эрланг location /back { # настройки проксирования на эрланг proxy_pass http://localhost:8738/back; proxy_set_header Host $host; # без особой надобности proxy_cache_valid 502 10s; # недолго кешируем ошибку "502 Bad Gateway", если эрланг ещё не запустился # всё что ниже нужно для работы вебсокетов proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; # передаём заголовок "Upgrade: websocket", если он пришел от клиента proxy_set_header Connection $connection_upgrade; # добавляем заголовок "Connection: Upgrade", если был передан заголовок "Upgrade: websocket" }
Это была предыстория. Вообще сейчас не важно что такое Erlang, Cowboy и WebSocket. Проблема вот в чём
После перезагрузки сервера получается так, что nginx стартует раньше чем erlang. Соответственно, nginx не видит ничего на порту 8738 и возвращает 502 Bad Gateway. Да вроде бы и норм, но когда erlang запускается, ситуация остаётся неизменной. Ошибка 502 так и будет возвращаться всегда. В логах nginx вот это:
2017/06/02 12:07:33 [error] 708#708: *899 connect() failed (111: Connection refused) while connecting to upstream, client: xxx.xxx.xxx.xxx, server: foobar.com.ua, request: "GET /back HTTP/1.1", upstream: "http://[::1]:8738/back", host: "foobar.com.ua"
Hotfix: просто сделать sudo nginx -s reload и сразу всё работает! Работает сколько угодно времени до первой перезагрузки.
Как побороть это?


Ответ

Проблема скорее всего в том, что nginx при загрузке резолвит localhost в IPv6 адрес, а ваш сервер слушает на IPv4 адресе. После перезагрузки конфига nginx повторно резолвит адрес и на этот раз резолвит IPv4 адрес.
Если Cowboy слушает на всех портах, то можно в настройках systemd указать nginx что бы он стартовал только после запуска Cowboy.

Комментариев нет:

Отправить комментарий