تحديد معدل الطلبات في C++: المكتبات والأدوات للتحكم في الطلبات

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

تحديد معدل الطلبات في C++: دليل كامل لتقييد الطلبات



تحديد معدل الطلبات (Rate limiting) هو آلية بالغة الأهمية لحماية الخوادم وواجهات برمجة التطبيقات (API) والأنظمة الموزعة من الأحمال الزائدة وهجمات حجب الخدمة الموزعة (DDoS) والارتفاعات المفاجئة في حركة المرور. في لغة C++، يتطلب تنفيذ تحديد معدل الطلبات خوارزميات فعالة واختيارًا صحيحًا للمكتبات. في هذه المقالة، سنستعرض الأساليب الرئيسية والمكتبات الشائعة ونقدم أمثلة جاهزة للكود.



ما هو تحديد معدل الطلبات ولماذا هو مطلوب؟

يحدد تحديد معدل الطلبات الحد الأقصى لعدد الطلبات التي يمكن للعميل أو النظام تنفيذها خلال فترة زمنية محددة. الأهداف الرئيسية:

  • الحماية من إساءة الاستخدام والتحميل الزائد على الخادم
  • ضمان توزيع متساوٍ للموارد بين المستخدمين
  • منع هجمات حجب الخدمة الموزعة (DDoS) وهجمات القوة الغاشمة
  • التحكم في استهلاك حصص واجهات برمجة التطبيقات (API)


الخوارزميات الرئيسية لتحديد معدل الطلبات

في لغة C++، يتم استخدام ثلاث خوارزميات تقليدية بشكل شائع:



1. Token Bucket (دلو الرموز)

الخوارزمية الأكثر شيوعًا. تمثل "دلوًا" يحتوي على رموز يتم تجديدها بمعدل ثابت. كل طلب يستهلك رمزًا واحدًا. إذا لم تكن هناك رموز، يتم رفض الطلب.

#include <chrono>#include <mutex>

class TokenBucket {private: double tokens; double maxTokens; double refillRate; // رمز في الثانية std::chrono::steady_clock::time_point lastRefill; std::mutex mtx;

public: TokenBucket(double maxTokens, double refillRate) : tokens(maxTokens), maxTokens(maxTokens), refillRate(refillRate) { lastRefill = std::chrono::steady_clock::now(); }

bool tryConsume() { std::lock_guard<std::mutex> lock(mtx); refill(); if (tokens >= 1.0) { tokens -= 1.0; return true; } return false; }

private: void refill() { auto now = std::chrono::steady_clock::now(); auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - lastRefill).count() / 1000.0; tokens = std::min(maxTokens, tokens + elapsed * refillRate); lastRefill = now; }};


2. Leaky Bucket (الدلو المتسرب)

تدخل الطلبات إلى قائمة انتظار (دلو) تتم معالجتها بمعدل ثابت. إذا فاض الدلو، يتم تجاهل الطلبات.

#include <queue>#include <chrono>

class LeakyBucket {private: std::queue<int> bucket; size_t capacity; double leakRate; // طلب في الثانية std::chrono::steady_clock::time_point lastLeak; std::mutex mtx;

public: LeakyBucket(size_t capacity, double leakRate) : capacity(capacity), leakRate(leakRate) { lastLeak = std::chrono::steady_clock::now(); }

bool addRequest(int request) { std::lock_guard<std::mutex> lock(mtx); leak(); if (bucket.size() < capacity) { bucket.push(request); return true; } return false; }

private: void leak() { auto now = std::chrono::steady_clock::now(); auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - lastLeak).count() / 1000.0; size_t toRemove = static_cast<size_t>(elapsed * leakRate); while (toRemove > 0 && !bucket.empty()) { bucket.pop(); toRemove--; } lastLeak = now; }};


3. Sliding Window Log (سجل النافذة المنزلقة)

يخزن الطوابع الزمنية للطلبات ويتجاهل تلك التي تتجاوز حدود النافذة. أكثر دقة ولكنه يتطلب ذاكرة أكبر.



المكتبات الشائعة في C++ لتحديد معدل الطلبات

على الرغم من أن المكتبة القياسية للغة C++ لا تحتوي على حلول جاهزة، إلا أن هناك مكتبات موثوقة:

توصيات