تحديد معدل الطلبات في C# (.NET): دليل شامل لمكتبة System.Threading.RateLimiting
\n\nفي تطبيقات الويب الحديثة والخدمات المصغرة (Microservices)، من الضروري التحكم في الحمل على الموارد. تحديد معدل الطلبات (Rate Limiting) هو آلية تمنع الاستخدام المفرط لواجهات API أو قواعد البيانات أو المكونات الأخرى. في نظام .NET البيئي، ظهرت مكتبة مضمنة System.Threading.RateLimiting توفر أدوات مرنة وعالية الأداء لتطبيق تحديد معدل الطلبات. في هذه المقالة، سنشرح بالتفصيل إمكانياتها وهندستها وأمثلة على استخدامها.
ما هي System.Threading.RateLimiting؟
\nSystem.Threading.RateLimiting هي مكتبة مضمنة في .NET 7 والإصدارات الأحدث. توفر تجريدات (Abstractions) وتطبيقات لاستراتيجيات مختلفة لتحديد السرعة. الفئة الرئيسية هي RateLimiter، التي تدير الوصول إلى المورد، وتسمح أو ترفض الطلبات بناءً على قواعد محددة.
المفاهيم الأساسية
\n- \n
- RateLimiter — الفئة الأساسية التي ترث منها جميع التطبيقات. \n
- Acquire / TryAcquire — طرق متزامنة (Synchronous) للحصول على الإذن. \n
- AcquireAsync / WaitAsync — طرق غير متزامنة (Asynchronous) تسمح بانتظار تحرير الحد. \n
- Metadata — معلومات إضافية حول الحد (مثل الوقت المتبقي لإعادة التعيين). \n
استراتيجيات تحديد معدل الطلبات المضمنة
\nتدعم المكتبة أربع استراتيجيات رئيسية:
\n\n1. النافذة الثابتة (Fixed Window)
\nيتم تجميع الطلبات في نوافذ زمنية ذات طول ثابت. إذا تم تجاوز الحد، يتم رفض الطلبات حتى بداية النافذة التالية.
\nusing System.Threading.RateLimiting;\n\nvar options = new FixedWindowRateLimiterOptions\n{\n PermitLimit = 10,\n Window = TimeSpan.FromSeconds(1),\n QueueProcessingOrder = QueueProcessingOrder.OldestFirst,\n QueueLimit = 0\n};\n\nvar limiter = new FixedWindowRateLimiter(options);\n\nfor (int i = 0; i < 15; i++)\n{\n using var lease = await limiter.AcquireAsync();\n if (lease.IsAcquired)\n {\n Console.WriteLine($"الطلب {i} تم تنفيذه");\n }\n else\n {\n Console.WriteLine($"الطلب {i} تم رفضه");\n }\n}\n\n2. النافذة المنزلقة (Sliding Window)
\nتشبه النافذة الثابتة، ولكن النافذة "تنزلق" مع كل طلب، مما يوفر تقييدًا أكثر سلاسة. يتم تقسيمها إلى أجزاء (Segments).
\nvar slidingOptions = new SlidingWindowRateLimiterOptions\n{\n PermitLimit = 10,\n Window = TimeSpan.FromSeconds(1),\n SegmentsPerWindow = 4,\n QueueLimit = 0\n};\n\nvar slidingLimiter = new SlidingWindowRateLimiter(slidingOptions);\n\n3. سلة الرموز (Token Bucket)
\nواحدة من أشهر الخوارزميات. تحتوي السلة على عدد معين من "الرموز المميزة". يتم إضافة الرموز بمعدل محدد. يستهلك الطلب رمزًا واحدًا أو أكثر. إذا كانت السلة فارغة، ينتظر الطلب أو يتم رفضه.
\nvar tokenOptions = new TokenBucketRateLimiterOptions\n{\n TokenLimit = 100,\n QueueLimit = 0,\n ReplenishmentPeriod = TimeSpan.FromSeconds(1),\n TokensPerPeriod = 10,\n AutoReplenishment = true\n};\n\nvar tokenLimiter = new TokenBucketRateLimiter(tokenOptions);\n\n4. خط الأنابيب (Concurrency Limiter)
\nيحدد عدد الطلبات التي يتم تنفيذها في وقت واحد. مفيد لإدارة التوازي (Concurrency) بدلاً من السرعة.
\nvar concurrencyOptions = new ConcurrencyLimiterOptions\n{\n PermitLimit = 5,\n QueueLimit = 10\n};\n\nvar concurrencyLimiter = new ConcurrencyLimiter(concurrencyOptions);\n\nاستخدام RateLimiter في ASP.NET Core
\nبدءًا من .NET 7، يمكن دمج تحديد معدل الطلبات بسهولة في middleware الخاص بـ ASP.NET Core. تسجيل الخدمات وتكوين السياسات:
\n// Program.cs\nbuilder.Servi