Upstream#

Предоставляет контекст для описания группы серверов, которые могут использоваться в директиве proxy_pass.

Пример конфигурации#

upstream backend {
    hash $remote_addr consistent;
    zone backend 1m;

    server backend1.example.com:1935  weight=5;
    server unix:/tmp/backend3;
    server backend3.example.com       service=_example._tcp resolve;

    server backup1.example.com:1935   backup;
    server backup2.example.com:1935   backup;
}

resolver 127.0.0.53 status_zone=resolver;

server {
    listen 1936;
    proxy_pass backend;
}

Директивы#

upstream#

Синтаксис

upstream имя { ... }

По умолчанию

Контекст

stream

Описывает группу серверов. Серверы могут слушать на разных портах. Кроме того, можно одновременно использовать серверы, слушающие на TCP- и UNIX-сокетах.

Пример:

upstream backend {
    server backend1.example.com:1935 weight=5;
    server 127.0.0.1:1935            max_fails=3 fail_timeout=30s;
    server unix:/tmp/backend2;
    server backend3.example.com:1935 resolve;

    server backup1.example.com:1935  backup;
}

По умолчанию соединения распределяются по серверам циклически (в режиме round-robin) с учетом весов серверов. В вышеприведенном примере каждые 7 соединений будут распределены так: 5 соединений на backend1.example.com:1935 и по одному соединению на второй и третий серверы.

Если при попытке работы с сервером происходит ошибка, то соединение передается следующему серверу, и так далее до тех пор, пока не будут опробованы все работающие серверы. Если связь с серверами не удалась, соединение будет закрыто.

server#

Синтаксис

server адрес [параметры];

По умолчанию

Контекст

upstream

Задает адрес и другие параметры сервера. Адрес может быть указан в виде доменного имени или IP-адреса, и обязательного порта, или в виде пути UNIX-сокета, который указывается после префикса unix:. Доменное имя, которому соответствует несколько IP-адресов, задает сразу несколько серверов.

Могут быть заданы следующие параметры:

weight=число

задает вес сервера
по умолчанию 1.

max_conns=число

ограничивает максимальное число одновременных активных соединений к проксируемому серверу.
Значение по умолчанию равно 0 и означает, что ограничения нет. Если группа не находится в зоне разделяемой памяти, то ограничение работает отдельно для каждого рабочего процесса.

max_fails=число — задает число неудачных попыток связи с сервером, которые должны произойти в течение заданного fail_timeout времени для того, чтобы сервер считался недоступным; после этого он будет повторно проверен через то же самое время.

В данном случае неудачной попыткой считается ошибка или таймаут при установке соединения с сервером.

Примечание

Если директива server в группе разрешается в несколько серверов, ее настройка max_fails применяется к каждому серверу отдельно.

Если после разрешения всех директив server в апстриме остается только один сервер, настройка max_fails не действует и будет проигнорирована.

max_fails=1

число попыток по умолчанию

max_fails=0

отключает учет попыток

fail_timeout=время — задает:

fail_timeout=время — задает период времени, в течение которого должно произойти определенное число неудачных попыток связи с сервером (max_fails), чтобы сервер считался недоступным. Затем сервер остается недоступным в течение того же самого времени, прежде чем будет проверен повторно.

Значение по умолчанию — 10 секунд.

Примечание

Если директива server в группе разрешается в несколько серверов, ее настройка fail_timeout применяется к каждому серверу отдельно.

Если после разрешения всех директив server в апстриме остается только один сервер, настройка fail_timeout не действует и будет проигнорирована.

backup

помечает сервер как запасной. На него будут передаваться запросы в случае, если не работают основные серверы.

down

помечает сервер как постоянно недоступный.

drain

помечает сервер как разгружаемый (draining); это значит, что он получает только запросы сессий, привязанных ранее через sticky. В остальном поведение такое же, как в режиме down.

Осторожно

Параметр backup нельзя использовать совместно с методами балансировки нагрузки hash и random.

Параметры down и drain взаимно исключающие.

Добавлено в версии 1.3.0.

resolve

Позволяет отслеживать изменения списка IP-адресов, соответствующего доменному имени, и обновлять его без перезагрузки конфигурации. При этом группа должна находиться в зоне разделяемой памяти; также должен быть определен преобразователь имен в адреса.

service=имя

Включает преобразование SRV-записей DNS и задает имя сервиса. При указании этого параметра необходимо также задать параметр resolve, не указывая порт сервера при имени хоста.

