LINUX.ORG.RU
ФорумAdmin

научить nginx повторять запрос если бэкенд недоступен

 


2

4

Как с наименьшей большую научить nginx продолжать долбить бэкенд даже если тот лежит? Это я хочу чтобы на время обновления/падения бэкенда запросы не терялись.

Я так понимаю, в платной версии подобная фича есть платной версии(директива queue), но мне бы в бесплатной...

Не хотелось бы городить огород и сильно грязные хаки а-ля блокировать трафик если бэкенд лежит чтобы у nginx включались таймауты и переход к «следующему» бэкенду в upstream.

★★★★★

Ответ на: комментарий от disarmer

Пробовал, при получении ошибки он сделает retry сразу же. Тут или поднимать два бэкенда и обновлять их по очереди, или искать другое решение. Nginx так тупо не умеет.

По твоей ссылке: «i had to have some 100 - 150 [same] entries of upstream in my nginx file for reducing errors to in significant number»

По-хорошему, фронтенд должен слать запрос ещё раз, но пока он так не умеет. Можно так же сделать fallback фейковый сервер который будет «тормозить» запросы в случае если бэкенд лежит. Либо, как я уже сказал, два бэкенда. Все варианты гемор :(

true_admin ★★★★★
() автор топика

Пробовал в секции upstream вставить две записи для одного бекенда и добавить параметры max_fails и fail_timeout?

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

добавить параметры max_fails и fail_timeout?

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

Реально нужна директива queue из nginx plus за $1900/yr :(. Либо другой прокси-сервер. Либо, я всё ещё надеюсь, я плохо знаю nginx и решение где-то на поверхности.

true_admin ★★★★★
() автор топика
Ответ на: комментарий от true_admin

Попробуй oops. Его так можно было настраивать. Но нужно искать патчи, чтобы на новых системах собирался.

Shadow ★★★★★
()
Ответ на: комментарий от true_admin

max_fails, fail_timeout и backup ты конечно же в мане не заметил. К слову, по-моему ничего не мешает выставить таймаут в ноль.

svr4
()
Последнее исправление: svr4 (всего исправлений: 1)
Ответ на: комментарий от svr4

Думаю два одинаковых unix socket он будет считать одним бекендом. Можно наверное симлинки на него наделать, но это надо проверять

disarmer ★★★
()
Ответ на: комментарий от disarmer

Не, не должен. Я лет 6-7 назад спрашивал это в рассылке :). Более того, сказали что это нормальный паттерн.

true_admin ★★★★★
() автор топика
Ответ на: комментарий от i-rinat

disarmer в итоге сделал такой конфиг:

upstream testprod0 {
  server prod0:8000      max_fails=0;
  server 127.0.0.1:6666  max_fails=0 backup;
  server prod0:8000      max_fails=0 backup;
}

...

location / {
  proxy_pass http://testprod0;
  proxy_next_upstream error invalid_header http_502;
  include /etc/nginx/proxy_params;
}

Плюс налабал эдакий prober который висит localhost:6666 и ждёт пока поднимется бэкенд. Как только он поднимается то пробер возвращает ошибку 502 чтобы nginx запросил следующий бэкенд. В идеале. А на самом деле он, то ли пробует backup-сервера в произвольном порядке, то ли помечает неотвечающие бэкенды как нерабочие.. В общем, порядок опроса бэкендов не совпадает с порядком их перечисления в конфиге. Пробовал добавлять всем weight, max_fails, fail_timeout в разных комбинациях, ничего не помогает. Эх :(

true_admin ★★★★★
() автор топика
Ответ на: комментарий от true_admin

Если больше нет вариантов, попробуй поднять самый простой tcp-сервер из ncat, который будет только читать запрос и молчать и поставить proxy_timeout в 2 секунды. Тогда, если бекенд провалится, nginx пойдёт на этот сервер, прождёт 2 секунды и пойдёт дальше, снова на бекенд

disarmer ★★★
()
Ответ на: комментарий от disarmer

пойдёт дальше, снова на бекенд

По сути, я так и пытался сделать. К сожалению, nginx начинает в рандомном порядке обращаться к бэкендам после того как они один раз отвалились.

ngx_http_upstream_order - попробуй

anonymous_sama, спасибо, по описанию то что нужно. Но поддерживать свой репозиторий со своим nginx... Я попробую ещё сделать как написано на serverfault. Но, наверно, проще забить и подождать пока наш фронтенд научится повторять запросы. Либо два бэкенда и обновлять их по-очереди, но я сходу не соображу как это сделать. Баш-скриптиком? :)

true_admin ★★★★★
() автор топика
Ответ на: комментарий от true_admin

К сожалению, nginx начинает в рандомном порядке обращаться к бэкендам после того как они один раз отвалились.

Тогда с таким конфигом вполне должно работать? Если бекенд всё еще мертв, то ретрай будет постоянно попадать на псевдобекенд с таймаутом. Если же бекенд вернулся, то 50% вероятности что попадёт на него и вернёт нормальный ответ, и 50% что еще подождёт 2 секунды (не очень хорошо, но терпимо при перезапуске)

upstream testprod0 {
  server prod0:8000      max_fails=0;
  server 127.0.0.1:6666  max_fails=0 backup;
}

disarmer ★★★
()
Ответ на: комментарий от true_admin

Я так и делаю, если использовать только стабильные версии, а не mainline. То это ни так сложно как казалось на первый взгляд. У меня стоит оповещалка с http://nginx.org/packages/ubuntu/pool/nginx/n/nginx/ и с главной nginx.org, если версия новая выходит, то мне сообщение на почту приходит. Там этого модуля естественно пока нет, но функционал на самом деле нужный и возможно я этот модуль добавлю.

anonymous_sama ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.