تحديد معدل الطلبات في Rust: مكتبات governor و leaky-bucket و middleware لخوادم الويب

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

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

ابدأ الدورة

تحديد معدل الطلبات في Rust: نظرة عامة على المكتبات والأدوات



تحديد معدل الطلبات (Rate limiting) هو آلية حاسمة لحماية خدمات الويب من الأحمال الزائدة وهجمات DDoS وسوء الاستخدام. في نظام Rust البيئي، تتوفر عدة مكتبات ناضجة لتنفيذ تحديد معدل الطلبات: من الخوارزميات منخفضة المستوى إلى middleware الجاهزة لأطر الويب الشائعة. في هذه المقالة، سنستعرض ثلاثة أساليب رئيسية: governor (خوارزمية GCRA)، leaky-bucket (الدلو المثقوب) والتكامل مع Actix/Axum.



1. مكتبة governor — خوارزمية GCRA



governor هي أشهر مكتبة لتحديد معدل الطلبات في Rust، وهي مبنية على خوارزمية معدل الخلايا العامة (GCRA). تُستخدم هذه الخوارزمية في بروتوكولات الشبكات وتسمح بضبط مرن لكل من الحمل الأقصى ومتوسط السرعة.



الإمكانيات الرئيسية:

  • دعم مفاتيح متعددة (IP، User-Agent، مفتاح API)
  • انفجار قابل للتخصيص (burst)
  • عمل غير متزامن عبر tokio أو async-std
  • أمان خيوط بدون أقفال


مثال لإعداد حد 100 طلب في الدقيقة مع انفجار 20:



use governor::{DefaultKeyedRateLimiter, Quota, RateLimiter};use std::num::NonZeroU32;use std::time::Duration;

#[tokio::main]async fn main() { // الحد: 100 طلب في الدقيقة، انفجار 20 let quota = Quota::with_period(Duration::from_secs(60)) .unwrap() .allow_burst(NonZeroU32::new(20).unwrap()); let limiter = DefaultKeyedRateLimiter::::new(quota); // التحقق للمستخدم "user123" match limiter.check_key("user123") { Ok(_) => println!("الطلب مسموح به"), Err(_) => println!("تم تجاوز الحد، الحالة 429"), }}


2. مكتبة leaky-bucket — الدلو المثقوب



خوارزمية الدلو المثقوب مطبقة في مكتبة leaky-bucket. إنها تحاكي دلو ماء يمتلئ بالطلبات ويتسرب بمعدل ثابت. مناسبة لتنعيم الأحمال الذروة.



الميزات:

  • نموذج بسيط: دلو بسعة N من الطلبات
  • معدل التسرب — عدد الطلبات في الثانية
  • دعم الحد الأقصى للطلبات المنتظرة


مثال مع حد 5 طلبات في الثانية ودلو بسعة 10:



use leaky_bucket::RateLimiter;use std::time::Duration;

#[tokio::main]async fn main() { let limiter = RateLimiter::builder() .initial(10) // العدد الأولي من الرموز .max(10) // الحجم الأقصى للدلو .interval(Duration::from_millis(200)) // التجديد كل 200 مللي ثانية .build(); // محاولة الحصول على رمز if limiter.try_acquire().is_ok() { println!("تمت معالجة الطلب"); } else { println!("الدلو فارغ، تم الرفض"); }}


3. Middleware لأطر الويب



تعمل middleware الجاهزة على تبسيط دمج تحديد معدل الطلبات في خوادم الويب المبنية على Actix و Axum بشكل كبير.



Actix + governor



use actix_web::{web, App, HttpServer, HttpRequest, HttpResponse, middleware::from_fn};use governor::{DefaultKeyedRateLimiter, Quota};use std::num::NonZeroU32;use std::time::Duration;

async fn rate_limit_middleware( req: HttpRequest, limiter: web::Data<DefaultKeyedRateLimiter<String>>,) -> Result<HttpResponse, actix_web::Error> { let client_ip = req.peer_addr() .map(|addr| addr.to_string()) .unwrap_or_default(); match limiter.check_key(&client_ip) { Ok(_) => Ok(HttpResponse::Ok().body("OK")), Err(_) => Ok(HttpResponse::TooManyRequests().body("Too Many Requests")), }}

توصيات