Если в имени службы нет точек, формируется имя по стандарту RFC: к имени службы добавляется префикс _, затем через точку добавляется _tcp. Так, имя службы http даст в результате _http._tcp.

Angie разрешает SRV-записи, объединяя нормализованное имя службы и имя хоста и получая список серверов для полученной комбинации через DNS, вместе с их приоритетами и весами.

  • SRV-записи с наивысшим приоритетом (те, которые имеют минимальное значение приоритета) разрешаются как основные серверы, а прочие записи становятся запасными серверами. Если backup установлено с server, SRV-записи с наивысшим приоритетом разрешаются как запасные серверы, а прочие записи игнорируются.

  • Вес аналогичен параметру weight директивы server. Если вес задан как в самой директиве, так и в SRV-записи, используется вес, установленный в директиве.

В этом примере выполняется поиск записи _http._tcp.backend.example.com:

server backend.example.com service=http resolve;

Добавлено в версии 1.4.0.

slow_start=время

задает время восстановления веса сервера, возвращающегося к работе при балансировке нагрузки методом round-robin или least_conn.

Если параметр задан и сервер после сбоя снова считается работающим с точки зрения max_fails и upstream_probe (PRO), то такой сервер равномерно набирает указанный для него вес в течение заданного времени.

Если параметр не задан, то в аналогичной ситуации сервер сразу начинает работу с указанным для него весом.

Примечание

Если в апстриме задан только один server, slow_start не работает и будет игнорироваться.

state (PRO)#

Добавлено в версии 1.4.0: PRO

Синтаксис

state файл;

По умолчанию

Контекст

upstream

Указывает файл, где постоянно хранится список серверов апстрима. При установке из наших пакетов для хранения таких файлов специально создается каталог /var/lib/angie/state/ (/var/db/angie/state/ во FreeBSD) с соответствующими правами доступа, и в конфигурации остается добавить лишь имя файла:

upstream backend {

    zone backend 1m;
    state /var/lib/angie/state/<ИМЯ ФАЙЛА>;
}

Список серверов здесь имеет формат, аналогичный s_server. Содержимое файла изменяется при любом изменении серверов в разделе /config/stream/upstreams/ через API конфигурации. Файл считывается при запуске Angie или перезагрузке конфигурации.

Осторожно

Чтобы использовать директиву state в блоке upstream, в нем не должно быть директив server, но нужна зона разделяемой памяти (zone).

zone#

Синтаксис

zone имя [размер];

По умолчанию

Контекст

upstream

Задает имя и размер зоны разделяемой памяти, в которой хранятся конфигурация группы и ее рабочее состояние, разделяемые между рабочими процессами. В одной и той же зоне могут быть сразу несколько групп. В этом случае достаточно указать размер только один раз.

feedback (PRO)#

Добавлено в версии 1.7.0: PRO

Синтаксис

feedback переменная [inverse] [factor=число] [account=условная_переменная];

По умолчанию

Контекст

upstream

Задает в upstream механизм балансировки нагрузки по обратной связи. Он динамически корректирует решения при балансировке, умножая вес каждого проксируемого сервера на среднее значение обратной связи, которое меняется с течением времени в зависимости от значения переменной и подчиняется необязательному условию.

Могут быть заданы следующие параметры:

переменная

Переменная, из которой берется значение обратной связи. Она должна представлять собой метрику производительности или состояния; предполагается, что ее передает сервер.

Значение оценивается при каждом ответе от сервера и учитывается в скользящем среднем согласно настройкам inverse и factor.

inverse

Если параметр задан, значение обратной связи интерпретируется наоборот: более низкие значения указывают на лучшую производительность.

factor

Коэффициент, по которому значение обратной связи учитывается при расчете среднего. Допустимы целые числа от 0 до 99. По умолчанию — 90.

Среднее рассчитывается по формуле экспоненциального сглаживания.

Чем больше коэффициент, тем меньше новые значения влияют на среднее; если указать 90, то будет взято 90 % от предыдущего значения и лишь 10 % от нового.

account

Указывает условную переменную, которая контролирует, как соединения учитываются при расчете. Среднее значение обновляется с учетом значения обратной связи, только если условная переменная не равна "" или "0".

Примечание

По умолчанию трафик от активных проверок не включается в расчет; комбинация переменной $upstream_probe с account позволяет включить и их или даже исключить все остальное.

Пример:

