محدود کننده های سرعت طراحی
1) چرا محدود کردن نرخ
محدود کردن نرخ در دسترس بودن و اقتصاد API ها را محافظت می کند: سیل ها را متوقف می کند، انفجار مجدد، اعتبار سنجی، محافظت از عملیات گران قیمت (معاملات پول، تولید گزارش)، بار را بر روی سیستم های وابسته (پایگاه داده ها/ارائه دهندگان) هموار می کند. طراحی خوب عدالت، قابلیت پیش بینی تاخیر و SLO های روشن را می دهد.
اهداف کلیدی
پایداری RPS و حفاظت از اضافه بار پشتی.
«کشش» کنترل (پشت سر هم کمک هزینه).
تمایز مشتری (در هر کاربر/در هر سازمان/در هر کلید/در هر IP/در هر منطقه).
مدل ارزش: «قیمت های» مختلف برای معاملات مختلف.
2) انواع محدود
محدودیت RPS: درخواست در هر ثانیه/دقیقه.
سهمیه: کل بودجه در هر دوره (روز/ماه).
رقابت: عملیات همزمان (پرداخت، کار سنگین).
نرخ/نوار بایت/ثانیه (بار/بارگیری).
محدودیت های وزنی: «هزینه» درخواست توسط پیچیدگی (به عنوان مثال، پیچیدگی GraphQL، اندازه دسته ای).
تطبیقی: در صورت بروز ناهنجاری ها (فعالیت مشکوک/خطاهای 401/403/5xx) محکم تر می شود.
3) الگوریتم ها و زمان استفاده از آنها
3. 1 شمارنده پنجره ثابت
ساده: شمارنده در هر فاصله (به عنوان مثال 100 دور در دقیقه)
مزایا: حداقل هزینه. منفی: «انفجار لبه» در مرزهای پنجره.
هنگامی که: پانل های مدیریت، دقت کم، کم هزینه.
3. 2 پنجره کشویی (ورود/شمارنده)
Log - زمان بندی درخواست های اخیر، دقیق و گران قیمت را در حافظه ذخیره می کند.
شمارنده: میانگین دو پنجره مجاور (نورد)، سازش دقت و قیمت.
هنگامی که: API های عمومی ترافیک متوسط، شما نیاز به صاف بودن بدون ریاضیات پیچیده دارید.
3. 3 سطل نشانه
پارامترها: نرخ 'r' (نشانه ها/ثانیه) و ظرفیت 'b' (پشت سر هم). هر درخواست نشانه را «می سوزاند».
مزایا: کمک هزینه پشت سر هم طبیعی، اجرای ساده. معایب: هیچ یکنواختی دقیقی وجود ندارد.
زمان: تقریبا همیشه برای RPS، اگر «volleys» در «b» مورد نیاز است.
3. 4 سطل نشتی (قطره ای)
صف که از آن «نشت» با سرعت ثابت.
مزایا: حتی جریان خروجی. معایب: تاخیر بیشتر
هنگامی که: صاف کردن به ارائه دهندگان «شکننده» خارجی.
3. 5 GCRA (الگوریتم نرخ سلول تعمیم یافته)
مدل زمان رسیدن تئوری (TAT):- 'TAT _ next = max (TAT_current, now) + 1/r'، درخواست پذیرفته میشود اگر «now <= TAT_current + burst/r».
- مزایا: دقیق، دقیق، حافظه کمی (حفظ TAT توسط کلید). معایب: درک آن سخت تر است.
هنگامی که: نیاز به کنترل دقیق و صاف بودن، محدودیت های توزیع شده.
3. 6 سمافور رقابتی
ضد عملیات فعال ؛ ورودی - اگر «بلیط» وجود دارد ؛ خروج - رها کردن
چه زمانی: عملیات طولانی مدت، موضوعات، WebSocket، بارگیری ها.
4) محدود کردن مدل کلیدی
کلید = ترکیب خصیصه:- 'client _ id '/' api _ key '/' user _ id '/' org _ id'
- 'IP/ASN/geo' (حفاظت خشن)
- 'endpoint/method' (مسیرهای داغ)
- 'scope/plan/tier' (کسب درآمد)
- 'idempotency _ key' (عملیات نوشتن)
- استفاده از یک سلسله مراتب: اول سخت در هر کلید، پس از آن در هر سازمان، پس از آن جهانی است.
5) مدل هزینه
تعریف «هزینه» «هزینه (q)»:- GraphQL: عمق × پیچیدگی میدان
- REST: اندازه پاسخ/درخواست، نوع عملیات (خواندن = 1، نوشتن = 3، گزارش = 10).
- دسته: 'هزینه = دقیقه (n، کلاه)'.
- ما توکنها را محدود میکنیم، نه «درخواستها»: «بودجه - = هزینه (q)».
6) پیاده سازی توزیع شده
6. 1 غرفه ها
در فرآیند: فوق العاده سریع، اما نه یک حد کلی (مناسب برای محدودیت های «نرم» محلی).
Redis: استاندارد واقعی. INCR/EXPIRE، اسکریپت های Lua (اتمی)، ZSET برای پنجره کشویی، کلیدهای با TTL.
فرستاده/NGINX/کنگ/Traefik: ساخته شده در فیلتر ؛ مناسب برای محیط.
Service Mesh: محدودیت های محلی در sidecar + هماهنگ سازی جهانی.
6. ۲ اتمی و مسابقه
Lua در Redis: چک کردن و افزایش در یک مرحله.
GCRA: ذخیره یک TAT با CAS/اسکریپت.
سازگاری ساعت: NTP، تایمر یکنواخت.
شاردینگ: هش سازگار با کلید ؛ اجتناب از قطعات «داغ».
6. 3 توزیع جغرافیایی
محدودیت های محلی در خوشه های منطقه ای + جهانی بالا (درشت).
CRDT/تکرار - مراقب باشید (تاخیر، مصرف دو برابر). محدودیت های منطقه ای با حاشیه ترجیح داده می شوند.
7) سیاست ها و اولویت بندی
برنامه ها: Free/Pro/Enterprise با «r»، «b»، سهمیه های مختلف.
اولویت ها: مسیرهای «گران» محدودیت کمتر یا هزینه بیشتری دارند.
لیست ها: اجازه می دهد لیست برای ادغام، انکار توسط ASN/پروکسی/TOP.
تشدید: اگر دوباره از آن عبور کنید، محدودیت را کاهش دهید، اثبات کار/captcha/challenges را وارد کنید.
8) نمونه هایی از پیکربندی
8. 1 نماینده (فیلتر محدودیت نرخ HTTP، شبه)
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، شبه)
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 محدودیت های رقابتی (شبه کد)
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 (شبه کد)
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) ادغام با retrays، timeouts و قطع کننده مدار
بودجه مجدد: سهم retrays را به X٪ از ترافیک اصلی محدود کنید.
Jitter: هنگامی که عقب نشینی، همیشه اضافه کردن لرزش - کاهش انفجار همزمان.
قطع کننده مدار: اگر یک خطای بالا («5xx»، وقفه) وجود دارد، محدودیت ها را کاهش دهید یا برخی از مسیرها را به «فقط خواندنی» انتقال دهید.
هجینگ: شسته و رفته ؛ در نظر گرفتن هزینه برای جلوگیری از دو برابر شدن بودجه خود را.
10) قابلیت مشاهده و مدیریت
Метрики: 'rps _ allowed', 'rps _ blocked', '429 _ rate', 'retry _ after _ avg', 'burst _ used', 'quota _ remaining', 'active _ concurrency'.
برچسب ها: با کلید محدود، منطقه، نقطه پایانی، برنامه.
سیاهههای مربوط به تصمیم (نمونه برداری): علت شکست، شمارنده فعلی، کلید TTL.
داشبورد: کارت های گرما با کلید/endpoints، مشتریان «داغ».
هشدارها: رشد 429> 2-5٪ در مسیرهای بحرانی، «خستگی» مکرر سهمیه ها، عدم تعادل قطعات.
11) تست و اعتبار سنجی
تست های قرارداد سیاست ها (جداول if-then).
بارگذاری: انفجار (x10 از r)، فلات طولانی، الگوهای «کثیف» (slow-POST، اتصالات طولانی).
ترافیک هرج و مرج: جریان ناهموار، رانش ساعت، قطره Redis/مش.
A/B-گنجاندن: canary rollout limits, سایه-راه حل (ورود به سیستم, اما مسدود نمی) قبل از گنجاندن.
12) موارد لبه و ظرافت
از «now ()» از یک منبع واحد (سرور) استفاده کنید، نه از هدر های مشتری.
Idempotency-Key: برای نوشتن - تقویت در retras را کاهش می دهد.
عملیات دسته ای: اندازه دسته و هزینه کل را محدود کنید.
نظرسنجی طولانی/WebSocket: تعداد کانال ها/اشتراک ها و مدت زمان را محدود کنید.
شروع سرد: شروع «گرم» شمارنده/پیش بارگذاری ؛ در غیر این صورت انفجار false 429.
درخواست های محاسباتی گران قیمت: محدود به اجرای منطق کسب و کار.
مرزهای TTL: TTL کلیدها باید پنجره + حاشیه ایمنی را پوشش دهند.
13) افزایش آنتی بوت
مراحل: هشدار → 429 + 'Retry-After' → چالش (captcha/پازل) → بلوک موقت.
سیگنال ها: دستگاه اثر انگشت، رفتار مکان نما/زمان بندی، TOR/پروکسی/میزبانی.
سیاستها باید برای پزشکی قانونی قطعی و قابل بازتولید باشند.
14) ایمنی و انطباق
انکار به طور پیش فرض در مسیرهای بحرانی (نوشتن/امور مالی).
حسابرسی: تصمیم گیری در مورد محدودیت ها برای موارد قانونی و بررسی حوادث را حفظ کنید.
PII: کلیدهای محدود نباید اطلاعات شخصی را در سیاهههای مربوط افشا کنند.
15) تولید لیست آمادگی
- کلید محدود و مدل هزینه تعریف شده است.
- الگوریتم انتخاب شده (token bucket/GCRA) و ذخیره سازی (Redis/gateway).
- سیاست برای مشتریان ردیف + فیوز جهانی است.
- محدودیت های رقابتی برای معاملات بلند مدت.
- تلاش مجدد بودجه، عقب نشینی با jitter، ادغام با قطع کننده مدار.
- داشبورد/هشدار، سیاهههای مربوط تصمیم گیری نمونه.
- قناری و حالت سایه.
- تست انفجار، فلات طولانی، شکست Redis، انحراف ساعت.
- مستندات مشتری: 429، کدهای «Retry-After»، نمونه های بازگشتی نمایشی.
16) TL ؛ دکتر متخصص
استفاده از سطل نشانه یا GCRA با Redis/دروازه، کلید های محدود طراحی و هزینه های درخواست، اضافه کردن semaphores رقابتی برای عملیات طولانی، ادغام با بودجه مجدد و قطع کننده مدار، نظارت بر 429 و «ظرفیت پشت سر هم»، رول از محدودیت ها از طریق canary/سایه و مطمئن شوید که برای تست انفجار و شکست ذخیره سازی