Limitatoare de rată de proiectare
1) De ce limitarea ratei
Limitarea ratei protejează disponibilitatea și economia API-urilor: oprește inundațiile, exploziile de retribuții, umplutura de acreditare, protejează operațiunile costisitoare (tranzacții bănești, generarea de rapoarte), netezește sarcina pe sistemele dependente (baze de date/furnizori). Designul bun oferă corectitudine, predictibilitate de latență și SLO-uri clare.
Obiective cheie
RPS stabilitate și protecție la suprasarcină backend.
„elasticitate” controlată (indemnizație de spargere).
Diferențierea clienților (per utilizator/per organizație/per cheie/per IP/per regiune).
Model de valoare: diferite „prețuri” pentru diferite tranzacții.
2) Tipuri de limită
Limitele SPR: cereri pe secundă/minut.
Cote: buget total pe perioadă (zi/lună).
Competitivitate: operațiuni simultane (checkout, muncă grea).
Tarif/Bandă Octeți/sec (încărcare/descărcare).
Limite ponderate: „costul” cererii prin complexitate (de exemplu, complexitatea GraphQL, dimensiunea lotului).
Adaptiv: înăsprit în caz de anomalii (activitate suspectă/erori 401/403/5xx).
3) Algoritmi și când să le aplicați
3. 1 Contor de ferestre fixe
Simplu: contra pe interval (ex. 100 r/min).
Pro: Costul minim. Contra: „explozii de margine” la marginile ferestrei.
Când: panouri admin, precizie redusă, cost redus.
3. 2 Fereastră glisantă (jurnal/contor)
Jurnal - stochează marcajele de timp ale cererilor recente, exacte, scumpe în memorie.
Contra: media a două ferestre adiacente (rulare), un compromis de precizie și preț.
Când: API-uri publice de trafic mediu, aveți nevoie de netezime fără matematică complexă.
3. 3 Cupă token
Parametrii: rata „r” (jetoane/sec) și capacitatea „b” (explozie). Fiecare cerere „arde” jetonul.
Argumente pro: indemnizație naturală, implementare simplă. Contra: Nu există o planeitate strictă.
Când: aproape întotdeauna pentru SPR, în cazul în care „volei” sunt necesare în cadrul „b”.
3. 4 Găleată cu scurgeri (picurare)
Coadă din care „scurgeri” la o viteză fixă.
Pro: chiar și fluxul de ieșire. Contra: Mai multe întârzieri.
Când: netezirea la furnizorii externi „fragili”.
3. 5 GCRA (Algoritm generalizat al ratei celulelor)
Modelul timpului teoretic de sosire (TAT):- 'TAT _ next = max (TAT_current, acum) + 1/r', cererea este acceptată dacă 'now <= TAT_current + burst/r'.
- Pro: memorie strictă, precisă, mică (păstrați TAT după cheie). Contra: mai greu de înțeles.
Când: aveți nevoie de control strict și netezime, limite distribuite.
3. 6 Semafoare competitive
Contor de operare activă; intrare - dacă există „bilete”; ieșire - eliberare.
Când: operațiuni de lungă durată, fire, WebSocket, descărcări.
4) Limită model cheie
Key = combinație atribut:- 'client _ id'/' api _ key '/' user _ id'/' org _ id'
- „IP/ASN/geo” (protecție brută)
- „punct final/metodă” (rute fierbinți)
- 'scop/plan/nivel' (monetizare)
- 'idempotency _ key' (operații de scriere)
- Utilizați o ierarhie: mai întâi strict pe cheie, apoi pe organizație, apoi global.
5) Model de cost
Definiți „cost” „cost (q)”:- GraphQL: complexitatea × adâncimea câmpului.
- REST: marimea raspunsului/cererii, tipul de operatie (read = 1, write = 3, report = 10).
- Lot: 'cost = min (n, capac)'.
- Limităm jetoanele, nu „cereri”: 'buget - = cost (q)'.
6) Implementarea distribuită
6. 1 Bolți
În proces: ultra-rapid, dar nu și o limită generală (potrivită pentru limitele locale „moi”).
Redis: standard de facto. INCR/EXPIRĂ, scripturi Lua (atomicitate), ZSET pentru fereastră glisantă, chei cu TTL.
Trimisul/NGINX/Kong/Traefik: filtre încorporate; convenabil pentru perimetru.
Service Mesh: limite locale pe sidecar + sincronizare globală.
6. 2 Atomicitate și curse
Lua în Redis: verificarea și incrementarea într-un singur pas.
GCRA: stocați un TAT cu CAS/script.
Consistența ceasului: NTP, cronometre monotone.
Sharding: hash consecvent cu cheie; evită cioburile „fierbinţi”.
6. 3 Geo-distribuție
Limitele locale ale clusterelor regionale + globale superioare (grosiere).
CRDT/replicare - atent (întârzieri, consum dublu). Limitele regionale cu o marjă sunt preferabile.
7) Politici și prioritizare
Planuri: Free/Pro/Enterprise cu diferite „r”, „b”, cote.
Priorități: rutele „scumpe” primesc mai puține limite sau costuri mai mari.
Liste: allow-list for integrations, deny by ASN/proxy/TOP.
Escaladarea: dacă o depășiți din nou, coborâți limita, introduceți dovada muncii/captcha/provocări.
8) Exemple de configurații
8. 1 Envoy (filtru limită de rată HTTP, pseudo)
yaml rate_limit:
domain: public-api descriptors:
- key: api_key rate_limit:
unit: second requests_per_unit: 50 burst: 100
- key: api_key value: payments. write rate_limit:
unit: second requests_per_unit: 5 burst: 10
8. 2 NGINX (lua + Redis, pseudo)
nginx lua_shared_dict limits 10m;
location /api/ {
access_by_lua_block {
local key = ngx. var. arg_apikey.. ":".. ngx. var. request_method.. ":".. ngx. var. uri
-- token bucket in Redis (evalsha)
local allowed, retry_after = ratelimit_allow(key, 50, 100) -- r=50/s, b=100 if not allowed then ngx. header["Retry-After"] = retry_after return ngx. exit(429)
end
}
proxy_pass http://backend;
}
8. 3 Limite competitive (pseudo cod)
pseudo on_request_start(key):
if redis. incr_with_ttl("sem:" + key, ttl=60) > MAX_CONCURRENCY:
redis. decr("sem:" + key); reject(429)
on_request_finish(key):
redis. decr("sem:" + key)
8. 4 GCRA (pseudocod)
pseudo params: r tokens/sec, burst b tat = redis. get(key) or now allowed_time = tat - (b / r)
if now < allowed_time: reject(429, retry_after = allowed_time - now)
tat_next = max(tat, now) + 1/r redis. set(key, tat_next, ttl = ceil(b/r) + safety)
9) Integrarea cu retroys, timeout-uri și întrerupător de circuit
Reîncercați bugetul: limitați ponderea retroactivelor la X% din traficul principal.
Jitter: când backoff, adăugați întotdeauna jitter - reduce exploziile sincrone.
Întrerupător de circuit: dacă există o eroare mare ('5xx', timeout), coborâți limitele sau transferați unele dintre trasee la „read-only”.
Gard viu: îngrijit; ia în considerare costurile pentru a evita dublarea bugetului.
10) Observabilitate și management
Метрики: 'rps _ allowed', 'rps _ blocked', '429 _ rate', 'retry _ after _ avg', 'burst _ used', 'cotă _ rămasă', 'active _ concurency'.
Labels: by limit key, region, endpoint, plan.
Jurnalele decizionale (eșantionate): cauza eșecului, contoarele curente, TTL cheie.
Tablouri de bord: carduri de căldură de taste/endpoints, clienți „fierbinți”.
Alerte: creștere de 429> 2-5% pe rutele critice, frecventă „epuizare” a cotelor, dezechilibru al cioburilor.
11) Testarea și validarea
Testele contractuale ale politicilor (tabele if-then).
Încărcare: explozii (x10 din r), platouri lungi, modele „murdare” (lent-POST, conexiuni lungi).
Trafic haos: fluxuri inegale, derivă ceas, Redis/plasă picătură.
A/B-includere: limite de lansare a canarului, soluții de umbră (log, dar nu blocați) înainte de includere.
12) Cazuri de margine și subtilități
Înclinare ceas: Utilizați „acum ()” de la o singură sursă (server), nu de la anteturile clientului.
Idempotency-Key: pentru scriere - reduce amplificarea în retras.
Operațiuni de lot: limitați dimensiunea lotului și costul total.
Sondaj lung/WebSocket: limitați numărul de canale/abonamente și durata.
Start rece: pornirea „caldă” a contoarelor/preîncărcării; în caz contrar explozii de fals 429.
Solicitări costisitoare computațional: limită la executarea logicii de afaceri.
Limitele TTL: TTL ale cheilor trebuie să acopere fereastra + marja de siguranță.
13) Escaladări ale antibot
Etape: avertizare → 429 + „Retry-After” provocare → (captcha/puzzle) → bloc temporar.
Semnale: dispozitiv-amprentă digitală, cursor/comportament de sincronizare, TOR/proxy/hosting.
Politicile trebuie să fie deterministe și reproductibile pentru criminalistică.
14) Siguranță și conformitate
Refuzați implicit rutele critice (scriere/finanțare).
Audit: păstrați deciziile privind limitele pentru cazurile de reglementare și revizuirile incidentelor.
PII: cheile limită nu trebuie să dezvăluie datele personale în jurnale.
15) Lista de verificare Prod Readiness
- Cheile limită și modelul de cost sunt definite.
- Algoritm selectat (cupă token/GCRA) și de stocare (Redis/gateway).
- Politici pentru clienți de nivel + siguranțe globale.
- Limite competitive pentru tranzacțiile pe termen lung.
- Retry-buget, backoff cu jitter, integrarea cu întrerupător de circuit.
- Tablouri de bord/alerte, jurnale de decizii eșantionate.
- Canare pe și modul umbră.
- Teste de explozii, platouri lungi, eșecuri Redis, înclinare ceas.
- Documentația clientului: 429, codurile „Retry-After”, exemple exponențiale de backoff.
16) TL; DR
Utilizați găleată token sau GCRA cu Redis/gateway, tastele limită de proiectare și solicitați costuri, adăugați semafoare competitive pentru operațiuni lungi, integrați-vă cu bugetul reîncercat și întrerupătorul de circuit, monitorizați 429 și „capacitatea de spargere”, introduceți limitele prin canar/umbră și asigurați-vă că testați exploziile și eșecul de stocare