upstream backend {

    zone backend 1m;

    feedback $feedback_value factor=80 account=$condition_value;

    server backend1.example.com:1935  weight=1;
    server backend2.example.com:1935  weight=2;
}

map $protocol $feedback_value {
    "TCP"                      100;
    "UDP"                      75;
    default                    10;
}

map $upstream_probe $condition_value {
    "high_priority" "1";
    "low_priority"  "0";
    default         "1";
}

Эта конфигурация категоризирует серверы по уровням обратной связи на основе протоколов, используемых в отдельных сессиях, а также добавляет условие на $upstream_probe, чтобы учитывать только активную проверку high_priority или обычные клиентские сессии.

hash#

Синтаксис

hash ключ [consistent];

По умолчанию

Контекст

upstream

Задает метод балансировки нагрузки для группы, при котором соответствие клиента серверу определяется при помощи хэшированного значения ключа. В качестве ключа может использоваться текст, переменные и их комбинации. Пример использования:

hash $remote_addr;

Метод совместим с библиотекой Perl Cache::Memcached.

Если задан параметр consistent, то вместо вышеописанного метода будет использоваться метод консистентного хэширования ketama. Метод гарантирует, что при добавлении сервера в группу или его удалении на другие серверы будет перераспределено минимальное число ключей. Применение метода для кэширующих серверов обеспечивает больший процент попаданий в кэш. Метод совместим с библиотекой Perl Cache::Memcached::Fast при значении параметра ketama_points равным 160.

least_conn#

Синтаксис

least_conn;

По умолчанию

Контекст

upstream

Задает для группы метод балансировки нагрузки, при котором соединение передается серверу с наименьшим числом активных соединений, с учетом весов серверов. Если подходит сразу несколько серверов, они выбираются циклически (в режиме round-robin) с учетом их весов.

least_time (PRO)#

Синтаксис

least_time connect | first_byte | last_byte [factor=number] [account=condition_variable];

По умолчанию

Контекст

upstream

Задает для группы метод балансировки нагрузки, при котором вероятность передачи соединения активному серверу обратно пропорциональна среднему времени его ответа; чем оно меньше, тем больше соединений будет получать сервер.

connect

Директива учитывает среднее время установки соединения.

first_byte

Директива использует среднее время получения первого байта ответа.

last_byte

Директива использует среднее время получения полного ответа.

Добавлено в версии 1.7.0: PRO

factor

Выполняет ту же функцию, что и response_time_factor (PRO), и переопределяет его, если параметр задан.

account

Указывает условную переменную, которая контролирует, какие соединения учитываются при расчете. Среднее значение обновляется, только если условная переменная соединения не равна "" или "0".

Примечание

По умолчанию активные проверки не включаются в расчет; комбинация переменной $upstream_probe с account позволяет включить их или даже исключить все остальное.

Текущие значения представлены как connect_time, first_byte_time и last_byte_time в объекте health сервера среди метрик апстрима в API.

random#

Синтаксис

random [two];

По умолчанию

Контекст

upstream

Задает для группы метод балансировки нагрузки, при котором соединение передается случайно выбранному серверу, с учетом весов серверов.

Если указан необязательный параметр two, Angie случайным образом выбирает два сервера, из которых выбирает сервер, используя указанный метод. Методом по умолчанию является least_conn, при котором соединение передается на сервер с наименьшим количеством активных соединений.

response_time_factor (PRO)#

Синтаксис

response_time_factor число;

По умолчанию

response_time_factor 90;

Контекст

upstream

Задает для метода балансировки нагрузки least_time (PRO) коэффициент сглаживания предыдущего значения при вычислении среднего времени ответа по формуле экспоненциально взвешенного скользящего среднего.

Чем больше указанное число, тем меньше новые значения влияют на среднее; если указать 90, то будет взято 90 % от предыдущего значения и лишь 10 % от нового. Допустимые значения — от 0 до 99 включительно.

Текущие результаты вычислений представлены как connect_time (время установления соединения), first_byte_time (время получения первого байта ответа) и last_byte_time (время получения ответа целиком) в объекте health сервера среди метрик апстрима в API.

Примечание

При подсчете учитываются только успешные ответы; что считать неуспешным ответом, определяют директивы proxy_next_upstream.

sticky#

Добавлено в версии 1.6.0: Angie

Добавлено в версии 1.6.0: Angie PRO

Синтаксис

sticky route $variable...;

sticky learn zone=zone create=$create_var1... lookup=$lookup_var1... [connect] [timeout=time];

По умолчанию

Контекст

