Rust में रेट लिमिटिंग: लाइब्रेरीज़ और टूल्स का अवलोकन
रेट लिमिटिंग (अनुरोध आवृत्ति को सीमित करना) — वेब सेवाओं को ओवरलोड, DDoS हमलों और दुरुपयोग से बचाने के लिए एक महत्वपूर्ण तंत्र है। Rust इकोसिस्टम में रेट लिमिटिंग को लागू करने के लिए कई परिपक्व लाइब्रेरीज़ उपलब्ध हैं: निम्न-स्तरीय एल्गोरिदम से लेकर लोकप्रिय वेब फ्रेमवर्क के लिए तैयार मिडलवेयर तक। इस लेख में हम तीन प्रमुख दृष्टिकोणों पर विचार करेंगे: governor (GCRA एल्गोरिदम), leaky-bucket (लीकी बकेट) और Actix/Axum के साथ एकीकरण।
1. governor लाइब्रेरी — GCRA एल्गोरिदम
governor — Rust में सबसे लोकप्रिय रेट लिमिटिंग लाइब्रेरी है, जो जेनेरिक सेल रेट एल्गोरिदम (GCRA) पर आधारित है। यह एल्गोरिदम नेटवर्क प्रोटोकॉल में उपयोग किया जाता है और पीक लोड और औसत गति दोनों को लचीले ढंग से कॉन्फ़िगर करने की अनुमति देता है।
मुख्य विशेषताएं:
- एकाधिक कुंजियों का समर्थन (IP, User-Agent, API-कुंजी)
- कॉन्फ़िगरेबल बर्स्ट (ट्रैफ़िक का उछाल)
tokioयाasync-stdके माध्यम से एसिंक्रोनस कार्य- बिना लॉक के थ्रेड-सुरक्षा
बर्स्ट 20 के साथ प्रति मिनट 100 अनुरोधों की सीमा सेट करने का उदाहरण:
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. वेब फ्रेमवर्क के लिए मिडलवेयर
तैयार मिडलवेयर 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")), }}