upstream priority

Maxim Dounin mdounin на mdounin.ru
Пт Ноя 6 18:49:10 UTC 2020


Hello!

On Fri, Nov 06, 2020 at 09:40:14AM -0800, Nikita Koshikov wrote:

> Доброго всем времени суток
> 
> Подскажите как можно сделать что-то максимально подобное для выбора
> backend сервера по приоритету, в идеале нужно что-то
> 
>   upstream backend {
>     server [::1]:81 priority=1;
>     server [::1]:82 priority=2;
>     server [::1]:83 priority=3;
>     server [::1]:84 priority=4;
>     server [::1]:85 priority=5;
>   }
> т.е. пока жив хоть один с более высоким приоритетом - слать запросы на него ?
> 
> Из того что пробовал
>   upstream backend {
>     server [::1]:81 weight=1;
>     server [::1]:83 backup;
>   }
> Так работает - однако не поддерживает 2+ бекенда

Если хочется строгий порядок перебора бэкендов, то стоит 
посмотреть в сторону перенаправления по error_page.  E.g.:

    location / {
        proxy_pass http://[::1]:81;
        error_page 502 504 @second;
        recursive_error_pages on;
    }

    location @second {
        proxy_pass http://[::1]:82;
        error_page 502 504 @third;
        recursive_error_pages on;
    }

    location @third {
        proxy_pass http://[::1]:82;
    }

В зависимости от конкретных потребностей можно добавить 
proxy_intercept_errors и соответственно другие error_page по 
вкусу.

> Из самого близкого что удалось сделать - через hash со статичным ключом
>   upstream backend {
>     hash 'http_balance';
>     server [::1]:81 weight=1 fail_timeout=60;
>     server [::1]:82 weight=2 fail_timeout=60;
>     server [::1]:83 weight=3 fail_timeout=60;
>   }
> Проблема только что веса не всегда работают, - в данной конфигурации
> выбирается server:82, хотя у 83 более высокий weight. Полная цепочка
> при отказах - 82->83->81
> Учитывается ли вес в такой конфигурации ?
> С более высокими весами начинает работать как нужно 83->82->81
>   upstream backend {
>     hash 'http_balance';
>     server [::1]:81 weight=1 fail_timeout=60;
>     server [::1]:82 weight=10 fail_timeout=60;
>     server [::1]:83 weight=100 fail_timeout=60;
>   }
> Хотелось бы понимать это совпадение или веса принимаются в расчет при
> выборе hash-а?

Вес - это не приоритет, а ручка для управления долей запросов, 
которые пойдут на конкретный бэкенд.  Вес, естественно, при выборе 
бэкенда учитывается, но в том смысле, что на бэкенд с весом 10 - в 
среднем, в предположении случайных ключей - будет отправлено в 10 
раз больше запросов, чем на бэкенд с весом 1.

В случае ошибок - происходит перехэширования запроса с другим 
ключом, с добавлением к ключу количества перехэширований.  И 
соответственно для конкретного ключа - последовательность бэкендов 
будет фиксированная, но для каждого ключа при этом своя.  Но есть 
нюанс: если за 20 перехэширований nginx не найдёт бэкенд, на 
который ещё не ходил - он сдастся и переключится на round-robin 
балансировку, где живой бэкенд, если он есть, можно гарантировано 
выбрать за фиксированное количество операций.

Соответственно подобрать такой статический ключ и такое 
распределение весов, при котором для данного ключа будет нужная 
вам последовательность перебора бэкендов - в принципе можно.  Но 
это не то, как должена работать hash-балансировка, и скорее всего 
для сложных случаев вы просто устанете подбирать.  Ну и, понятно, 
поддерживать это будет непросто.

-- 
Maxim Dounin
http://mdounin.ru/


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