Re: Проблемы с proxy connect timeout

Maxim Dounin mdounin на mdounin.ru
Пн Авг 7 14:39:44 UTC 2017


Hello!

On Mon, Aug 07, 2017 at 07:30:15AM -0400, d.sibilkov wrote:

> Всем привет, не могу понять некоторые аспекты директивы
> proxy_connect_timeout из ngx_stream_proxy_module и ngx_http_proxy_module,
> это по сути одна директива которая всегда работает по одному принципу?
> почему она входит в состав двух различных модулей?

Модули ngx_stream_proxy_module и ngx_http_proxy_module - это два 
совершенно разных модуля, и каждый имеет свои собственные 
конфигурационные директивы.  Иногда они похожи, иногда - нет.

> Опишу сложившуюся ситуацию: есть 2 сервера (соответственно 2 адреса), на
> каждом крутится несколько бэкендов, у каждого бэкенда свой порт который он
> слушает (около пяти портов на адресе). Организована балансировка без весов с
> помощью least_conn подобным образом:
>     upstream backend_service {
>         least_conn;
>         server backend-server1.vds.com:7000 max_fails=1 fail_timeout=5;
>         server backend-server1.vds.com:7001 max_fails=1 fail_timeout=5;
>         server backend-server2.vds.com:7000 max_fails=1 fail_timeout=5;
>         server backend-server2.vds.com:7001 max_fails=1 fail_timeout=5;
> 
> Бэкенды крутятся как сервисы systemd и в силу различных причин такое иногда
> бывает что один из сервисов может упасть и не подняться, или может
> потребуется его остановить. Дело в том, что в такой ситуации балансировщик
> кидает пользователя на апстрим, который в момент запроса лежит, при этом сам
> сервер на котором крутится бэкенд работает и порт для бэкенда открыт,
> соответственно proxy_connect_timeout почему-то не срабатывает, видимо его
> волнует лишь доступность сервера и открыт ли порт, а что там дальше -нет.
> Соответственно при запросе пользователь ждет 60с, которые выставлены по
> умолчанию в proxy_read_timeout, апстрим маркируется как упавший,
> отрабатывает  fail_timeout=5 и все по-новой, а наша цель перекинуть
> пользователя на рабочий бэкенд как только понятно что тот к которому он
> пытается подключиться лежит.
> Возникает вопрос - это нормальное поведение? Есть-ли способы разрешить мою
> ситуацию без сложных костылей?

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

Ну и очевидно, что если у вас бекенды падают, и детектирование 
упавшего бекенда знимает 60 секунд, уменьшать fail_timeout до 5 
секунд несколько, как бы это сказать, расточительно.  Наоборот, 
стоит поднять до каких-либо сравнимых значений.

> И да, выставить значение proxy_read_timeout поменьше я не могу - нужно
> учитывать низкое качество соединения у пользователя, и низкое значение этой
> директивы может его просто зациклить в перекидывании туда-сюда (или нет?).
> Спасибо.

Нет.  Качество соединения у пользователя не влияет на работу 
proxy_read_timeout.  Соответствующий таймаут срабатывает тогда и 
только тогда, когда nginx ждёт данных от бекенда, и за заданное 
время никакие данные не приходят.  То есть он может сработать 
когда бекенд, скажем, занят обработкой сложного запроса и ничего 
не возвращает в ответ (например, какой-нибудь phpmyadmin 
восстанавливает базу из бекапа), но не будет срабатывать, если 
клиент не успевает читать ответ и nginx вынужден ждать, чтобы 
отправить данные клиенту.

-- 
Maxim Dounin
http://nginx.org/


Подробная информация о списке рассылки nginx-ru