pulse-lets-go/docs/routing.md

5.0 KiB
Raw Blame History

Routing

Маршрутизация звонков состоит из двух уровней:

  1. Routing Rules — priority-based правила с regex-матчингом (first-match-wins)
  2. Balancing Mode — стратегия выбора ноды внутри правила или глобально

Routing Rules

Правила хранятся в data/routes.json и проверяются в порядке Priority (меньше = раньше). Первое совпавшее правило определяет маршрутизацию. Если правило не сработало (нода мертва / пул пуст) — переход к следующему. Если ни одно правило не совпало — глобальный PickNode().

Match Conditions (AND-логика)

Все непустые поля должны совпасть одновременно. Пустые поля — не проверяются.

Поле Тип Описание
match_caller_id regex Caller ID звонящего
match_destination regex Номер назначения
match_ingress_trunk regex ID входящего транка
match_days string Дни недели: "1-5" (пн-пт), "1,3,5" (пн,ср,пт), "6" (сб). Воскресенье = 0 или 7
match_time_start "HH:MM" Начало временного диапазона
match_time_end "HH:MM" Конец временного диапазона

Action Types

Тип Поле Описание
node action_node_id Маршрутизация на конкретную ноду. Если нода dead/stale/lethal — fallthrough к следующему правилу
pool action_pool_ids Выбор лучшей ноды из заданного списка (по текущему режиму балансировки). Пустой/нездоровый пул — fallthrough
auto Fallthrough к глобальному PickNode() с учётом режима балансировки

Пример правила

{
  "id": "rule-001",
  "name": "VIP caller to dedicated pool",
  "enabled": true,
  "priority": 10,
  "match_caller_id": "^7495",
  "match_destination": "",
  "match_ingress_trunk": "",
  "match_days": "1-5",
  "match_time_start": "09:00",
  "match_time_end": "18:00",
  "action_type": "pool",
  "action_pool_ids": ["pbx-01", "pbx-02"],
  "description": "VIP номера 7495 в бизнес-часы на выделенные ноды"
}

Balancing Modes

Режим балансировки определяет, как выбирается нода из множества healthy-нод (после отсева lethal). Применяется как в глобальном PickNode(), так и внутри pool-правил.

best

Выбирает ноду с максимальным score из кэша. O(1) — bestScore предрассчитывается при каждой метрике.

  • Всегда одна и та же нода при одинаковых метриках — максимально нагружает лучшую ноду
  • Хорошо для тестирования и сценариев где нужна предсказуемость

weighted_random (по умолчанию)

Выбирает ноду пропорционально score: чем выше score, тем выше вероятность быть выбранной. O(n) — сканирует все ноды.

Алгоритм:

  1. Отсеивает disabled, stale, lethal (score < 0)
  2. Суммирует score всех кандидатов (totalScore)
  3. pick = rand(0, totalScore), идёт по кандидатам, вычитая score
  4. Если totalScore <= 0 — равновероятный выбор
  • Распределяет нагрузку пропорционально готовности
  • Предсказуемость ниже, но утилизация выше — менее загруженные ноды получают пропорционально меньше звонков

Переключение режима

Через API:

PUT /api/route/mode
Authorization: Bearer <admin-jwt>
{"mode": "best"}

Через конфиг:

{ "balance_mode": "weighted_random" }

Допустимые значения: "best", "weighted_random". API-эндпоинт сразу применяет режим и сохраняет в config.json.

Ответ /api/route

В ответе маршрутизации появилось поле matched_rule — имя сработавшего правила (или "none" если правило не применилось):

{
  "node_id": "pbx-03",
  "score": 88,
  "sip_gateway": "sip:pbx03.lan:5060",
  "matched_rule": "VIP to dedicated"
}