تحديد معدل الطلبات في C++: نظرة عامة على الأدوات والتنفيذ
\n\nتحديد معدل الطلبات (Rate limiting) هو آلية بالغة الأهمية لحماية خدمات الويب وAPI والخدمات المصغرة من الأحمال الزائدة وهجمات DDoS والاستخدام غير الرشيد للموارد. في النظام البيئي لـ C++، توجد العديد من المكتبات الناضجة والأساليب لتنفيذ تحديد معدل الطلبات. في هذه المقالة، سنستعرض الخوارزميات الرئيسية والمكتبات الشائعة ونكتب أمثلة على الكود.
\n\nخوارزميات تحديد معدل الطلبات الشائعة
\n\nقبل اختيار مكتبة، من المفيد فهم الخوارزميات الأساسية:
\n\n- \n
- Token Bucket (سلة الرموز) — يتم إضافة الرموز بمعدل ثابت، ويستهلك كل طلب رمزًا واحدًا. إذا لم تكن هناك رموز، يتم رفض الطلب. بسيط وفعال. \n
- Sliding Window (النافذة المنزلقة) — تأخذ في الاعتبار عدد الطلبات خلال الفاصل الزمني الأخير (مثل 10 طلبات في الثانية الواحدة). \n
- Fixed Window (النافذة الثابتة) — عداد بسيط للطلبات خلال فترة زمنية ثابتة (مثل إعادة تعيين العداد كل دقيقة). \n
- Leaky Bucket (الدلو المتسرب) — يتم وضع الطلبات في قائمة انتظار ومعالجتها بمعدل ثابت، ويتم تجاهل الفائض. \n
مكتبات تحديد معدل الطلبات في C++
\n\n1. Boost.Token Bucket (Boost.Timer + تنفيذ يدوي)
\n\nلا توجد في Boost مكتبة جاهزة لـ token bucket، ولكن من السهل كتابتها باستخدام boost::timer أو std::chrono. ومع ذلك، للحلول الإنتاجية، من الأفضل استخدام مكتبات كاملة.
2. libcppa (إطار عمل C++ Actor)
\n\nتوفر مكتبة libcppa (الآن جزء من CAF — C++ Actor Framework) آليات مدمجة لتحديد معدل الطلبات للممثلين (Actors). تسمح بتقييد عدد الرسائل في وحدة الزمن.
#include <caf/all.hpp>\n\nusing namespace caf;\n\nbehavior rate_limited_actor(event_based_actor* self, int max_requests, duration period) {\n auto limiter = self->make_rate_limiter(max_requests, period);\n return {\n [=](const std::string& msg) {\n if (limiter->try_acquire()) {\n aout(self) << "Processed: " << msg << endl;\n } else {\n aout(self) << "Rate limit exceeded for: " << msg << endl;\n }\n }\n };\n}\n\n\n3. userver (من ياندكس)
\n\nإطار العمل userver من ياندكس هو حل قوي للخدمات عالية التحميل بلغة C++. يتضمن دعمًا مدمجًا لتحديد معدل الطلبات من خلال components::RateLimiter و utils::TokenBucket.
#include <userver/utils/token_bucket.hpp>\n\nusing namespace userver;\n\nint main() {\n utils::TokenBucket limiter(10, std::chrono::seconds(1)); // 10 طلبات في الثانية\n for (int i = 0; i < 20; ++i) {\n if (limiter.TryObtain()) {\n std::cout << "Request " << i << " allowed\\n";\n } else {\n std::cout << "Request " << i << " blocked\\n";\n }\n std::this_thread::sleep_for(std::chrono::milliseconds(50));\n }\n return 0;\n}\n\n\n4. Pistache (إطار عمل HTTP مع تحديد معدل الطلبات)
\n\nمكتبة Pistache لإنشاء خوادم HTTP تحتوي على middleware مدمج لتحديد معدل الطلبات. مثال:
\n\n#include <pistache/endpoint.h>\n#include <pistache/router.h>\n#include <pistache/http.h>\n\nusing namespace Pistache;\n\nint main() {\n Http::Endpoint server(Address(Ipv4::any(), Port(9080)));\n auto router = std::make_shared<Rest::Router>();\n \n // محدد معدل مدمج: 5 طلبات في الثانية\n router->addMiddleware(Http::Middleware::RateLimit(5, std::chrono::seconds(1)));\n \n Rest::Routes::Get(*router, "/api/resource", [](const Rest::Request& req, Http::ResponseWri