Когда к edge приходит больше запросов, чем он обслужит, лучше сразу отказать в лишних, чем держать их в очереди, пока не замедлится все. Защита от перегрузки делает именно это и настраивается для каждого edge из central, поэтому менять ее можно без передеплоя. Нужен зарегистрированный edge и оператор с правом edges:manage; с edges:read настройки видны, но не меняются.
Что она защищает
Два ограничителя, у каждого свой режим и свои настройки:
| Ограничитель | Где | Что ограничивает |
|---|---|---|
| Inbound admission | edge | Запросы в обработке на edge. Выше лимита запрос получает 503 и заголовок Retry-After. |
| Outbound calls | каждый сервис, на каждого peer | Вызовы edge к auth и к вашим backend’ам ресурсов: вызовы в обработке, ограниченное ожидание, таймаут запроса, circuit breaker и бюджет повторов. Отказ — 503, слишком долгий вызов — 504. |
central исходящий ограничитель никогда не ограничивает, поэтому сервис может дождаться своей конфигурации при старте, а до конца старта ничего не применяется.
Три режима
| Режим | Что происходит |
|---|---|
off | Ничего не считается, не изучается и не отклоняется. |
shadow | Edge считает, что отклонил бы enforce, и ничего не отклоняет. Это значение по умолчанию: после обновления ничего не меняется, пока вы не выберете другое. |
enforce | Edge отклоняет все, что выше лимита. |
Приоритеты
Inbound admission не равняет все запросы. Запрос принимается, пока число запросов в обработке ниже доли лимита его уровня, поэтому верх лимита остается свободным для более важной работы:
- Новый вход (самый дорогой, работа еще не начата): отклоняется первым. Может занять start share лимита, по умолчанию 0,65.
- Уже начатая работа (обмен кода, выход): отклоняется следующей. Может занять continuation share, по умолчанию 0,85.
- Проксируемые вызовы к вашему API: отклоняются последними. Могут занять весь лимит.
- Health и метрики, синхронизация конфигурации и back-channel logout: не считаются и не отклоняются никогда.
Что значат числа
Лимит не придуман человеком. Edge выучивает его по времени вызовов и по тому, насколько поздно его собственный executor запускает таймер: лимит сжимается, когда вызовы замедляются или executor «залипает», и растет обратно, пока вызовы быстрые, между нижним и верхним пределом. Он выучивается, пока режим inbound не off; в shadow лимит выучивается, но ничего не отклоняется. Starting limit — лишь точка старта (она зажимается в пределы).
Каждое поле необязательно. Пустое поле не отправляется, и edge берет значение своего деплоя: переменную окружения HTTP_ADMISSION_* или HTTP_CLIENT_GUARD_*, если edge ее задает, иначе встроенное значение по умолчанию. Заданное поле не «прибивает» остальные.
Inbound
| Поле | По умолчанию | База из окружения | Смысл |
|---|---|---|---|
mode | shadow | HTTP_ADMISSION_MODE | off, shadow или enforce. |
maxInFlight (Starting limit) | 256 | HTTP_ADMISSION_MAX_IN_FLIGHT | С чего начинается выученный лимит, от 1 до 100000. |
continuationShare | 0,85 | HTTP_ADMISSION_CONTINUATION_SHARE | Доля лимита для уже начатой работы, от 0,01 до 1. |
startShare | 0,65 | HTTP_ADMISSION_START_SHARE | Доля лимита для нового входа, от 0,01 до 1, не больше continuationShare. |
retryAfterSeconds | 1 | HTTP_ADMISSION_RETRY_AFTER | Retry-After в отказе, от 1 до 60 с. |
adaptive.minLimit | 16 | нет | Выученный лимит не опускается ниже, от 1 до 100000. |
adaptive.maxLimit | 1024 | нет | Выученный лимит не поднимается выше, от 1 до 100000, не меньше minLimit. |
adaptive.tolerance | 1,5 | нет | Насколько медленнее обычного может стать вызов, прежде чем лимит начнет сжиматься, от 1 до 5. |
adaptive.smoothing | 0,2 | нет | Какая доля новой оценки заменяет лимит, от 0,01 до 1. |
adaptive.lagTargetMillis | 50 | нет | Насколько поздно executor может запустить таймер, чтобы это еще не считалось остановкой, от 5 до 10000 мс. |
Starting limit ниже minLimit или выше maxLimit стартует с ближайшей границы.
Outbound
| Поле | По умолчанию | База из окружения | Смысл |
|---|---|---|---|
mode | shadow | HTTP_CLIENT_GUARD_MODE | off, shadow или enforce. |
maxConcurrent | размер пула соединений (128) | HTTP_CLIENT_GUARD_MAX_CONCURRENT | Вызовы в обработке к одному peer, от 1 до 100000. |
maxQueue | 256 | HTTP_CLIENT_GUARD_MAX_QUEUE | Сколько вызовов могут ждать место; еще один отклоняется сразу, от 1 до 100000. |
queueTimeoutMillis | 1000 | HTTP_CLIENT_GUARD_QUEUE_TIMEOUT | Сколько вызов максимум ждет место, от 1 до 600000 мс. |
requestTimeoutMillis | 10000 | HTTP_CLIENT_GUARD_REQUEST_TIMEOUT | Сколько вызов может идти до заголовков ответа, от 1 до 600000 мс. |
breaker.enabled | выключен | нет | Circuit breaker выключен, пока не включен. |
breaker.failureRatio | 0,5 | нет | Доля неудачных вызовов (ошибка транспорта, таймаут, 502, 503, 504), открывающая цепь, от 0,01 до 1. |
breaker.minCalls | 20 | нет | Сколько вызовов должно быть в окне, прежде чем доля учитывается, от 1 до 10000. |
breaker.windowSeconds | 10 | нет | Период, за который считается доля, от 1 до 300 с. |
breaker.openSeconds | 5 | нет | Сколько цепь отказывает сразу, прежде чем пробовать, от 1 до 600 с. |
breaker.probeCalls | 3 | нет | Сколько вызовов пропускается для проверки полуоткрытой цепи, от 1 до 100. |
retryBudget.ratio | 0,1 | нет | Сколько повторов разрешено на сделанный вызов, от 0 до 1. |
retryBudget.minPerSecond | 5 | нет | Сколько повторов в секунду разрешено всегда, от 0 до 1000. |
Очередь и таймауты действуют только в enforce.
Настройка в консоли
Откройте Edges, откройте нужный edge и нажмите Edit на карточке Overload protection. Редактор открывается в боковой панели: раздел inbound и раздел outbound, в каждом короткая подсказка по настройке, режим на выбор из Deployment default, Off, Shadow и Enforce, а у остальных полей под ними написано значение по умолчанию (и его переменная окружения). Редко меняемые tolerance, smoothing и lag target лежат под Advanced.


