پرش به محتوای اصلی

RateLimitEngine؛ مهندسی کنترل نرخ برای سامانه‌های .NET

یک کتابخانه .NET 8 برای کنترل نرخ درخواست که الگوریتم، ذخیره‌سازی وضعیت و یکپارچه‌سازی HTTP را از هم جدا می‌کند و رفتار آن در همزمانی، مرزهای زمانی و خرابی Redis به‌صورت صریح تعریف شده است.

زمینه

کنترل نرخ در ظاهر یک شمارنده ساده است، اما در یک سامانه واقعی باید با درخواست‌های همزمان، چند نمونه از application، حالت توزیع‌شده، هزینه متفاوت درخواست‌ها و خرابی زیرساخت کنار بیاید. RateLimitEngine برای تبدیل این مسئله به یک کتابخانه قابل استفاده و قابل آزمون طراحی شد.

مسئله

هدف، ساخت یک abstraction پایدار برای rate limiting بود که بتواند الگوریتم‌های مختلف را بدون وابسته کردن application به جزئیات storage یا HTTP integration به کار بگیرد. علاوه بر تصمیم Allow/Deny، اطلاعاتی مانند Remaining، ResetAfter و RetryAfter نیز باید رفتار مشخص و قابل تفسیر داشته باشند.

محدودیت‌ها و الزامات

  • رفتار صحیح در حضور درخواست‌های همزمان
  • امکان استفاده از state محلی یا shared در Redis
  • جدا بودن الگوریتم، storage و HTTP integration
  • تعریف روشن رفتار هنگام در دسترس نبودن Redis
  • قابلیت آزمون‌پذیری رفتارهای وابسته به زمان و مرز پنجره‌ها
  • پشتیبانی از درخواست‌های weighted با هزینه بیشتر از یک permit

رویکرد

هسته طراحی حول یک IRateLimiter و factory انتخاب الگوریتم شکل گرفت. چهار الگوریتم Fixed Window، Sliding Window، Token Bucket و GCRA از لایه application جدا هستند و state می‌تواند در حافظه یا Redis نگهداری شود. یکپارچه‌سازی ASP.NET Core نیز به‌عنوان لایه جداگانه روی همین هسته قرار می‌گیرد.

text
Application -> IRateLimiter -> Algorithm
                         -> State Store (Memory / Redis)
                         -> HTTP Integration (ASP.NET Core)

تصمیم‌ها و مصالحه‌ها

تصمیمدلیل
جداسازی algorithm و stateامکان تغییر الگوریتم یا backend بدون تغییر قرارداد اصلی rate limiting.
Redis به‌عنوان state توزیع‌شدهچند instance می‌توانند روی یک limit مشترک کار کنند.
استفاده از زمان سرور Redisکاهش وابستگی رفتار توزیع‌شده به ساعت processهای مختلف.
تعریف صریح failure semanticsرفتار سیستم در زمان اختلال backend بخشی از contract است، نه یک جزئیات پنهان.
Weighted requestspermit مصرف‌شده می‌تواند متناسب با هزینه منطقی هر درخواست باشد.

نتیجه

خروجی یک کتابخانه reusable برای .NET 8 است که چهار الگوریتم rate limiting، backendهای in-memory و Redis، integration برای ASP.NET Core، درخواست‌های weighted و semantics مشخص برای failure و retry را در یک معماری تفکیک‌شده ارائه می‌کند. نسخه منتشرشده پروژه 1.0.0 است. این پروژه نشان می‌دهد مسئله‌ای که در ظاهر یک قابلیت کوچک است، چگونه می‌تواند به طراحی abstraction، مدیریت همزمانی، رفتار توزیع‌شده و قراردادهای روشن reliability نیاز داشته باشد.

عمق فنی

  • قرارداد اصلی IRateLimiter و RateLimitDecision
  • Fixed Window، Sliding Window، Token Bucket و GCRA
  • Redis state با Lua script و server time برای transitionهای اتمیک
  • جداسازی Core، Algorithms، Redis و ASP.NET Core integration
  • رفتار deterministic و قابل آزمون برای منطق وابسته به زمان

شواهد

کد، طراحی و مستندات پروژه به‌صورت عمومی در GitHub قابل بررسی است.

GitHub — RateLimitEngine

Repository شامل کد کتابخانه، مستندات طراحی، مثال‌ها و تست‌های پروژه است.

باز کردن منبع

مسئله فنی مشابهی دارید؟

اگر مسئله شما به reliability، concurrency، distributed state یا یک ماژول فنی حساس مربوط است، می‌توانیم درباره دامنه و مسیر مناسب بررسی کنیم.