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#
Синтаксис |
|
По умолчанию |
— |
Контекст |
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#
Синтаксис |
|
По умолчанию |
— |
Контекст |
upstream |
Задает адрес и другие параметры сервера. Адрес может быть указан в виде доменного имени или IP-адреса, и обязательного порта, или в виде пути UNIX-сокета, который указывается после префикса unix:
. Доменное имя, которому соответствует несколько IP-адресов, задает сразу несколько серверов.
Могут быть заданы следующие параметры:
|
задает вес сервера |
|
ограничивает максимальное число одновременных активных соединений к проксируемому серверу. |
max_fails=
число — задает число неудачных попыток связи с сервером,
которые должны произойти в течение заданного fail_timeout
времени для того, чтобы сервер считался недоступным; после
этого он будет повторно проверен через то же самое время.
В данном случае неудачной попыткой считается ошибка или таймаут при установке соединения с сервером.
Примечание
Если директива server
в группе разрешается в несколько серверов,
ее настройка max_fails
применяется к каждому серверу отдельно.
Если после разрешения всех директив server
в апстриме остается только один сервер,
настройка max_fails
не действует и будет проигнорирована.
|
число попыток по умолчанию |
|
отключает учет попыток |
fail_timeout=
время — задает:
fail_timeout=
время — задает период времени, в течение которого
должно произойти определенное число неудачных попыток связи с сервером
(max_fails
), чтобы сервер считался недоступным.
Затем сервер остается недоступным в течение того же самого времени,
прежде чем будет проверен повторно.
Значение по умолчанию — 10 секунд.
Примечание
Если директива server
в группе разрешается в несколько серверов,
ее настройка fail_timeout
применяется к каждому серверу отдельно.
Если после разрешения всех директив server
в апстриме остается только один сервер,
настройка fail_timeout
не действует и будет проигнорирована.
|
помечает сервер как запасной. На него будут передаваться запросы в случае, если не работают основные серверы. |
|
помечает сервер как постоянно недоступный. |
|
помечает сервер как разгружаемый (draining); это значит,
что он получает только запросы сессий,
привязанных ранее через sticky.
В остальном поведение такое же, как в режиме |
Осторожно
Параметр backup
нельзя использовать совместно с методами
балансировки нагрузки hash и random.
Параметры down
и drain
взаимно исключающие.
|
Позволяет отслеживать изменения списка IP-адресов, соответствующего
доменному имени, и обновлять его без перезагрузки конфигурации.
При этом группа должна находиться в
зоне разделяемой памяти;
также должен быть определен
|
|
Включает преобразование SRV-записей DNS и задает имя сервиса. При указании этого параметра необходимо также задать параметр resolve, не указывая порт сервера при имени хоста. Если в имени службы нет точек, формируется имя по стандарту RFC:
к имени службы добавляется префикс Angie разрешает SRV-записи, объединяя нормализованное имя службы и имя хоста и получая список серверов для полученной комбинации через DNS, вместе с их приоритетами и весами.
|
В этом примере выполняется поиск записи _http._tcp.backend.example.com
:
server backend.example.com service=http resolve;
|
задает время восстановления веса сервера,
возвращающегося к работе
при балансировке нагрузки методом
Если параметр задан
и сервер после сбоя снова считается работающим
с точки зрения Если параметр не задан, то в аналогичной ситуации сервер сразу начинает работу с указанным для него весом. |
Примечание
Если в апстриме задан только один server
,
slow_start
не работает и будет игнорироваться.
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#
Синтаксис |
|
По умолчанию |
— |
Контекст |
upstream |
Задает имя и размер зоны разделяемой памяти, в которой хранятся конфигурация группы и ее рабочее состояние, разделяемые между рабочими процессами. В одной и той же зоне могут быть сразу несколько групп. В этом случае достаточно указать размер только один раз.
feedback#
Синтаксис |
|
По умолчанию |
— |
Контекст |
upstream |
Задает в upstream
механизм балансировки нагрузки по обратной связи.
Он динамически корректирует решения при балансировке,
умножая вес каждого проксируемого сервера на среднее значение обратной связи,
которое меняется с течением времени в зависимости от значения переменной
и подчиняется необязательному условию.
Могут быть заданы следующие параметры:
|
Переменная, из которой берется значение обратной связи. Она должна представлять собой метрику производительности или состояния; предполагается, что ее передает сервер. Значение оценивается при каждом ответе от сервера
и учитывается в скользящем среднем
согласно настройкам |
|
Если параметр задан, значение обратной связи интерпретируется наоборот: более низкие значения указывают на лучшую производительность. |
|
Коэффициент, по которому значение обратной связи учитывается
при расчете среднего.
Допустимы целые числа от 0 до 99.
По умолчанию — Среднее рассчитывается по формуле экспоненциального сглаживания. Чем больше коэффициент, тем меньше новые значения влияют на среднее;
если указать |
|
Указывает условную переменную,
которая контролирует, как соединения учитываются при расчете.
Среднее значение обновляется с учетом значения обратной связи,
только если условная переменная
не равна Примечание По умолчанию трафик от |
Пример:
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#
Синтаксис |
|
По умолчанию |
— |
Контекст |
upstream |
Задает метод балансировки нагрузки для группы, при котором соответствие клиента серверу определяется при помощи хэшированного значения ключа. В качестве ключа может использоваться текст, переменные и их комбинации. Пример использования:
hash $remote_addr;
Метод совместим с библиотекой Perl Cache::Memcached.
Если задан параметр consistent
, то вместо вышеописанного метода будет использоваться метод консистентного хэширования ketama. Метод гарантирует, что при добавлении сервера в группу или его удалении на другие серверы будет перераспределено минимальное число ключей. Применение метода для кэширующих серверов обеспечивает больший процент попаданий в кэш. Метод совместим с библиотекой Perl Cache::Memcached::Fast при значении параметра ketama_points равным 160.
least_conn#
Синтаксис |
|
По умолчанию |
— |
Контекст |
upstream |
Задает для группы метод балансировки нагрузки, при котором соединение передается серверу с наименьшим числом активных соединений, с учетом весов серверов. Если подходит сразу несколько серверов, они выбираются циклически (в режиме round-robin) с учетом их весов.
Ключевые моменты и преимущества#
Динамическая балансировка нагрузки: Непрерывно отслеживает количество активных соединений для адаптации к текущей нагрузке на каждом сервере.
Простота: Работает без необходимости дополнительных параметров или сложных настроек.
Совместимость: Совместим с другими конфигурациями проксируемых серверов, включая веса, максимальное количество сбоев и время ожидания после сбоя.
least_time#
Синтаксис |
|
По умолчанию |
— |
Контекст |
upstream |
Задает для группы метод балансировки нагрузки, при котором вероятность передачи соединения активному серверу обратно пропорциональна среднему времени его ответа; чем оно меньше, тем больше соединений будет получать сервер.
|
Директива учитывает среднее время установки соединения. |
|
Директива использует среднее время получения первого байта ответа. |
|
Директива использует среднее время получения полного ответа. |
|
Выполняет ту же функцию, что и response_time_factor, и переопределяет его, если параметр задан. |
|
Указывает условную переменную,
которая контролирует, какие соединения учитываются при расчете.
Среднее значение обновляется,
только если условная переменная соединения
не равна Примечание По умолчанию |
Текущие значения представлены как connect_time
, first_byte_time
и last_byte_time
в объекте health
сервера
среди метрик апстрима в API.
least_bandwidth#
Модуль балансировки нагрузки least_bandwidth
в потоковом модуле выбирает
проксируемый сервер, который использует наименьший объем пропускной способности,
стремясь равномерно распределить сетевой трафик, направляя новые сессии на
сервер с наименьшим потреблением пропускной способности.
Режимы работы#
Модуль поддерживает три режима:
Upstream (
upstream
): Учитывает только пропускную способность, используемую от клиента к серверу.Downstream (
downstream
): Учитывает только пропускную способность, используемую от сервера к клиенту.Both (
both
): Учитывает сумму пропускной способности, используемой вверх (от клиента к серверу) и вниз по потоку (от сервера к клиенту).
Модуль вводит новую директиву в контексте upstream
потокового модуля:
least_bandwidth [both|upstream|downstream] [factor=<значение>];
both
: Режим по умолчанию, если не указан.factor
: Необязательный коэффициент сглаживания для расчета скользящего среднего, в диапазоне от 0 до 100 (по умолчанию 90).
Как это работает#
Модуль периодически вычисляет среднее использование пропускной способности для каждого проксируемого сервера, используя формулу скользящего среднего для сглаживания колебаний со временем. Когда начинается новая сессия, он выбирает проксируемый сервер с наименьшим средним использованием пропускной способности, скорректированным с учетом веса сервера, если он указан. Если несколько серверов имеют одинаковое минимальное среднее использование пропускной способности, он применяет взвешенный метод round-robin среди них для справедливого распределения нагрузки. Этот механизм гарантирует, что сессии направляются на серверы, которые в настоящее время используют меньше пропускной способности, способствуя равномерному распределению сетевой нагрузки.
Пример конфигурации#
stream {
upstream backend {
least_bandwidth both factor=80;
server backend1.example.com:12345;
server backend2.example.com:12345;
}
server {
listen 12345;
proxy_pass backend;
}
}
В этом примере:
В директиве
least_bandwidth
настроен учет как входящей, так и исходящей пропускной способности.Коэффициент сглаживания установлен равным 80, что влияет на скорость адаптации среднего значения к изменениям в использовании пропускной способности.
Для балансировки нагрузки определены два проксируемых сервера.
Ключевые моменты и преимущества#
Динамическая балансировка нагрузки: Непрерывно отслеживает использование пропускной способности для адаптации к текущей нагрузке на каждом сервере.
Коэффициент сглаживания: Параметр
factor
контролирует отзывчивость расчета скользящего среднего; более высокий коэффициент означает более медленную адаптацию к изменениям.Режимы: Позволяет выбирать балансировку на основе входящей пропускной способности, исходящей пропускной способности или обоих, в зависимости от потребностей приложения.
Совместимость: Совместим с другими конфигурациями проксируемых серверов, включая веса, максимальное количество сбоев и время ожидания после сбоя.
least_packets#
Модуль балансировки нагрузки least_packets
в потоковом модуле выбирает
проксируемый сервер, обрабатывающий наименьшее количество трафика на основе
количества переданных пакетов, стремясь равномерно распределить сетевую
нагрузку, направляя новые сеансы на сервер с наименьшей скоростью передачи
пакетов.
Режимы работы#
Модуль поддерживает три режима:
Upstream (
upstream
): Учитывает только пакеты, отправленные от клиента к серверу.Downstream (
downstream
): Учитывает только пакеты, отправленные от сервера к клиенту.Оба (
both
): Учитывает сумму пакетов, отправленных вверх (от клиента к серверу) и вниз по потоку (от сервера к клиенту).
Модуль вводит новую директиву в контексте upstream
потокового модуля:
least_packets [both|upstream|downstream] [factor=<значение>];
both
: Режим по умолчанию, если не указан.factor
: Необязательный коэффициент сглаживания для расчета скользящего среднего, в диапазоне от 0 до 100 (по умолчанию 90).
Как это работает#
Модуль периодически обновляет среднюю скорость пакетов для каждого проксируемого сервера, используя формулу скользящего среднего для сглаживания колебаний со временем. Когда инициируется новый сеанс, он выбирает проксируемый сервер с наименьшей средней скоростью передачи пакетов, скорректированной с учетом веса сервера. Если несколько серверов имеют одно и то же минимальное значение, среди них применяется взвешенный метод round-robin. Этот процесс гарантирует, что сеансы направляются на серверы, которые в настоящее время наименее загружены с точки зрения обработки пакетов, способствуя равномерному распределению сетевой нагрузки.
Пример конфигурации#
stream {
upstream backend {
least_packets both factor=80;
server backend1.example.com:12345;
server backend2.example.com:12345;
}
server {
listen 12345;
proxy_pass backend;
}
}
В этом примере:
В директиве
least_packets
настроен учет как входящих, так и исходящих пакетов.Коэффициент сглаживания установлен равным 80, что влияет на то, как быстро среднее значение адаптируется к изменениям скорости пакетов.
Определены два проксируемых сервера для балансировки нагрузки.
Ключевые моменты и преимущества#
Динамическая балансировка нагрузки: Непрерывно отслеживает скорость пакетов для адаптации к текущей нагрузке на каждом сервере.
Коэффициент сглаживания: Параметр
factor
контролирует отзывчивость расчета скользящего среднего; более высокий коэффициент означает более медленную адаптацию к изменениям.Режимы: Позволяет выбирать балансировку на основе числа входящих пакетов, исходящих пакетов или обоих значений.
Совместимость: Совместим с другими конфигурациями проксируемых серверов, включая веса, максимальное количество сбоев и время ожидания после сбоя.
random#
Синтаксис |
|
По умолчанию |
— |
Контекст |
upstream |
Задает для группы метод балансировки нагрузки, при котором соединение передается случайно выбранному серверу, с учетом весов серверов.
Если указан необязательный параметр two
, Angie случайным образом выбирает два сервера, из которых выбирает сервер, используя указанный метод. Методом по умолчанию является least_conn, при котором соединение передается на сервер с наименьшим количеством активных соединений.
response_time_factor#
Синтаксис |
|
По умолчанию |
|
Контекст |
upstream |
Задает для метода балансировки нагрузки least_time коэффициент сглаживания предыдущего значения при вычислении среднего времени ответа по формуле экспоненциально взвешенного скользящего среднего.
Чем больше указанное число, тем меньше новые значения влияют на среднее; если
указать 90
, то будет взято 90 % от предыдущего значения и лишь 10 % от
нового. Допустимые значения — от 0 до 99 включительно.
Текущие результаты вычислений представлены как connect_time
(время
установления соединения), first_byte_time
(время получения первого
байта ответа) и last_byte_time
(время получения ответа целиком) в
объекте health
сервера среди метрик апстрима
в API.
Примечание
При подсчете учитываются только успешные ответы; что считать неуспешным
ответом, определяют директивы proxy_next_upstream
.
sticky#
Синтаксис |
|
По умолчанию |
— |
Контекст |
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;
}
}
В этом режиме для привязки клиента к конкретному проксируемому серверу используется динамически генерируемый ключ; он более гибок, так как назначает серверы на ходу, хранит сеансы в зоне общей памяти и поддерживает различные способы передачи идентификаторов сессий.
Здесь сессия создается
на основе свойств соединения, идущих от проксируемого сервера.
С параметрами create
и lookup
перечисляются переменные,
указывающие, как создаются новые
и ищутся существующие сессии.
Оба параметра можно использовать по нескольку раз.
Идентификатором сессии служит значение первой непустой переменной,
указанной с create
;
например, это может быть
имя проксируемого сервера
.
Сессии хранятся в зоне общей памяти;
ее имя и размер задаются параметром zone
.
Если к сессии не было обращений в течение времени
timeout
, она удаляется.
Значение по умолчанию — 1 час.
Последующие соединения от клиентов, желающих использовать сессию,
должны содержать ее идентификатор,
причем так, чтобы он попал в непустую переменную,
указанную с lookup
;
тогда его значение будет сопоставлено с сессиями в общей памяти.
Если выбрать сервер не удается
или выбранный сервер не может обработать соединение,
то будет выбран другой сервер
согласно настроенному методу балансировки.
Параметр connect
позволяет создать сессию
сразу после получения заголовков ответа от проксируемого сервера.
Без него сессия создается только после завершения обработки со.
В примере Angie создает и ищет сессии,
используя переменную $rdp_cookie
:
stream {
upstream backend {
server 127.0.0.1:3390 sid=a;
server 127.0.0.1:3391 sid=b;
sticky learn lookup=$rdp_cookie create=$rdp_cookie zone=sessions:1m;
}
server {
listen 127.0.0.1:3389;
ssl_preread on;
proxy_pass backend;
}
}
sticky_strict#
Синтаксис |
|
По умолчанию |
|
Контекст |
upstream |
При включении Angie будет возвращать клиенту ошибку соединения, если желаемый сервер недоступен, вместо использования любого другого доступного сервера, как это происходит, когда в группе нет доступных серверов.
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
#
Статус соединений с привязкой.
|
Соединение направлено в группу серверов, где привязка не используется. |
|
Соединение не содержит информации о привязке к серверу. |
|
Соединение с привязкой направлено на желаемый сервер. |
|
Соединение с привязкой направлено на сервер, выбранный по алгоритму балансировки. |
Статусы из нескольких соединений разделяются запятыми и двоеточиями аналогично адресам в переменной $upstream_addr.