Редактор проверяет диапазоны по ходу ввода теми же сообщениями, что и central, и не отправляет политику, которая их нарушает. Save overload protection отправляет только заполненные поля. Reset to deployment defaults после подтверждения удаляет политику, и edge возвращается к значениям своего деплоя.
Изменение доходит до edge при следующей синхронизации конфигурации, в пределах интервала обновления (по умолчанию 5 минут). Пока central недоступен, edge держит последнюю полученную политику. Политику, не прошедшую проверку, central отклоняет, а edge не применяет.
Настройка через API
PATCH /configuration/edges/policies?edgeId=<id> с секцией overload заменяет политику целиком; "overload": null удаляет ее, а остальные секции edge (accessLog, rateLimits) остаются как есть. Секция — схема OverloadPolicy в OpenAPI-файле central. Поля, которых нет в схеме, игнорируются. expectedRevisions и dryRun описаны на странице Лимиты запросов.
{
"overload": {
"inbound": {
"mode": "enforce",
"adaptive": { "maxLimit": 1536 }
},
"outbound": { "mode": "shadow" }
}
}
Значение вне диапазона дает 400 без тела; первая найденная проблема — в журнале central.
Как включать
- Оставьте
shadow, значение по умолчанию, минимум на сутки реального трафика с пиком. - Смотрите
http_admission_refused_total{mode="shadow"}. Около нуля при свободных ресурсах — лимит не мешает. Много shadow-отказов на пике —enforceотсек бы этот трафик: сначала поднимитеadaptive.maxLimitили добавьте мощности. - Переведите inbound
modeвenforceна одном edge. Понаблюдайте за отказами, пропускной способностью и задержкой весь пик, затем включайте остальные. - Outbound включайте на шаг позже тем же способом, а circuit breaker — последним.
Что видит клиент в enforce: 503 и Retry-After: <retryAfterSeconds>. Клиент должен подождать не меньше этого времени, добавить jitter и повторить ограниченное число раз; повтор без паузы только усиливает перегрузку.
Метрики
| Метрика | Что показывает |
|---|---|
http_admission_refused_total{tier,mode} | Отказы по уровням; в shadow — что отклонил бы enforce. |
http_admission_in_flight, http_admission_in_flight_peak | Запросы в обработке сейчас и наибольшее значение с прошлого замера. |
http_admission_limit | Действующий выученный лимит. |
http_admission_adaptive_limit_ratio | Выученный лимит к maxLimit; около 1 — запас есть, низкое — edge зажат. |
http_admission_rtt_seconds{tier} | Среднее время вызова за последнее окно по уровням. |
http_executor_lag_seconds | Худшее опоздание таймера на 10 мс за последнюю секунду. |
http_client_guard_rejected_total{mode} | Исходящие отказы; в shadow — что отклонил бы enforce. |
http_client_guard_in_flight, _waiting, _breaker_state | Исходящие вызовы в обработке, в ожидании и состояние цепи. |
Подстройка
| Симптом | Что менять |
|---|---|
Отказы в enforce, а pod простаивает | Поднимите adaptive.minLimit, а если http_admission_limit упирается в верх, — adaptive.maxLimit. |
| Задержка растет раньше, чем edge начинает отказывать | Снизьте adaptive.tolerance (ближе к 1) или adaptive.lagTargetMillis. |
| Лимит колеблется вверх и вниз | Снизьте adaptive.smoothing. |
| Новые входы отклоняются, а проксируемые вызовы проходят | Так и задумано. Поднимайте startShare, только если входы важнее проксируемых вызовов. |
| Клиенты повторяют запросы без паузы после отказа | Поднимите retryAfterSeconds. |
| Вызовы к медленному backend копятся | Снизьте outbound maxConcurrent и поставьте requestTimeoutMillis чуть выше p99 backend’а. |
| Падающий backend продолжает получать вызовы | Включите circuit breaker и подберите failureRatio и openSeconds. |
Что дальше
- Лимиты запросов — отказ вызывающему, который шлет больше своей доли, ответом
429 - Наблюдаемость — endpoint метрик и на что еще стоит настроить алерты
- Edges — экран, в который эта страница добавляет карточку
- Конфигурация edge — окружение edge