← Cloudflare Workers / workers / runtime-apis / bindings
Rate Limiting
API Rate Limiting позволяет задавать лимиты запросов и писать код вокруг них в вашем Worker.
С его помощью можно применять:
- Ограничения частоты запросов, которые применяются после запуска Worker, только когда выполнение доходит до определённого участка кода
- Разные лимиты частоты запросов для разных типов клиентов или пользователей (например, бесплатные и платные)
- Лимиты для конкретного ресурса или пути (например, лимит на маршрут API)
- Любая комбинация из перечисленного выше
API Rate Limiting работает на той же инфраструктуре, что обслуживает правила ограничения частоты запросов.
Начало работы
Сначала добавьте привязка в ваш Worker, который дает ему доступ к Rate Limiting API:
{
"main": "src/index.js",
"ratelimits": [
{
"name": "MY_RATE_LIMITER",
// An identifier you define, that is unique to your Cloudflare account.
// Must be an integer.
"namespace_id": "1001",
// Limit: the number of tokens allowed within a given period in a single
// Cloudflare location
// Period: the duration of the period, in seconds. Must be either 10 or 60
"simple": {
"limit": 100,
"period": 60
}
}
]
}main = "src/index.js"
[[ratelimits]]
name = "MY_RATE_LIMITER"
namespace_id = "1001"
[ratelimits.simple]
limit = 100
period = 60Эта привязка (binding) делает MY_RATE_LIMITER привязка, которая предоставляет limit() метод:
export default {
async fetch(request, env) {
const { pathname } = new URL(request.url)
const { success } = await env.MY_RATE_LIMITER.limit({ key: pathname }) // key can be any string of your choosing
if (!success) {
return new Response(`429 Failure – rate limit exceeded for ${pathname}`, { status: 429 })
}
return new Response(`Success!`)
}
}interface Env {
MY_RATE_LIMITER: RateLimit;
}
export default {
async fetch(request, env): Promise<Response> {
const { pathname } = new URL(request.url)
const { success } = await env.MY_RATE_LIMITER.limit({ key: pathname }) // key can be any string of your choosing
if (!success) {
return new Response(`429 Failure – rate limit exceeded for ${pathname}`, { status: 429 })
}
return new Response(`Success!`)
}
} satisfies ExportedHandler<Env>; limit() API принимает один аргумент: объект конфигурации с key поле.
- Указанный вами ключ может быть любым
stringзначение. - Распространенный подход заключается в том, чтобы формировать ключ, объединяя строку, однозначно идентифицирующую инициатора запроса (например, ID пользователя или ID клиента), со строкой, идентифицирующей конкретный ресурс (например, определенный маршрут API).
Для одного Worker можно определить и настроить несколько конфигураций ограничения скорости, что позволяет задавать разные лимиты по входящим запросам и (или) пользовательским параметрам для защиты приложения или вышестоящих API.
Например, вот как можно задать две конфигурации ограничения частоты запросов для пользователей бесплатного и платного тарифов:
{
"main": "src/index.js",
"ratelimits": [
// Free user rate limiting
{
"name": "FREE_USER_RATE_LIMITER",
"namespace_id": "1001",
"simple": {
"limit": 100,
"period": 60
}
},
// Paid user rate limiting
{
"name": "PAID_USER_RATE_LIMITER",
"namespace_id": "1002",
"simple": {
"limit": 1000,
"period": 60
}
}
]
}main = "src/index.js"
[[ratelimits]]
name = "FREE_USER_RATE_LIMITER"
namespace_id = "1001"
[ratelimits.simple]
limit = 100
period = 60
[[ratelimits]]
name = "PAID_USER_RATE_LIMITER"
namespace_id = "1002"
[ratelimits.simple]
limit = 1_000
period = 60Конфигурация
У привязки Rate Limiting есть следующие настройки:
| Параметр | Тип | Описание |
|---|---|---|
namespace_id |
string |
Строка с положительным целым числом, которое уникально определяет это пространство имён rate limiting в вашем аккаунте Cloudflare (например, "1001"). Хотя значение должно быть допустимым целым числом, оно задаётся в виде строки. Это сделано намеренно. |
simple |
object |
Конфигурация ограничения скорости. simple это единственный поддерживаемый тип. |
simple.limit |
number |
Количество разрешённых запросов (или вызовов limit()) в пределах указанного period. |
simple.period |
number |
Длительность окна ограничения частоты запросов в секундах. Должна быть равна 10 или 60. |
Например, чтобы установить ограничение в 1500 запросов в минуту, конфигурация ограничения частоты запросов будет выглядеть так:
{
"ratelimits": [
{
"name": "MY_RATE_LIMITER",
"namespace_id": "1001",
// 1500 requests - calls to limit() increment this
"simple": {
"limit": 1500,
"period": 60
}
}
]
}[[ratelimits]]
name = "MY_RATE_LIMITER"
namespace_id = "1001"
[ratelimits.simple]
limit = 1_500
period = 60Рекомендации
key передаётся в limit функция, которая определяет, по какому признаку ограничивать частоту запросов, должна отражать уникальную характеристику пользователя или класса пользователей, для которых вы хотите применить ограничение.
- Хорошим выбором являются, например, API-ключи в
Authorizationзаголовки HTTP, пути или маршруты URL, отдельные параметры запроса, используемые вашим приложением, и/или идентификаторы пользователей и арендаторов. Все это стабильные идентификаторы, которые вряд ли изменятся от запроса к запросу. - Не рекомендуется использовать IP-адреса или геолокацию (регионы или страны), поскольку эти данные могут быть общими для многих пользователей в целом ряде допустимых случаев. Ограничивая частоту запросов по таким ключам, вы рискуете непреднамеренно ограничить более широкую группу пользователей, чем предполагали.
// Recommended: use a key that represents a specific user or class of user
const url = new URL(req.url)
const userId = url.searchParams.get("userId") || ""
const { success } = await env.MY_RATE_LIMITER.limit({ key: userId })
// Not recommended: many users may share a single IP, especially on mobile networks
// or when using privacy-enabling proxies
const ipAddress = req.headers.get("cf-connecting-ip") || ""
const { success } = await env.MY_RATE_LIMITER.limit({ key: ipAddress })Локальность
Ограничения частоты запросов, которые вы задаёте и применяете в Worker, действуют только в пределах Местоположение Cloudflare ↗ в котором выполняется ваш Worker.
Например, если запрос к Worker, показанному выше, поступает из Сиднея (Австралия), то после 100 запросов за 60-секундное окно любые дальнейшие запросы к определённому пути будут отклонены с кодом состояния HTTP 429. Но это будет действовать только для запросов, обрабатываемых в Сиднее. Для каждого уникального ключа, передаваемого в привязку ограничения частоты запросов, действует отдельный лимит для каждой локации Cloudflare.
Производительность
API Rate Limiting в Workers спроектирован так, чтобы работать быстро.
Базовые счётчики кэшируются на той же машине, где выполняется ваш Worker, и обновляются асинхронно в фоновом режиме через взаимодействие с хранилищем данных, расположенным в том же дата-центре Cloudflare.
Это означает, что, хотя в коде вы await вызов limit() метод:
const { success } = await env.MY_RATE_LIMITER.limit({ key: customerId })Вы не ожидаете сетевой запрос. Rate Limiting API можно использовать, не добавляя ощутимой задержки в работу Worker.
Точность
Из этого также следует, что Rate Limiting API является нестрогим, согласуется в конечном счёте и намеренно не предназначен для точного учёта.
Например, если в одну локацию Cloudflare поступает много запросов к вашему Worker, и все они ограничиваются по одному ключу, изолят который обрабатывает каждый запрос, будет сверяться с локально кешированным значением лимита запросов. Очень быстро, но не мгновенно, эти запросы начнут учитываться в лимите запросов в рамках этого дата-центра Cloudflare.
Мониторинг
Привязки Rate Limiting пока не отображаются на панели управления Cloudflare. Чтобы отслеживать в Worker запросы с ограничением частоты:
- Workers Observability : используйте Workers Logs и Трассировки чтобы отслеживать ответы HTTP 429, которые Worker возвращает при превышении ограничений частоты запросов.
- Workers Analytics Engine : добавьте привязку Analytics Engine к своему Worker и отправляйте пользовательские точки данных (например,
rate_limitedсобытие) когдаlimit()возвращает{ success: false }. Это позволяет создавать дашборды и отслеживать метрики ограничения скорости запросов в динамике.
Примеры
@elithrar/workers-hono-rate-limit↗ : промежуточный слой (middleware), который позволяет легко добавлять ограничения частоты запросов к маршрутам в вашем Hono ↗ приложение.@hono-rate-limiter/cloudflare↗ : промежуточный слой (middleware), который позволяет легко добавлять ограничения частоты запросов к маршрутам в вашем Hono ↗ приложение с несколькими хранилищами данных на выбор.hono-cf-rate-limit↗ : промежуточный слой (middleware) для приложений на Hono, который ограничивает частоту запросов (rate limiting) в Cloudflare Workers, используя встроенные возможности Wrangler.