Модуль ngx_stream_upstream_module

Пример конфигурации
Директивы
     upstream
     server
     zone
     state
     hash
     least_conn
     least_time
     health_check
     health_check_timeout
     match
Встроенные переменные

Модуль ngx_stream_upstream_module (1.9.0) позволяет описывать группы серверов, которые могут использоваться в директиве proxy_pass.

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

upstream backend {
    hash $remote_addr consistent;

    server backend1.example.com:12345  weight=5;
    server backend2.example.com:12345;
    server unix:/tmp/backend3;

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

server {
    listen 12346;
    proxy_pass backend;
}

Динамически настраиваемая группа, доступна как часть коммерческой подписки:

resolver 10.0.0.1;

upstream dynamic {
    zone upstream_dynamic 64k;

    server backend1.example.com:12345 weight=5;
    server backend2.example.com:12345 fail_timeout=5s slow_start=30s;
    server 192.0.2.1:12345            max_fails=3;
    server backend3.example.com:12345 resolve;
    server backend4.example.com       service=http resolve;

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

server {
    listen 12346;
    proxy_pass dynamic;
    health_check;
}

Директивы

Синтаксис: upstream название { ... }
Умолчание:
Контекст: stream

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

Пример:

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

    server backup1.example.com:12345  backup;
}

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

Синтаксис: server адрес [параметры];
Умолчание:
Контекст: upstream

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

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

weight=число
задаёт вес сервера, по умолчанию 1.
max_conns=число
ограничивает максимальное число одновременных соединений к проксируемому серверу (1.11.5). Значение по умолчанию равно 0 и означает, что ограничения нет. Если группа не находится в зоне разделяемой памяти, то ограничение работает отдельно для каждого рабочего процесса.
До версии 1.11.5 этот параметр был доступен как часть коммерческой подписки.
max_fails=число
задаёт число неудачных попыток работы с сервером, которые должны произойти в течение времени, заданного параметром fail_timeout, чтобы сервер считался недоступным на период времени, также заданный параметром fail_timeout. По умолчанию число попыток устанавливается равным 1. Нулевое значение отключает учёт попыток. В данном случае неудачной попыткой считается ошибка или таймаут при установке соединения с сервером.
fail_timeout=время
задаёт
  • время, в течение которого должно произойти заданное число неудачных попыток работы с сервером для того, чтобы сервер считался недоступным;
  • и время, в течение которого сервер будет считаться недоступным.
По умолчанию параметр равен 10 секундам.
backup
помечает сервер как запасной сервер. На него будут передаваться соединения в случае, если не работают основные серверы.
down
помечает сервер как постоянно недоступный.

Кроме того, следующие параметры доступны как часть коммерческой подписки:

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

Для работы этого параметра директива resolver должна быть задана в блоке stream. Пример:

stream {
    resolver 10.0.0.1;

    upstream u {
        zone ...;
        ...
        server example.com:12345 resolve;
    }
}

service=имя
включает преобразование SRV-записей DNS и задаёт имя сервиса (1.9.13). Для работы параметра необходимо указать параметр resolve для сервера и не указывать порт сервера.

Если имя сервиса не содержит точку (“.”), то имя составляется в соответствии с RFC и в префикс службы добавляется протокол TCP. Например, для получения SRV-записи _http._tcp.backend.example.com необходимо указать директиву:

server backend.example.com service=http resolve;

Если имя сервиса содержит одну и более точек, то имя составляется при помощи соединения префикса службы и имени сервера. Например, для получения SRV-записей _http._tcp.backend.example.com и server1.backend.example.com необходимо указать директивы:

server backend.example.com service=_http._tcp resolve;
server example.com service=server1.backend resolve;

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

slow_start=время
задаёт время, в течение которого вес сервера восстановится от нуля до своего номинального значения в ситуации, когда неработоспособный (unhealthy) сервер вновь становится работоспособным (healthy) или когда сервер становится доступным по прошествии времени, в течение которого он считался недоступным. Значение по умолчанию равно нулю и означает, что медленный старт выключен.
Параметр нельзя использовать совместно с методом балансировки нагрузки hash.

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

Синтаксис: zone имя [размер];
Умолчание:
Контекст: upstream

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

Дополнительно, как часть коммерческой подписки, в таких группах для изменения состава группы или настроек отдельных серверов нет необходимости перезапускать nginx. Конфигурация доступна через специальный location, в котором указана директива upstream_conf.

Синтаксис: state файл;
Умолчание:
Контекст: upstream

Эта директива появилась в версии 1.9.7.

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

Примеры:

state /var/lib/nginx/state/servers.conf; # путь для Linux
state /var/db/nginx/state/servers.conf;  # путь для FreeBSD

В данный момент состояние ограничено списком серверов с их параметрами. Файл читается при парсинге конфигурации и обновляется каждый раз при изменении конфигурации группы. Изменение содержимого файла напрямую не рекомендуется. Директиву нельзя использовать совместно с директивой server.

Изменения, совершённые в момент перезагрузки конфигурации или обновления бинарного файла, могут быть потеряны.

Эта директива доступна как часть коммерческой подписки.

Синтаксис: hash ключ [consistent];
Умолчание:
Контекст: upstream

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

hash $remote_addr;

Следует отметить, что любое добавление или удаление серверов в группе может привести к перераспределению большинства ключей на другие серверы. Метод совместим с библиотекой Perl Cache::Memcached.

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

Синтаксис: least_conn;
Умолчание:
Контекст: upstream

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

Синтаксис: least_time connect | first_byte | last_byte [inflight];
Умолчание:
Контекст: upstream

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

Если указан параметр connect, то учитывается время соединения с сервером группы. Если указан параметр first_byte, то учитывается время получения первого байта данных. Если указан параметр last_byte, то учитывается время получения ответа. Если указан параметр inflight (1.11.6), то также учитываются незавершённые соединения.

До версии 1.11.6 незавершённые соединения учитывались по умолчанию.

Эта директива доступна как часть коммерческой подписки.

Синтаксис: health_check [параметры];
Умолчание:
Контекст: server

Активирует периодические проверки работоспособности серверов в группе.

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

interval=время
задаёт интервал между двумя последовательными проверками, по умолчанию 5 секунд.
jitter=время
задаёт время, в пределах которого случайным образом задерживается каждая проверка, по умолчанию задержки нет.
fails=число
задаёт число последовательных неуспешных проверок для определённого сервера, после которых сервер будет считаться неработоспособным, по умолчанию 1.
passes=число
задаёт число последовательных успешных проверок для определённого сервера, после которых сервер будет считаться работоспособным, по умолчанию 1.
mandatory
устанавливает исходное состояние “checking” для сервера до завершения первой проверки работоспособности (1.11.7). Если параметр не указан, то исходно сервер будет считаться работоспособным.
match=имя
указывает на блок match с условиями, которым должно удовлетворять соединение, чтобы результат проверки считался успешным. По умолчанию для TCP проверяется лишь возможность установки TCP-соединения с сервером, для UDP проверяется отсутствие сообщения ICMP “Destination Unreachable” в ответ на отправленную строку “nginx health check”.
До версии 1.11.7 по умолчанию для UDP требовалось наличие блока match с параметрами send и expect.
port=число
задаёт порт, используемый при подключении к серверу для проверки его работоспособности (1.9.7). По умолчанию совпадает с портом сервера.
udp
указывает, что для проверки работоспособности будет использоваться протокол UDP вместо протокола TCP, используемого по умолчанию (1.9.13).

В примере

server {
    proxy_pass backend;
    health_check;
}

для каждого сервера группы backend с интервалом в 5 секунд проверяется возможность установки TCP-соединения. Если соединение с сервером не может быть установлено, проверка считается неуспешной и сервер признаётся неработоспособным. На неработоспособные серверы и серверы в состоянии “checking” клиентские соединения передаваться не будут.

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

Группа должна находиться в зоне разделяемой памяти.

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

Эта директива доступна как часть коммерческой подписки.

Синтаксис: health_check_timeout время;
Умолчание:
health_check_timeout 5s;
Контекст: stream, server

Переопределяет значение proxy_timeout для проверок работоспособности.

Эта директива доступна как часть коммерческой подписки.

Синтаксис: match имя { ... }
Умолчание:
Контекст: stream

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

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

send строка;
отправляет строку на сервер;
expect стока | ~ regex;
текстовая строка (1.9.12) или регулярное выражение, которым должны соответствовать данные, полученные с сервера. Регулярное выражение задаётся либо с модификатором “~*” (для поиска совпадения без учёта регистра символов), либо с модификатором “~” (с учётом регистра).

Параметры send и expect могут содержать строки в шестнадцатеричном виде с префиксом “\x” и последующими двумя шестнадцатеричными цифрами, например “\x80” (1.9.12).

Проверка работоспособности считается успешной, если

Пример:

upstream backend {
    zone     upstream_backend 10m;
    server   127.0.0.1:12345;
}

match http {
    send     "GET / HTTP/1.0\r\nHost: localhost\r\n\r\n";
    expect ~ "200 OK";
}

server {
    listen       12346;
    proxy_pass   backend;
    health_check match=http;
}

Проверяются лишь первые байты данных proxy_buffer_size, полученные от сервера.

Эта директива доступна как часть коммерческой подписки.

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

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

$upstream_addr
хранит IP-адрес и порт или путь к UNIX-сокету сервера группы (1.11.4). Если при проксировании были сделаны обращения к нескольким серверам, то их адреса разделяются запятой, например “192.168.1.1:12345, 192.168.1.2:12345, unix:/tmp/sock”.
$upstream_bytes_sent
число байт, переданных на сервер группы (1.11.4). Значения нескольких соединений разделяются запятыми подобно адресам в переменной $upstream_addr.
$upstream_bytes_received
число байт, полученных от сервера группы (1.11.4). Значения нескольких соединений разделяются запятыми подобно адресам в переменной $upstream_addr.
$upstream_connect_time
время установки соединения с сервером группы (1.11.4); время хранится в секундах с точностью до миллисекунд. Времена нескольких соединений разделяются запятыми подобно адресам в переменной $upstream_addr.
$upstream_first_byte_time
время получения первого байта данных (1.11.4); время хранится в секундах с точностью до миллисекунд. Времена нескольких соединений разделяются запятыми подобно адресам в переменной $upstream_addr.
$upstream_session_time
длительность сессии в секундах с точностью до миллисекунд (1.11.4). Времена нескольких соединений разделяются запятыми подобно адресам в переменной $upstream_addr.