upstream

Настраивает привязку клиентских сессий к проксируемым серверам в режиме, заданном первым параметром; для разгрузки серверов, у которых задана директива sticky, можно использовать опцию drain в блоке server.

Внимание

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

Этот режим использует предопределенные идентификаторы маршрутов, которые могут быть встроены в свойства соединения, доступные Angie. Он менее гибок, так как зависит от предопределенных значений, но лучше подходит, если такие идентификаторы уже используются.

Здесь при установлении соединения проксируемый сервер может назначить клиенту маршрут и вернуть его идентификатор способом, известным им обоим. В качестве идентификатора маршрута должно использоваться значение параметра sid директивы server. Учтите, что параметр дополнительно хэшируется, если задана директива sticky_secret.

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

В параметрах директивы указываются переменные для маршрутизации. Чтобы выбрать сервер, куда направляется входящее соединение, используется первая непустая переменная; она затем сравнивается с параметром sid директивы server. Если выбрать сервер не удается или выбранный сервер не может принять соединение, то будет выбран другой сервер согласно настроенному методу балансировки.

Здесь Angie ищет идентификатор маршрута в переменной $route, получающей значение на основе $ssl_preread_server_name (обратите внимание, что нужно включить ssl_preread):

stream {

    map $ssl_preread_server_name $route {

        a.example.com            a;
        b.example.com            b;
        default                  "";
    }

    upstream backend {

        server 127.0.0.1:8081 sid=a;
        server 127.0.0.1:8082 sid=b;

        sticky route $route;
    }

    server {

        listen 127.0.0.1:8080;

        ssl_preread on;

        proxy_pass backend;
    }
}

sticky_strict#

Добавлено в версии 1.6.0: Angie

Добавлено в версии 1.6.0: Angie PRO

Синтаксис

sticky_strict on | off;

По умолчанию

sticky_strict off;

Контекст

upstream

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

sticky_secret#

Добавлено в версии 1.6.0: Angie

Добавлено в версии 1.6.0: Angie PRO

Синтаксис

sticky_secret строка;

По умолчанию

Контекст

upstream

Добавляет строку как соль в функцию MD5-хэширования для директивы sticky в режиме route. Строка может содержать переменные, например $remote_addr:

upstream backend {
    server 127.0.0.1:8081 sid=a;
    server 127.0.0.1:8082 sid=b;

    sticky route $route;
    sticky_secret my_secret.$remote_addr;
}

Соль добавляется после хэшируемого значения; чтобы независимо проверить механизм хэширования:

$ echo -n "<VALUE><SALT>" | md5sum

Встроенные переменные#

Модуль stream_upstream поддерживает следующие встроенные переменные:

$upstream_addr#

хранит IP-адрес и порт или путь к UNIX-сокету сервера группы. Если при проксировании были сделаны обращения к нескольким серверам, то их адреса разделяются запятой, например:

192.168.1.1:1935, 192.168.1.2:1935, unix:/tmp/sock"

Если сервер не может быть выбран, то переменная хранит имя группы серверов.

$upstream_bytes_received#

число байт, полученных от сервера группы. Значения нескольких соединений разделяются запятыми и двоеточиями подобно адресам в переменной $upstream_addr.

$upstream_bytes_sent#

число байт, переданных на сервер группы. Значения нескольких соединений разделяются запятыми и двоеточиями подобно адресам в переменной $upstream_addr.

$upstream_connect_time#

хранит время, затраченное на установление соединения с сервером группы; время хранится в секундах с точностью до миллисекунд. Времена нескольких соединений разделяются запятыми и двоеточиями подобно адресам в переменной $upstream_addr.

$upstream_first_byte_time#

время получения первого байта данных; время хранится в секундах с точностью до миллисекунд. Времена нескольких соединений разделяются запятыми подобно адресам в переменной $upstream_addr.

$upstream_session_time#

длительность сессии в секундах с точностью до миллисекунд. Времена нескольких соединений разделяются запятыми подобно адресам в переменной $upstream_addr.

$upstream_sticky_status#

Статус соединений с привязкой.

""

Соединение направлено в группу серверов, где привязка не используется.

NEW

Соединение не содержит информации о привязке к серверу.

HIT

Соединение с привязкой направлено на желаемый сервер.

MISS

Соединение с привязкой направлено на сервер, выбранный по алгоритму балансировки.

Статусы из нескольких соединений разделяются запятыми и двоеточиями аналогично адресам в переменной $upstream_addr.