تحديد معدل الطلبات (Rate Limiting) وThrottling في PHP: تحكم في تدفق الطلبات
\n\nتخيل: لقد أطلقت API رائع لخدمتك. كل شيء يعمل بشكل مثالي، حتى يبدأ أحد العملاء "المشاغبين" في إغراق خادمك بآلاف الطلبات في الثانية. أو الأسوأ من ذلك، يقرر بوت تجميع البيانات سحب قاعدة بياناتك بالكامل. هل هذا مألوف؟ إذا لم يكن كذلك، فأنت محظوظ. لكن من الأفضل أن تكون مستعدًا. وهنا يأتي دور تحديد معدل الطلبات (Rate Limiting) وThrottling - الفارسان اللذان سيحميان خادمك من الازدحام.
\n\nفي هذه المقالة، سنتعرف على كيفية تطبيق تحديد معدل الطلبات في PHP، وسنستعرض أمثلة عملية على الكود، وسنفهم أي طريقة تختار لمشروعك. تنبيه: لن تضطر لاختراع العجلة من جديد، لكن من المفيد معرفة الخوارزميات الأساسية.
\n\nRate Limiting مقابل Throttling: ما الفرق؟
\n\nغالبًا ما تُستخدم هذه المصطلحات كمرادفات، لكن هناك فرق دقيق بينهما.
\n\n- \n
- تحديد معدل الطلبات (Rate Limiting) - حد صارم. أنت تقول: "الحد الأقصى 100 طلب في الدقيقة". بمجرد استنفاد الحد، يتلقى العميل خطأ HTTP 429 (Too Many Requests) وعليه الانتظار. \n
- Throttling - تحكم أكثر مرونة. بدلاً من الحظر، يمكنك ببساطة إبطاء معالجة الطلبات التي تتجاوز الحد، أو وضعها في قائمة انتظار، أو تقليل أولويتها. \n
عمليًا، غالبًا ما يتم تنفيذ Throttling في PHP من خلال التأخير (sleep) أو قوائم الانتظار، بينما يتم تنفيذ تحديد معدل الطلبات من خلال حساب الطلبات لكل وحدة زمنية. بالنسبة لمعظم بوابات API، فإن الجمع بين كلا النهجين هو الأمثل.
\n\nلماذا هذا مهم جدًا لمشروعك؟
\n\nهناك ثلاثة أسباب رئيسية على الأقل لتطبيق تحديد معدل الطلبات في PHP:
\n\n- \n
- الحماية من هجمات DDoS والبوتات - حتى النص البرمجي البسيط يمكن أن يعطل الخادم إذا لم تتحكم في تكرار الطلبات. \n
- توزيع عادل للموارد - لا ينبغي أن يحرم عميل واحد "جشع" بقية المستخدمين من الخدمة. \n
- الاستقرار والقدرة على التنبؤ - ستعرف ذروة الحمل المتوقعة ويمكنك ضبط البنية التحتية بشكل صحيح. \n
خوارزميات تحديد معدل الطلبات: اختر الاستراتيجية
\n\nقبل كتابة الكود، دعنا نستعرض ثلاث خوارزميات شائعة. لكل منها مزاياها وعيوبها.
\n\n1. النافذة الثابتة (Fixed Window)
\nالنهج الأبسط. نقسم الوقت إلى شرائح (مثلًا، كل دقيقة). نتذكر عدد الطلبات التي وصلت في النافذة الحالية. عند الوصول إلى الحد، يتم الحظر حتى النافذة التالية.
\n\nالعيب: عند حدود النوافذ، قد يحدث طفرة - يمكن للعميل إرسال 100 طلب في نهاية الدقيقة و 100 أخرى في بداية الدقيقة التالية، مما يعطي 200 طلب في ثانيتين.
\n\n2. النافذة المنزلقة (Sliding Window)
\nخوارزمية أكثر دقة. بدلاً من الشرائح الثابتة، ننظر إلى آخر N ثانية. الطلبات "تتقادم" وتخرج من النافذة. هذا يمنع الطفرات على الحدود.
\n\n3. دلو الرموز (Token Bucket)
\nخوارزمية أنيقة من عالم الشبكات. يوجد "دلو" به رموز. كل طلب يأخذ رمزًا واحدًا. يتم تجديد الرموز بمعدل محدد. إذا كان الدلو فارغًا، يتم رفض الطلب. مثالي لـ Throttling في PHP، لأنه يسمح بطفرات صغيرة في حركة المرور.
\n\nالتنفيذ العملي: من البسيط إلى المعقد
\n\nدعنا ننتقل إلى الكود. سنبدأ بمثال أساسي باستخدام الملفات، ثم ننظر إلى الحلول الجاهزة للاستخدام في الإنتاج.
\n\nمحدد معدل طلبات أساسي باستخدام الملفات (للتعلم)
\n\nيستخدم هذا المثال الملفات لتخزين العدادات. غير مناسب للإنتاج، لكنه يوضح المبدأ بشكل ممتاز.
\n\n<?php\nclass SimpleRateLimiter {\n private string $storageDir;\n private int $maxRequests;\n private int $windowSeconds;\n\n public function __construct(string $storageDir, int $maxRequests = 100, int $windowSeconds = 60) {\n $this->storageDir = rtrim($storageDir, '/') . '/';\n $this->maxRequests = $maxRequests;\n $this->windowSeconds =