← Cloudflare Workers / workers / runtime-apis / bindings
Rate Limiting
Rate Limiting API vám umožňuje definovat rate limity a psát kolem nich kód ve vašem Workeru.
Můžete jej použít k vynucení:
- Omezení rychlosti, která se uplatní až po spuštění Workeru, konkrétně jakmile je dosaženo určité části vašeho kódu
- Různé limity četnosti požadavků pro různé typy zákazníků nebo uživatelů (např. bezplatní oproti placeným)
- Limity specifické pro zdroj nebo cestu (např. limit na trasu API)
- Jakákoli kombinace výše uvedeného
Rate Limiting API běží na stejné infrastruktuře, která obsluhuje pravidla rate limitingu.
Začínáme
Nejprve přidejte binding k vašemu Workeru, který mu udělí přístup k 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 = 60Tento binding zpřístupňuje MY_RATE_LIMITER binding, který poskytuje limit() metoda:
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 přijímá jediný argument, konfigurační objekt s key .
- Klíč, který zadáte, může být libovolný
stringhodnota. - Běžným postupem je definovat klíč kombinací řetězce, který jednoznačně identifikuje aktéra iniciujícího požadavek (např. ID uživatele nebo ID zákazníka), a řetězce, který identifikuje konkrétní zdroj (např. konkrétní API route).
Pro jeden Worker můžete definovat a nakonfigurovat více konfigurací rate limitingu, což vám umožňuje podle potřeby definovat různé limity pro příchozí požadavky a/nebo uživatelské parametry a chránit tak vaši aplikaci nebo upstream API.
Například takto můžete definovat dvě konfigurace omezení rychlosti požadavků pro uživatele s bezplatným a placeným plánem:
{
"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 = 60Konfigurace
Binding pro omezování rychlosti požadavků má následující nastavení:
| Nastavení | Typ | Popis |
|---|---|---|
namespace_id |
string |
Řetězec s kladným celým číslem, které jednoznačně určuje tento namespace pro omezování rychlosti požadavků ve vašem účtu Cloudflare (například "1001"). I když hodnota musí být platné celé číslo, uvádí se jako řetězec. Je to záměr. |
simple |
object |
Konfigurace rate limitu. simple je jediný podporovaný typ. |
simple.limit |
number |
Počet povolených požadavků (nebo volání limit()) v rámci dané period. |
simple.period |
number |
Doba trvání okna omezení rychlosti (rate limit), v sekundách. Musí být buď 10 nebo 60. |
Chcete-li například uplatnit limit 1500 požadavků za minutu, definujte konfiguraci omezení rychlosti požadavků takto:
{
"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 = 60Osvědčené postupy
key předaný do limit funkce, která určuje, co se má omezovat, by měla představovat jedinečnou charakteristiku uživatele nebo třídy uživatelů, pro které chcete frekvenci omezit.
- Mezi vhodné volby patří API klíče v
Authorizationhlavičky HTTP, cesty URL nebo routy, konkrétní parametry dotazu používané vaší aplikací a/nebo ID uživatelů a ID tenantů. Všechny tyto identifikátory jsou stabilní a je nepravděpodobné, že by se mezi jednotlivými požadavky měnily. - Nedoporučuje se používat IP adresy nebo polohy (regiony či země), protože je v mnoha oprávněných případech může sdílet velké množství uživatelů. Omezováním frekvence požadavků podle těchto klíčů tak můžete neúmyslně omezit širší skupinu uživatelů, než jste zamýšleli.
// 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 })Lokalita
Omezení rychlosti, která definujete a vynucujete ve svém Workeru, jsou lokální vůči lokalita Cloudflare ↗ ve kterém váš Worker běží.
Pokud například přijde požadavek na výše uvedený Worker ze Sydney v Austrálii, po 100 požadavcích během 60sekundového okna se všechny další požadavky na danou cestu odmítnou a vrátí se stavový kód HTTP 429. To by se ale týkalo pouze požadavků obsloužených v Sydney. Pro každý jedinečný klíč předaný vazbě rate limiting platí samostatný limit pro každou lokalitu Cloudflare.
Výkon
Rate Limiting API ve Workers je navržené tak, aby bylo rychlé.
Podkladové čítače jsou ukládány do mezipaměti na stejném stroji, na kterém běží váš Worker, a asynchronně se aktualizují na pozadí komunikací s úložištěm ve stejné lokalitě Cloudflare.
To znamená, že přestože ve svém kódu await volání limit() metoda:
const { success } = await env.MY_RATE_LIMITER.limit({ key: customerId })Nečekáte na síťový požadavek. Rate Limiting API můžete použít, aniž byste do svého Workeru zanesli znatelnou latenci.
Přesnost
Výše uvedené také znamená, že Rate Limiting API je benevolentní, postupně konzistentní a záměrně navržené tak, aby se nepoužívalo jako přesný účetní systém.
Pokud například do vašeho Workeru přichází v jedné lokalitě Cloudflare mnoho požadavků, všechny s omezením rychlosti na stejném klíči, izolát která obsluhuje každý požadavek, porovná to s lokálně uloženou hodnotou limitu četnosti požadavků. Tyto požadavky se velmi rychle, ale ne okamžitě, započítají do limitu četnosti požadavků v dané lokalitě Cloudflare.
Monitoring
Rate limiting bindings nejsou v současnosti v Cloudflare dashboardu vidět. Pro sledování požadavků s omezenou rychlostí z vašeho Workeru:
- Workers Observability : použijte Workers Logs a Trasování ke sledování HTTP 429 odpovědí vracených vaším Workerem při překročení rate limitů.
- Workers Analytics Engine : přidejte do svého Workeru binding Analytics Engine a odesílejte vlastní datové body (například
rate_limitedudálost) kdyžlimit()vrací{ success: false }. Díky tomu můžete vytvářet dashboardy a dotazovat se na metriky rate limitingu v čase.
Příklady
@elithrar/workers-hono-rate-limit↗, Middleware that lets you easily add rate limits to routes in your Hono ↗ aplikace.@hono-rate-limiter/cloudflare↗, Middleware that lets you easily add rate limits to routes in your Hono ↗ aplikace s možností výběru z několika datových úložišť.hono-cf-rate-limit↗ : middleware pro aplikace Hono, který v Cloudflare Workers uplatňuje rate limiting pomocí vestavěných funkcí Wrangleru.