Здесь — почему остановленная копия не испортила ни одного ответа, а больная портила каждый второй.
Копия не приняла подключение — nginx считает попытку неудачной и отправляет тот же запрос следующей копии. Клиент получает ответ 8081 и об отказе не узнаёт: отказ остаётся строкой в error.log. Какие ответы считать неудачей, задаёт директива proxy_next_upstream. По умолчанию это error timeout: копия не подключилась, оборвала соединение или не ответила вовремя.
Неудачи nginx ещё и считает. Набрала копия max_fails неудач за fail_timeout — nginx выключает её на fail_timeout, потом пробует снова одним запросом. Так работает пассивная проверка здоровья: отдельных проверочных запросов нет, nginx судит копию по ответам на настоящие.
| Директива | По умолчанию | Что задаёт |
|---|---|---|
max_fails |
1 | сколько неудач выключают копию |
fail_timeout |
10s | за какое время считать неудачи и на сколько выключать |
proxy_next_upstream |
error timeout |
какие неудачи отправляют запрос следующей копии |
max_fails и fail_timeout пишут в строке копии: server 127.0.0.1:8082 max_fails=2 fail_timeout=20s;. proxy_next_upstream ставят в location.
Ответ 500 в этот список не входит: для nginx это обычный ответ приложения, и он уходит клиенту. Чтобы 500 тоже считался неудачей, его добавляют: proxy_next_upstream error timeout http_500;. Тогда nginx повторит запрос на другой копии, а больную выключит на fail_timeout.
Опрашивать копии самому nginx не умеет — это активная проверка, она есть у haproxy. Но и она проверяет только то, что спрашивает: копия 8082 на /healthz отвечает 200.
В upstream строка server 127.0.0.1:8082 max_fails=3 fail_timeout=30s;, копия 8082 остановлена, 8081 работает. Сколько строк Connection refused оставят в error.log шесть запросов подряд?
-
Клиент получит
200, но каждая неудачная попытка подключения к 8082 пишет строку в error.log. -
В опыте
max_failsбыл 1. Теперь копию выключают три неудачи: 8082 получит второй, четвёртый и шестой запросы. -
К 8082 уходит каждый второй запрос, остальные отвечает 8081 без ошибок. Попыток подключиться к 8082 — три.
По кругу 8082 получает второй, четвёртый и шестой запросы; каждый отказ — строка в error.log и повтор на 8081. Третья неудача выключает копию на 30 с, а клиент все шесть раз получает 200.
Главное в шаге
-
Неудача — то, что перечислено в
proxy_next_upstream: с ней nginx повторяет запрос на другой копии. -
max_failsнеудач заfail_timeoutвыключают копию наfail_timeout— поэтому шесть запросов оставили одну строку отказа. -
Ответ
500по умолчанию уходит клиенту; повтор и выключение для него включаетhttp_500.