Модуль ngx_stream_upstream_module

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

Модуль 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
помечает сервер как запасной сервер. На него будут передаваться соединения в случае, если не работают основные серверы.
Параметр нельзя использовать совместно с методами балансировки нагрузки hash и random.
down
помечает сервер как постоянно недоступный.

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

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

Для работы этого параметра директива resolver должна быть задана в блоке stream или в соответствующем блоке upstream.

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 и random.

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

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

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

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

До версии 1.13.3 конфигурация была доступна только через специальный 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 незавершённые соединения учитывались по умолчанию.

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

Синтаксис: random [two [метод]];
Умолчание:
Контекст: upstream

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

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

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

Если указан метод least_time, то соединение передаётся серверу с наименьшими средним временем ответа и числом активных соединений. Если указан least_time=connect, то учитывается время соединения с сервером группы. Если указан least_time=first_byte, то учитывается время получения первого байта данных. Если указан least_time=last_byte, то учитывается время получения последнего байта данных.

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

Синтаксис: resolver адрес ... [valid=время] [ipv4=on|off] [ipv6=on|off] [status_zone=зона];
Умолчание:
Контекст: upstream

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

Задаёт серверы DNS, используемые для преобразования имён вышестоящих серверов в адреса, например:

resolver 127.0.0.1 [::1]:5353;

Адрес может быть указан в виде доменного имени или IP-адреса, и необязательного порта. Если порт не указан, используется порт 53. Серверы DNS опрашиваются циклически.

По умолчанию nginx будет искать как IPv4-, так и IPv6-адреса при преобразовании имён в адреса. Если поиск IPv4- или IPv6-адресов нежелателен, можно указать параметр ipv4=off (1.23.1) или ipv6=off.

По умолчанию nginx кэширует ответы, используя значение TTL из ответа. Необязательный параметр valid позволяет это переопределить:

resolver 127.0.0.1 [::1]:5353 valid=30s;

Для предотвращения DNS-спуфинга рекомендуется использовать DNS-серверы в защищённой доверенной локальной сети.

Необязательный параметр status_zone включает сбор информации о запросах и ответах сервера DNS в указанной зоне.

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

Синтаксис: resolver_timeout время;
Умолчание:
resolver_timeout 30s;
Контекст: upstream

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

Задаёт таймаут для преобразования имени в адрес, например:

resolver_timeout 5s;

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

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

Модуль 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_received
число байт, полученных от сервера группы (1.11.4). Значения нескольких соединений разделяются запятыми подобно адресам в переменной $upstream_addr.
$upstream_bytes_sent
число байт, переданных на сервер группы (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.