19 يونيو، 2025
لغات البرمجة

كيف تبني نظام Rate Limiting متقدم باستخدام Redis وخوارزمية Token Bucket

في عالم مليء بالتطبيقات المتصلة بالإنترنت، من الضروري أن يكون لديك وسيلة للتحكم في عدد الطلبات التي يمكن للمستخدم أو العميل إرسالها إلى خوادمك. سواء كنت تدير واجهة API عامة أو تطور تطبيقًا داخليًا، فواحدة من أهم طبقات الحماية والأداء هي: نظام Rate Limiting.في هذه المقالة، سنتعمق في بناء نظام Rate Limiting متقدم باستخدام Redis وخوارزمية Token Bucket، مع شرح الفرق بينها وبين خوارزمية Leaky Bucket، ونوضح متى تستخدم كل واحدة، حسب نوع التطبيق أو الـ API.—ما هو Rate Limiting ولماذا هو مهم؟Rate Limiting هو أسلوب للتحكم في عدد الطلبات التي يمكن للمستخدم أو العميل إرسالها خلال فترة زمنية معينة. الهدف منه:حماية الخادم من الحمل الزائد.منع إساءة الاستخدام (مثل الـ Spam أو الهجمات).تحسين تجربة المستخدم ومنع “الاختناقات”.ضمان عدالة توزيع الموارد بين المستخدمين.—خوارزميات Rate Limiting: الفرق بين Token Bucket وLeaky Bucket1. Leaky Bucket:تشبه دلوًا يتسرب منه الماء بمعدل ثابت. الطلبات تدخل الدلو، لكنها تُعالج بمعدل ثابت. إذا فاض الدلو، يتم رفض الطلب.المميزات:معدل معالجة منتظم.جيد للأنظمة التي تتطلب استقرارًا في حجم المرور.العيوب:لا يسمح بـ “الانفجارات المؤقتة” (Burst).2. Token Bucket:أيضًا يشبه دلوًا، لكن بالعكس: الدلو يُملأ بـ Tokens بمعدل ثابت. كل طلب يحتاج إلى Token ليُنفذ. إذا كان هناك Tokens كافية، يُنفذ فورًا. وإذا لم يكن، ينتظر أو يُرفض.المميزات:يسمح بـ “الانفجارات المؤقتة” (Bursting).مرن أكثر في التعامل مع المستخدمين النشطين.العيوب:أكثر تعقيدًا في التنفيذ من Leaky Bucket.—لماذا نختار Token Bucket مع Redis؟Redis سريع وخفيف ومثالي لعمليات الوصول المتكرر منخفضة الكمون.مناسب للبيئات الموزعة، مما يسمح بتطبيق Rate Limiting على مستوى عالمي.Token Bucket يوفر مرونة في المعالجة، مما يجعله مثاليًا لـ REST APIs أو GraphQL التي قد تستقبل طلبات غير منتظمة.—الحالات المناسبة لاستخدام Token Bucketنوع API أو خدمة الأنسب لماذا؟API عام بعد تسجيل الدخول Token Bucket لأن المستخدمين قد يرسلون دفعات مفاجئة من الطلبات.خدمة بث مباشر أو Video Leaky Bucket يجب الحفاظ على معدل ثابت للبيانات.بوابة دفع إلكتروني Token Bucket يحتاج المستخدم لإرسال عدة طلبات متقاربة.مراقبة النظام أو Logging Leaky Bucket لتفادي انفجار السجلات فجأة.—تصميم Token Bucket باستخدام Redis1. ما نحتاجه لكل مستخدم أو مفتاح API:آخر وقت تم فيه تحديث الرصيد.عدد الـ Tokens المتاحة حاليًا.الحد الأقصى لعدد الـ Tokens.معدل إعادة تعبئة الـ Tokens (مثلاً: 1 كل ثانية).2. كيفية الحساب:عند كل طلب:1. نحسب كم Token تم تجديده منذ آخر مرة.2. نضيفها إلى الرصيد، دون تجاوز الحد الأقصى.3. إذا كان هناك على الأقل Token واحد:نسمح بالطلب ونخصم 1 Token.4. إذا لم يكن هناك Tokens كافية:نرفض الطلب (429 Too Many Requests).—مثال عملي بلغة Python باستخدام Redisimport timeimport redisr = redis.Redis()def allow_request(key, max_tokens=10, refill_rate=1): now = time.time() bucket = r.hgetall(key) if not bucket: r.hset(key, mapping={“tokens”: max_tokens – 1, “last”: now}) return True tokens = float(bucket.get(b”tokens”, 0)) last = float(bucket.get(b”last”, now)) elapsed = now – last # حساب عدد التوكنز التي تم تجديدها tokens = min(max_tokens, tokens + elapsed * refill_rate) if tokens >= 1: tokens -= 1 r.hset(key, mapping={“tokens”: tokens, “last”: now}) return True else: return Falseالمفاتيح في Redis ستكون فريدة لكل مستخدم أو مفتاح API، ويمكنك استخدام صلاحية انتهاء EXPIRE لإزالة المفاتيح القديمة.—مزايا هذا النظام:أداء فائق: Redis سريع جدًا ويعمل في الذاكرة.إمكانية التوزيع: يمكنك تطبيقه على خوادم متعددة.مرونة التخصيص: يمكن تعيين حد لكل مستخدم، أو لكل IP.دقة زمنية: الحسابات تعتمد على الوقت الحقيقي وليس على فواصل محددة.—إضافة حماية إضافية: تنبيهات + Retry-Afterعندما ترفض الطلب، أرسل Header:HTTP/1.1 429 Too Many RequestsRetry-After: 3يمكن أيضًا إرسال Header مخصص:X-RateLimit-Remaining: 2X-RateLimit-Reset: 1716022235هذا يسمح للمطورين الآخرين بفهم حدودهم ويمنعهم من إرسال طلبات عشوائية.—تحسينات ممكنةدعم حزم متعددة: على حسب نوع الطلب، تخصم 1 أو 2 أو أكثر من الـ Tokens.تخصيص حسب نوع العميل: حسابات مجانية لها حد معين، والمدفوعة حد أعلى.تحليل البيانات: استخدام Grafana أو Kibana لمراقبة معدل الرفض.—خاتمةبناء نظام Rate Limiting متقدم باستخدام Redis وخوارزمية Token Bucket هو خطوة مهمة لأي تطبيق Backend يتعامل مع عدد كبير من الطلبات. باستخدام هذا النموذج، تستطيع توفير أداء عادل، حماية خوادمك، وتحسين تجربة المستخدم دون التنازل عن المرونة.

Leave feedback about this