Назад | Перейти на главную страницу

Взвешенная маршрутизация через несколько бэкэндов HAProxy

У меня есть два независимых приложения A и B. Каждое приложение использует сине-зеленые развертывания через сине-зеленые балансировщики нагрузки AWS, зарегистрированные в бэкэнде HAProxy с использованием взвешенной маршрутизации.

У меня есть требование направить трафик через обе приложения (серверные части) на основе веса, например, маршрутизация 90% трафика на серверную часть A и оставшиеся 10% на серверную часть B.

Можно ли настроить интерфейс в HAproxy, который распределяет трафик между несколькими бэкэндами указанным выше способом?

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

Другой вариант - настроить внутренний DNS для бэкэнда A и бэкэнда B, а затем бэкэнд по умолчанию может выполнять маршрутизацию между ними, но в идеале я бы избегал выхода из HAProxy только для возврата.

Для выборочной маршрутизации идентичных запросов к разным «бэкэндам» (как определено HAProxy - группами серверов) вам понадобится некоторый критерий, который вы можете вычислить в интерфейсе для каждого запроса, а затем use_backend когда это правда (или ложь, в зависимости от обстоятельств).

Например, rand() принести возвращает случайное целое число (не случайное в криптографическом смысле, но достаточно случайное для этой цели), а mod() конвертер возвращает результат деления по модулю, поэтому, если мы хотим, чтобы запросы примерно 1:10 перешли на бэкэнд bbb а остальное перейти на бэкэнд aaa тогда мы могли бы сделать что-то вроде этого:

frontend main
    mode http
    ...
    use_backend bbb if { rand(),mod(10) -m int 0 }
    default_backend aaa

Конвертеры вроде mod() им предшествуют их ввод, поэтому вывод rand() это первый ввод mod() и выход mod() сравнивается как целое число -m int против 0. Если случайное целое число без остатка делится на 10, тогда выражение истинно и бэкэнд bbb используется.

Вы можете улучшить это, убедившись, что bbb имеет хотя бы один работоспособный сервер, прежде чем принять решение об отправке ему запросов, используя nbsrv() принести чтобы гарантировать, что количество исправных серверов в bbb больше 0.

use_backend bbb if { rand(),mod(10) -m int 0 } { nbsrv(bbb) gt 0 }

Обратите внимание, что парсер конфигурации требует, чтобы каждый { и } иметь пробелы до и после, за исключением конца строки.