Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Троттлинг — это паттерн проектирования, который контролирует, какую нагрузку система может принять в данный момент времени. В распределённых системах пики трафика, штормы повторных попыток, паттерны веерного распределения запросов и общие нижестоящие зависимости создают условия, при которых неконтролируемая нагрузка в конечном итоге исчерпывает доступную ёмкость. Когда компонент достигает емкости, механизм регулирования помогает отклонять или откладывать дополнительные запросы до тех пор, пока система не будет готова снова. В противном случае задержка может возрасти, повторные попытки могут усилить нагрузку, а сбои — распространиться по системе.
Распространенный архитектурный подход заключается в применении регулирования только в шлюзе для защиты входящего трафика. Изолированный механизм регулирования может защитить один компонент при перемещении перегрузки на другие части приложения, увеличивая задержку и ухудшая взаимодействие с пользователем.
В хорошо спроектированном дизайне применяйте шаблон по всей системе, а не только на краю. Учитывайте ситуации, в которых ваш сервис делит пропускную способность между несколькими вызывающими сторонами, предоставляет ресурсы, которые могут быть исчерпаны, или участвует в цепочке вызовов, где перегрузка одного компонента может каскадно распространиться на другие. Все эти моменты потенциально хорошие кандидаты для регулирования. Для эффективного регулирования требуется согласованный ответ между компонентами архитектуры. Вы должны рассматривать перегрузку как обычное рабочее состояние: ожидать ее, отслеживать ее и активно контролировать, как ваша система реагирует при достижении ограничений емкости.
Регулирование покупает время для реактивных ответов во время таких событий, как операции масштабирования, исследование по вызову, разбиение цепи. Статические ограничения, калиброванные в прошлом квартале, больше не могут отражать сегодняшние шаблоны трафика.
Цель этой статьи — познакомить вас с рекомендациями по эффективному ограничению скорости. Предполагается, что вы понимаете шаблон регулирования.
Начните с принципов ограничения, поскольку каждая рабочая нагрузка опирается на определенные базовые принципы. Принципы представлены на вкладках, и перед настройкой ограничений в вашем проекте следует ознакомиться со всеми ними.
После того как вы разберётесь в основных принципах, оцените, на каком этапе внедрения вы находитесь, ознакомившись с разделом Этапы внедрения. Используйте нижние уровни для создания базового варианта реализации, а затем оптимизируйте его по мере развития рабочей нагрузки.
Остальная часть руководства представляет собой справочник по практикам троттлинга, обозначенным как TP. Каждый TP — это дискретная единица управления и отображается в числовом порядке.
Типы регулирования
Каждый тип регулирования защищает другую часть архитектуры. Поместите каждую из них на границу, где она может напрямую управлять нагрузкой.
Таблица сопоставляет типы с архитектурными уровнями, используемыми в приведенных ниже методиках.
| Type | Что он контролирует | Где он живёт | Соответствующие методики |
|---|---|---|---|
| Ограничение входного трафика | Скорость и объём запросов, поступающих в вашу систему | Шлюз API, общедоступные и частные точки входа | TP-1, TP-2 |
| Внутреннее регулирование | Трафик между вашими подкомпонентами, такими как базы данных, кэши, очереди и совместно используемые службы | Межсервисные вызовы в пределах вашего контура | TP-6 |
| Ограничение исходящего трафика | Трафик, который система отправляет нижестоящим зависимостям | клиентские SDK, точки разветвления, маршруты исходящих вызовов | TP-7 |
| Ограничение с учетом состояния | Ограничения, которые настраиваются на основе работоспособности системы в режиме реального времени, стоимости операций или глубины очереди | Механизм политик ограничения, уровень контроля допуска | TP-12, TP-13, TP-14 |
Риск: ограничение пропускной способности зависит от взаимодействия между сервером и его клиентами. Чтобы быть эффективным, сервер должен применять четкие, прогнозируемые политики регулирования и постоянно обмениваться ими. Клиенты, в свою очередь, должны понимать и уважать эти ограничения, реализуя соответствующие механизмы повтора, отката и контроля скорости. Уменьшите этот риск, имея четко определенные контракты, которые вознаграждают хорошее поведение и препятствуют злоупотреблению или чрезмерному потреблению.
Для большинства рабочих нагрузок требуется совместное использование всех четырёх типов. Если вы ограничиваете только входящий трафик, то защищаете лишь вход, но проталкиваете перегрузку вглубь приложения. Внутренние и исходящие элементы управления останавливают распространение. Регулирование с учетом состояния позволяет системе изменяться по мере изменения условий вместо того, чтобы работать с устаревшими фиксированными ограничениями.
Принципы ограничения
Независимо от того, какие типы ограничения производительности применяются в вашей рабочей нагрузке, вам по-прежнему нужны те же базовые принципы. Если вы впервые сталкиваетесь с троттлингом, ознакомьтесь с этими принципами по порядку, чтобы понять, зачем нужна каждая из этих практик, прежде чем внедрять как. Если вы просматриваете существующий дизайн, используйте вопросы проектирования под каждым принципом в качестве контрольного списка, чтобы найти пробелы.
| Терминология | Description |
|---|---|
| Граница | Граница — это группа компонентов, которую защищает механизм троттлинга и которая обычно представлена точкой входа. |
| Размерность | Измерение — это пара из имени и значения из метаданных запроса, которую оценивает правило ограничения запросов. |
| Вверх по течению | Апстрим — это вызывающая сторона, которая отправляет запросы вашему сервису. |
| Вниз по течению | Downstream — это зависимость, которую вызывает ваш сервис. |
Проектируйте с учётом перегрузки как штатного режима работы
В распределённых системах перегрузка — это ожидаемое явление, а не исключение. Регулирование — это цикл управления, который защищает общие зависимости и сохраняет ваши SLO под нагрузкой. Проектируйте систему исходя из того, что всплески трафика, повторные запросы и каскадные эффекты неизбежны.
Рекомендации по проектированию
Используйте их при проверке существующей структуры или оценки того, где ваша система подвергается перегрузке риска.
- Что приводит эту систему к насыщению и влияет на SLO: запросы, уровень параллелизма, ЦП, ввод-вывод, глубина очереди или квоты нижестоящих сервисов?
- Где возникает нагрузка, разветвляется (fan-out) или распространяется каскадом?
- Для каждой точки входа каковы явные границы влияния (шлюз, сегмент, зависимость)?
- Что такое соответствующий механизм сигнализации перегрузки между компонентами?
- Когда (не если) происходит перегрузка, как система исцелится и восстановится?
Рекомендации по проектированию
- Определите границы регулирования (где происходит регулирование) и измерения регулирования (какие ограничения применяются) во время разработки и убедитесь, что они соответствуют векторам насыщенности.
- Принудительное применение ограничений на каждой точке входа, включая низкоприоритетные и доступные только для чтения API.
- Контролируйте параллелизм в точках ветвления.
- Убедитесь, что компоненты в этой системе готовы соблюдать сигналы перегрузки, относящиеся к протоколу.
- Рассматривайте ограничение пропускной способности как жизненный цикл: измеряйте → применяйте → учитесь → адаптируйтесь.
Предостережение
Ограничение скорости не заменяет защиту от DoS/DDoS. Продолжайте инвестировать в механизмы для обнаружения, устранения и блокирования вредоносного трафика, предназначенного для перегрузки системы.
Соответствующие рекомендации
Этапы внедрения
| Уровень зрелости | Лучшие практики | Преимущества |
|---|---|---|
| 1 |
TP-1: Настройка защиты — ваш путь к дополнительным возможностям. TP-2: Реализовать троттлинг фронтенда TP-3: Создать обратное давление TP-4: эффективность работы (часть 1) |
Защищайте сервис, которым вы владеете; обеспечьте оперативное реагирование |
| 2 |
TP-5: учитывайте обратное давление TP-6: внутренние элементы управления TP-7: выходная переборка |
Защитите зависимость нижнего уровня и свой сервис |
| 3 |
TP-8. Кэш не заменяет регулирование. TP-9: Держите троттлинг вне критического пути. TP-10: защита горизонтальной инфраструктуры TP-11: операционное превосходство (часть 2) |
Ваш сервис избегает неудачных архитектурных подходов; у вас есть операционная готовность и дисциплина, чтобы выдерживать сбои |
| 4 |
TP-12: регулирование с учетом состояния TP-13: Соблюдайте границы транзакций TP-14: непрерывная валидация посредством случайного раннего отбрасывания |
Ваш сервис обеспечивает детальный контроль QoS; клиент и сервис автоматически проверяют готовность ответа |
Important
В рабочих нагрузках искусственного интеллекта основной вектор насыщенности перемещается от скорости запроса к пропускной способности маркера. Емкость становится пропорциональна размеру запроса и ответа, а не количеству запросов. Вкладки Azure OpenAI в этом разделе применяют указанные выше принципы с этой точки зрения.
[TP-1] Настройка защиты в шлюзе
Начните управление нагрузкой на первом контролируемом вами компоненте шлюза уровня 3 (см. элемент 1 на изображении, показывающем точки ограничения в системе). Возможности шлюза и положение в пути запроса определяют, насколько сложными могут быть эти элементы управления. Даже простые проверки, такие как фильтрация исходного IP-адреса или DNS, могут защищать внутренние службы во время всплесков трафика.
Шлюзы также являются хорошим местом для грубой блокировки нагрузки во время непредвиденных пиков трафика. Блокировка на этом уровне может снизить количество внутренних систем, дестабилизируемых во время события, и помочь системе быстрее восстановиться.
Сделайте проверки шлюза простыми и недорогими. Сложные элементы управления на этом этапе замедляют все запросы. Выберите шлюзовые продукты, обеспечивающие баланс между скоростью отклика и сложностью политик. Также помните, что эти средства управления уровня 3 являются крупнозернистыми. Когда они активируются, радиус взрыва часто шире, чем ожидалось. Продолжайте использовать TP-2 для реализации более комплексных элементов управления.
[TP-2] Реализовать троттлинг в нескольких местах
Реализуйте регулирование во всех точках, где нагрузка уровня 7 входит в систему (см. элемент 2 на изображении с точками регулирования в системе), включая частные точки входа, используемые внутренними службами. Эта конструкция гарантирует, что вызывающие абоненты не могут обойти системные ограничения. Как отмечалось в TP-1, одного лишь ограничения пропускной способности шлюза обычно недостаточно.
Разработка ограничений
После определения точек входа определите ограничения, чтобы достичь следующих целей:
- Защита пользователей или рабочих нагрузок друг от друга (также известных как шумные соседи). Эти ограничения являются ограничениями пользователей.
- Защитите службу и ее инфраструктуру от всех пользователей. Эти ограничения являются ограничениями службы.
Для каждого API определите по крайней мере одно ограничение пользователя и одно ограничение службы. В идеале пользовательские ограничения должны срабатывать раньше, чем ограничения сервиса, когда отдельный клиент отправляет слишком много трафика. Однако ограничения служб могут активироваться даже в том случае, если ни одно ограничение пользователя не нарушается. Эта ситуация может произойти во время временных событий, таких как сбои зоны, при перемещении трафика и перегрузке оставшихся секций.
Ментальная модель заключается в том, что каждый запрос содержит набор измерений (регион = X, удостоверение = Y и т. д.), а политики регулирования определяют ряд входных ворот (логических И) в этих измерениях.
В следующей таблице показана пример иерархии общих измерений запросов:
| Предельный размер | Type | Protects | Comment |
|---|---|---|---|
| Идентификация рабочей нагрузки | User | Шумные или чрезмерно активные нагрузки друг от друга | Настоятельно рекомендуется |
| Идентификатор ресурса на стороне сервера | User | Единый набор рабочих нагрузок, которые нуждаются в одних и том же ресурсах, защищенных друг от друга | Обычно приводит к желательному поведению. Группы ресурсов могут работать хорошо здесь. |
| Subscription | User | Больший набор рабочих нагрузок друг от друга | Обычно приводит к желательному поведению. |
| Tenant | User | Недобросовестные пользователи вашего сервиса среди остальных пользователей | Обычно приводит к желательному поведению. |
| Имя операции | Service | API, который находится под нагрузкой из-за сбоя других API вашего сервиса | Настоятельно рекомендуется |
| Сервис/Глобальный | Service | Защитите свою инфраструктуру от перегрузки терминала | Не рекомендуется. Этот тип ограничения затрагивает очень большую область и может вызывать ненужные сбои, когда такие ограничения устаревают. Вместо этого используйте ограничения на основе имени операции . |
| Сервисный узел | Service | Защищает узел от перегрузки | Не рекомендуется. Хотя эти ограничения очень эффективны при равномерном распределении трафика, они могут создавать ощущение случайности, когда трафик на отдельных узлах неравномерен или состав узлов неоднороден. Вместо этого используйте ограничения на основе имени операции . |
Компромисс: Адресное ограничение скорости повышает справедливость и общее качество пользовательского опыта, ограничивая только тех пользователей, которые превышают согласованные условия использования, вместо ухудшения качества обслуживания для всех пользователей. Однако этот подход представляет дополнительную сложность, требуя четких определений контрактов, отслеживания использования пользователей и текущего управления и применения дифференцированных ограничений скорости для пользователей.
Архитектурные элементы, внутренние для службы (то есть не видимые пользователям, например разделы или сегменты), не подходят в качестве основы для пользовательских ограничений. Так как пользователи не могут прогнозировать или контролировать эти конструкции, они не имеют разумного способа реагирования. Кроме того, сообщения об ошибках могут выявить внутренние структурные детали и создать проблемы безопасности, поэтому будьте осторожны. Ограничения служб для этих конструкций по-прежнему могут быть ценными, но если эти ограничения превышены, сообщите условие как HTTP 503 (служба недоступна) или эквивалентно с четкой семантикой повторных попыток. Дополнительные сведения см. в разделе TP-3.
Риск: Есть риск, связанный с локальным ограничением пропускной способности, если ваша система эластична. Это означает ограничение пропускной способности, при котором трафик учитывается на каждом узле. Операции масштабирования вверх и вниз, а также органический рост приведут к нагрузке, превышающей ту, которая была предусмотрена изначально. Со временем это постепенное ухудшение может перегрузить ограниченные в ресурсах серверные компоненты в самый неожиданный момент. Если вы всё же решите использовать ограничение только на локальном уровне, убедитесь, что это сопровождается строгой операционной дисциплиной и регулярной проверкой степени использования лимитов.
Блокировка трафика
Реализуйте возможность блокировать определенные пользователи или операции API, не требуя развертывания службы или перезапуска. Сведения о конкретных требованиях см. в разделе TP-4.
Примените иерархию ограничений в приведенной выше таблице. Идентификатор рабочей нагрузки и имя операции являются минимальными рекомендуемыми измерениями.
[TP-3] Создать обратное давление
Когда ограничение пользователя или службы нарушается, условие обычно является временным. Сообщите об этом состоянии вышестоящим вызывающим сторонам, возвращая HTTP 429 (Слишком много запросов) или HTTP 503 (Служба недоступна), чтобы они могли корректно отреагировать. Используйте 429 для ограничений пользователей и 503 для ограничений службы.
Note
Используйте HTTP 429 для принудительного применения ограничений пользователей и HTTP 503 для ограничений уровня обслуживания. Включите инструкции по повторным попыткам только в том случае, если повторная попытка безопасна и предназначена.
Без этого сигнала вызывающие абоненты могут немедленно повторить попытку, увеличить трафик и вызвать более регулирование и сбои. Они могут возвращать HTTP 500 своим клиентам или перемещать долговыполняющиеся операции в DLQ. Такие последствия приводят к непредсказуемому пользовательскому опыту и увеличивают число обращений по рабочему сайту.
Сигнализация с помощью кода 429
Когда превышен лимит пользователя, сигнализируйте вызывающим сторонам верхнего уровня о необходимости снизить частоту запросов, возвращая код HTTP 429. Этот код указывает на то, что вызывающая сторона нарушила условия взаимодействия с вашим сервисом.
Как минимум, добавьте следующий заголовок с ответом 429:
| Заголовка | Тип данных | Обсуждение |
|---|---|---|
Retry-After |
Целое число; время в секундах | Вызывающая сторона должна ждать как минимум столько секунд. Хотя RFC 9110 допускает метку времени в формате HTTP-date, возвращайте длительность, а не метку времени. В терминах ISO 8601 эта длительность может рассматриваться как PTnS. Для n = 0 клиент может немедленно повторить попытку.Длительности менее секунды не поддерживаются, поскольку они не имеют широкого применения в системах того типа, которые рассматриваются в этом документе. Если у вас есть вариант использования, обратитесь к авторам. |
В дополнение к указанному выше заголовку верните следующие заголовки:
| Заголовка | Тип данных | Обсуждение |
|---|---|---|
RateLimit-Policy |
Струна | Набор политик, применяемых к этому запросу. Пример: RateLimit-Policy: "default";q=100;w=10. Этот заголовок указывает на политику ограничения скорости с именем default, которая выделяет 100 requests в течение 10 секунд. См. проект IETF о заголовках ограничения скорости для получения полной спецификации. |
RateLimit |
Струна | Оставшиеся единицы мощности и время, когда мощности, как ожидается, снова будут доступны. Пример: RateLimit: "default";r=0;t=30. Этот заголовок указывает, что для политики default осталось 0 единиц, и сервер ожидает, что дополнительные единицы станут доступны через 30 секунд. Полные спецификации см. в черновике заголовков ограничений скорости IETF . |
x-ms-ratelimit-used |
Число; Количество | Единицы измерения ёмкости, которые будут использоваться в этом вызове. Будет включен в заголовок RateLimit (WIP) |
При превышении лимита ваш механизм ограничения должен возвращать эти значения вашему приложению. Использование стандартизированных заголовков обеспечивает совместимость с клиентским промежуточным ПО, соответствующим отраслевым стандартам.
Сигнал через 503
Если превышен лимит сервиса, сообщайте об этом вышестоящим вызывающим сторонам, возвращая код HTTP 503. Этот код указывает, что служба временно ограничена, не связана с поведением получателя.
При ответе с кодом 503 можно дополнительно включить заголовки, описанные ранее, только если вы хотите, чтобы клиенты повторили попытку. Если вы навсегда отклоняете трафик и не хотите повторов, не включайте заголовки с указаниями для повторов. В отличие от 429, 503 также могут быть возвращены по причинам, отличным от нарушений ограничения службы.
Вычисление Retry-After
Чтобы создать эффективный механизм обратного давления, вычислите интервал Retry-After, который возвращается клиентам. Если решение регулирования не предоставляет предварительно компилированного значения, вычислите его следующим образом:
Retry-After = Now + Throttling Window Length(W) + Randomized Jitter
Jitter следует выбирать случайным образом в интервале (-W, +небольшое кратное W), чтобы предотвратить повторяющиеся волны запросов. Приоритет трафика, длина времени ожидания, заголовок повторных попыток (см. TP-5) и типичные продолжительности вызовов API также могут влиять на jitter. Цель состоит в том, чтобы предсказать, когда емкость, скорее всего, будет доступна для обслуживания запроса. Не возвращайте абсолютное время в Retry-After, чтобы рассинхронизация часов и различия в разборе часовых поясов не приводили к дополнительным сбоям.
Дополнительные сведения о более сложных случаях см. в TP-12, TP-13 и TP-14.
Возвращайте 429 при превышении пользовательских лимитов с Retry-After, чтобы вызывающая сторона снижала частоту запросов и разумно выполняла повторные попытки.
[TP-4] Создание операций для обработки событий загрузки
Механизмы ограничения скорости дают сбой по многим причинам. Пока программное обеспечение не достигнет более высокого уровня зрелости, DRI должны иметь возможность быстро смягчать последствия случаев троттлинга, используя цикл «наблюдение, решение, действие».
Наблюдаемость и инструментарий DRI — два столпа этой передовой практики. Успех измеряется тем, насколько быстро DRI могут действовать при минимальной зоне поражения. У вашей команды должны быть следующие возможности:
- Обратите внимание: Текущие лимиты троттлинга и степень их исчерпания.
- Определите: Выявите трафик топ‑N для каждого API в соответствии с существующими ограничениями.
- Действовать: Блокировать трафик с наименьшим побочным ущербом.
- Безопасность: DRIs действуют быстро и безопасно.
- Подготовка и обучение: Предусмотрено ли обучение для DRIs? Включает ли анализ операций управление нагрузкой в качестве основной области?
Средство DRI должно отображать текущее ограничение насыщенности и верхних N вызывающих объектов на API, чтобы вы могли действовать с минимальным радиусом взрыва.
[TP-5] Учитывайте обратное давление
Поскольку код 429 указывает на временную ситуацию, соблюдение механизма обратного давления за счёт снижения трафика к нижестоящим сервисам повышает общую стабильность. Хотя это состояние является временным, оно может длиться в течение длительного времени (т. е. несколько времени существования запроса). В результате эффективная обработка механизма обратного давления требует тщательного планирования.
Сначала решите, следует ли завершить запрос с ошибкой и позволить вышестоящему вызывающему коду повторить попытку или повторить запрос самостоятельно. Если вы решите повторить попытку самостоятельно, оцените, следует ли поместить в очередь задачу, допускающую повторную попытку (в устойчивом хранилище или в памяти). Не рекомендуется держать поток занятым на всё время выполнения повторных попыток, поскольку повторные попытки, находящиеся в процессе выполнения, могут вызвать блокировку в начале очереди, при которой повторно отправляемые запросы задерживают запросы, которые можно было бы обработать немедленно. Это также делает объявление банкротства (т. е. сброс очереди повторных попыток) труднее, так как может потребоваться перезапуск службы и задержка восстановления.
Затем выполните повторные попытки в упорядоченном режиме. Не выполняйте повторную попытку, пока не истечёт интервал, указанный в заголовке Retry. При каждой повторной попытке добавляйте к запросу заголовок retry-attempt, указывающий, сколько раз этот запрос был повторно отправлен. Поддерживайте низкое количество повторных попыток и заранее согласовывайте его с зависимыми сервисами. Серверы могут возвращать ответ 425 («Слишком рано») и повышать его до 403 («Запрещено»), если эти требования нарушаются. Если ответ 429 не содержит заголовков, указывающих, когда повторить запрос, используйте экспоненциальную задержку между повторными попытками; для ответа 429 допустимо ограниченное число повторных попыток. Но не повторяйте запрос при ошибке 503, если в ответе нет заголовков повтора.
Наконец, используйте шаблон разбиения цепи, чтобы быстро завершиться ошибкой. Не направляйте трафик в зависимый сервис, который уже сообщил о действующем ограничении запросов. Когда эта зависимость восстанавливается, не обрабатывайте сразу всю накопившуюся в очереди работу, поскольку это может вызвать резкий всплеск трафика в нижестоящих системах. Постепенно возвращайте трафик, чтобы нижестоящие системы могли постепенно нарастить нагрузку. Во время повторного введения продолжайте использовать retry-attempt заголовок, как указано выше. Если достигнуто максимальное число повторных попыток, отклоните запрос, отправив вышестоящий HTTP 503 с соответствующими заголовками и метаданными. Убедитесь, что библиотеки и пакеты SDK, используемые для вызова зависимостей, поддерживают эти механизмы.
Retry-After Соблюдайте заголовок, а не блокируйте потоки для повторных попыток и используйте средства останова канала для быстрого сбоя во время устойчивых окон регулирования.
[TP-6] Защита внутренних компонентов
Хотя регулирование точки входа обеспечивает контроль допуска, регулирование трафика между подкомпонентами, такими как базы данных, кэши и очереди, также важно (см. элемент 3 на изображении с точками регулирования в системе).
Регулирование в этом слое позволяет каждой подкомпоненте защитить себя. Считайте, что другие подкомпоненты могут быть скомпрометированы, и не делайте никаких предположений об их поведении под нагрузкой. Этот подход создает логические "ячейки" внутри системы, которые относительно изолированы друг от друга и защищены от ошибок в других компонентах. В частности, сосредоточьтесь на компонентах, совместно используемых в различных типах работы, выполняемой службой. Защита этих ячеек может значительно повысить время восстановления.
[TP-7] Реализация переборки исходящего трафика при вызове зависимостей
Исходящие блоки необходимы для ограничения максимального количества одновременных вызовов в полете (см. элемент 4 на изображении с точками регулирования в системе). Хотя каждая зависимость должна иметь собственные механизмы защиты, такие механизмы не всегда могут быть реализованы.
Трафик к зависимым службам проходит через системы 3-го и 4-го уровней (которые часто являются общими, например балансировщики нагрузки и коммутаторы), прежде чем достигнет 7-го уровня, где может применяться ограничение скорости. В результате перегрузка может произойти до начала регулирования на уровне приложения.
На малых временных масштабах запросы поступают неравномерно в пределах окна агрегирования для ограничения пропускной способности. Короткий всплеск может быть приемлемым для вашей системы, но всё равно может перегрузить нижележащую инфраструктуру (очереди переполняются, сокеты исчерпываются, а нижележащие системы теряют устойчивость).
Исходящие блоки помогают сглаживать трафик и уменьшать дисперсию между службой и зависимостями, что повышает общую стабильность. Убедитесь, что клиентский пакет SDK поддерживает исходящие блоки.
Следите за точками разветвления: местами, где одна входящая задача превращается в несколько запросов (пакетные вызовы, обработчики очередей, рабочие процессы, массовые обновления в базе данных). Здесь требуется внимание на вызов заказа, истечения срока действия и восстановления.
Исходящие переборки ограничивают одновременные вызовы во время полета к зависимостям. Применяйте их в точках ветвления, где одна задача порождает множество последующих запросов.
[TP-8] Не используйте кеширование вместо ограничения частоты запросов
Некоторые службы используют кэширование для повышения отказоустойчивости или снижения задержки, что может уменьшить постоянную нагрузку. Этот подход может показаться рабочим, но он может дать сбой, если трафик вызывающей стороны приводит к промахам кэша и вызывает незапланированную нагрузку с точки зрения доступной мощности.
Используйте кэширование, когда оно помогает, но оставляйте ограничение скорости запросов и изоляцию ресурсов в силе на случай наихудших сценариев промаха кэша. Этот подход также помогает снизить влияние атак DoS на кэш. Кроме того, учитывайте прогрев кэша после холодного старта: перезапуск партиции может создать временную нагрузку на работающие партиции. Кэши дают ощутимые преимущества, но также усложняют архитектуру.
Используйте кэш для снижения задержки и постоянной нагрузки, но устанавливайте лимиты троттлинга, которые сохраняются даже при наихудшей доле промахов кэша, а не при средней.
[TP-9] Держать учёт троттлинга вне критического пути
Независимо от используемой службы регулирования, отправляйте данные об использовании и получайте решения асинхронно. Этот подход повышает отказоустойчивость, поскольку система может продолжать работать, даже если служба ограничения скорости дает сбой. Рассмотрите возможность выделить в приложении отдельный поток для учёта ограничений и хранения решений о применении ограничений, к которым потоки обработки запросов могут быстро обращаться. Критически важные пути приложения могут отправлять данные об использовании в этот поток и синхронно проверять принимаемые решения.
Ведите учёт ограничений асинхронно, чтобы медленное или недоступное хранилище данных об ограничениях не блокировало критический путь обработки запроса.
[TP-10] Обратите внимание на сквозную инфраструктуру
Сквозные зависимости, такие как обновления зоны DNS, часто группируют трафик для ограничения скорости иначе, чем это делает ваша служба. Эти зависимости часто содержат мало бизнес-логики или вовсе её не содержат, предполагаются бесконечно масштабируемыми, а затем о них забывают. Однако даже один клиент может перегрузить эту общую инфраструктуру до критического уровня и вызвать троттлинг для многих других, не связанных с ним пользователей. В результате убедитесь, что:
- Ваша служба не должна перегружать подобную службу; примените TP-7, чтобы избежать более масштабного, чем необходимо, воздействия.
- У вас есть план на случай, если сквозная зависимость станет недоступной. Кэширование «последних корректных» ответов и использование заранее определённых режимов браунаута могут быть эффективными приёмами.
С подозрением относитесь к зависимостям, которые вообще не ограничивают интенсивность запросов. Они могут автоматически ударить ограничения и вернуть 500s всем пользователям без предупреждения.
[TP-11] Периодически повторно оценивать, настраивать и проверять
Периодически вернитесь в конфигурацию, чтобы она отражала текущие шаблоны использования в вашей системе. В идеале это следует делать в рамках еженедельной проверки рабочего сайта, используя специальную панель мониторинга, которая показывает текущие ограничения, а также использование в реальном времени и исторические данные об использовании (верхние и нижние пороговые значения). Используйте автоматизацию. Убедитесь, что проверки инцидентов включают этот анализ шаблона использования.
Методы проверки: Периодически проводите тестирование, задавая низкие ограничения в политиках ограничения скорости или используя Chaos Studio, чтобы убедиться, что корректность обработки ошибок 429 и способность DRI выполнять первичную диагностику не ухудшились. Другие тесты включают:
- Воссоздайте последние N сбоев (где N определяется владельцем службы).
- Нагрузочный тест наименее используемых API
- Проведите нагрузочное тестирование самых дорогих API
Как минимум, серьёзно рассмотрите возможность совмещения как минимум двух из этих тестов с учениями по отработке зональных отказов.
Создание сред-реплик с имитированными зависимостями и генераторами трафика на базе искусственного интеллекта позволяет проверить нефункциональные требования (производительность и отказоустойчивость) и рекомендуется как долгосрочная инвестиция.
Периодически просматривайте ограничения для текущих шаблонов использования. Статические ограничения распадаются по мере развития трафика. Проверьте с помощью контролируемого тестирования с низким ограничением.
[TP-12] Реализация регулирования с учетом состояния
Ограничение нагрузки с учётом состояния системы перераспределяет ограниченные ресурсы в соответствии с целями бизнеса. Используются следующие методы:
- Динамическое регулирование: Модуляция номинальной стоимости на основе типа операции (считывания и записи) или текущего состояния (длина очереди, память).
- Исчерпание ресурсов: Для асинхронных систем переоценивайте задачи в очереди при изменении затрат или состояния. Должна быть возможность удалить поставленную в очередь задачу («объявить банкротство»). Крайние сроки и приоритет LIFO могут помочь.
- Браунуты: Предварительно решенные режимы понижения состояния, когда метрики работоспособности превышают пороговые значения (отключают операции с низким приоритетом, возвращают более короткие результаты и т. д.).
- Кратковременное превышение и заимствование: Разрешить кратковременное потребление выше базового уровня. Заимствование ресурсов использует свободные мощности других. Оба требуют тщательного контроля справедливости.
Регулирование, которое реагирует на состояние системы в режиме реального времени, а не фиксированные ограничения, выделяет дефицитную емкость в соответствии с бизнес-приоритетами.
[TP-13] Соблюдайте границы транзакции
Для API служб с транзакционной семантикой убедитесь, что ограничение пропускной способности может отдавать приоритет транзакциям, уже находящимся в обработке, по сравнению с запуском новых. Ограничение подопераций транзакционного API может привести к срыву транзакции или её откату, что приводит к неэффективному расходованию ресурсов и ухудшает пользовательский опыт. Это поведение можно реализовать с помощью специальных идентификаторов транзакций, передаваемых с помощью вызова API, хотя в вашем случае использования могут существовать более естественные идентификаторы. Этот подход требует тщательного проектирования и изменений приложений.
Отдавайте приоритет завершению уже выполняющихся транзакционных операций, а не приему новых, чтобы не тратить впустую уже частично задействованные ресурсы.
[TP-14] Реализовать случайное раннее отбрасывание
Так как агрегирование использования приближается к высоким ограничениям использования (см. изображение, показывающее изменение использования ресурсов с нагрузкой), начинает отклонять тщательно выбранную долю трафика. Положительное значение для оставшихся маркеров в заголовке RateLimit сигнализирует вызывающим абонентам о том, что их трафик находится в этой категории и что система приближается к ограничениям. Преимущества: (1) запретить системе достичь красной зоны, и (2) убедитесь, что вышестоящий партнер остается готовым соблюдать ограничения.
Начните сбрасывать часть трафика заранее, когда совокупная нагрузка приближается к пределам, не дожидаясь достижения жёсткого предела.