Модуль stream_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 и по одному соединению на второй и третий серверы.

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

upstream_probe (PRO)#

Added in version 1.4.0: PRO

Синтаксис:

upstream_probe имя [port=число] [interval=время] [test=условие] [essential] [fails=число] [passes=число] [max_response=размер] [mode=always|idle|onfail] [udp] [send=строка];

Умолчание:

Контекст:

server

Задает активную проверку работоспособности серверов апстрима, указанного в директиве proxy_pass в том же контексте server, где находится директива upstream_probe.

Сервер проходит проверку, если запрос к нему успешно выполняется с учетом всех параметров самой директивы upstream_probe и всех параметров, влияющих на использование апстримов тем контекстом server, где она задана, в том числе директивы proxy_next_upstream.

Чтобы использовать проверки, в апстриме необходима зона разделяемой памяти (zone). Для одного апстрима можно определить несколько проверок.

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

имя

Обязательное имя проверки.

port

Альтернативный порт для запроса.

interval

Интервал между проверками.
По умолчанию — 5s.

test

Проверяемое при запросе условие; задается строкой из переменных. Если результат подстановки всех переменных — "" или "0", проверка не пройдена.

essential

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

fails

Число последовательных неуспешных запросов, при котором проверка считает сервер неработающим.
По умолчанию — 1.

passes

Число последовательных успешных запросов, при котором проверка считает сервер работающим.
По умолчанию — 1.

max_response

Максимальный объем памяти для ответа. Если задано нулевое значение, ожидание ответа отключается.
По умолчанию — 256k.

mode

Режим проверки в зависимости от работоспособности серверов:

  • always — серверы проверяются независимо от состояния;

  • idle — проверяются неработающие серверы, а также серверы, где с последнего клиентского запроса прошло время interval.

  • onfail — проверяются серверы только в неработающем состоянии.

По умолчанию — always.

udp

Если параметр указан, используется протокол UDP. По умолчанию для проверок используется TCP.

send

Отправляемые для проверки данные; это может быть строка с префиксом data: или имя файла с данными (задается абсолютно или относительно каталога /usr/local/angie/).

Пример:

upstream backend {
    zone backend 1m;

    server a.example.com;
    server b.example.com;
}

map $upstream_probe_response $good {
    ~200    "1";
    default  "";
}

server {
    listen ...;

    # ...
    proxy_pass backend;
    upstream_probe_timeout 1s;

    upstream_probe backend_probe
        port=12345
        interval=5s
        test=$good
        essential
        fails=3
        passes=3
        max_response=512k
        mode=onfail
        "send=data:GET / HTTP/1.0\n\n";
}

Детали работы:

  • Изначально сервер не получает клиентские запросы, пока не пройдет все заданные для него проверки с параметром essential. Если таких проверок нет, сервер считается работающим.

  • Сервер считается неработающим и не получает клиентские запросы, если какая-либо заданная для него проверка достигает своего порога fails или сам сервер достигает порога max_fails.

  • Чтобы неработающий сервер снова мог считаться работающим, все заданные для него проверки должны достичь своего порога passes; после этого учитывается порог max_fails.

upstream_probe_timeout (PRO)#

Added in version 1.4.0: PRO

Синтаксис:

upstream_probe_timeout время;

Умолчание:

upstream_probe_timeout 50s;

Контекст:

server

Задает максимальное время бездействия установленного с сервером соединения для проверок, настроенных с помощью директивы upstream_probe (PRO); при превышении этого предела соединение будет закрыто.

server#

Синтаксис:

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

Умолчание:

Контекст:

upstream

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

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

weight=число

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

max_conns=число

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

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

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

Примечание

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

max_fails=1

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

max_fails=0

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

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

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

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

backup

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

down

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

Осторожно

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

Added in version 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;

Added in version 1.4.0.

slow_start=время

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

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

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

Примечание

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

state (PRO)#

Added in version 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

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

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;

Умолчание:

Контекст:

upstream

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

В режиме connect учитывается среднее время установки соединения; в режиме first_byte — среднее время получения первого байта ответа; в режиме last_byte — среднее время получения полного ответа.

Подсчет средних значений управляется директивой response_time_factor (PRO). Текущие значения представлены как 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.

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

Модуль 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_probe_response (PRO)#

содержимое ответа, полученного в ходе активной проверки upstream_probe (PRO)

$upstream_session_time#

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