تحديد معدل الطلبات في Java: المكتبات والخوارزميات والتنفيذ

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

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

ابدأ الدورة

تحديد معدل الطلبات في Java: من النظرية إلى التنفيذ العملي



تحديد معدل الطلبات (Rate Limiting) هو أحد الآليات الرئيسية للحماية وإدارة الحمل في الأنظمة الموزعة الحديثة. في Java، يتم حل هذه المشكلة على مستوى الأدوات المدمجة وكذلك باستخدام مكتبات متخصصة. في هذه المقالة، سنستعرض الخوارزميات الأساسية، والمكتبات الشائعة، ونقدم أمثلة عملية على الكود.



لماذا نحتاج إلى تحديد معدل الطلبات؟

يتيح تحديد معدل الطلبات ما يلي:

  • حماية API من إساءة الاستخدام (DDoS، تخمين كلمات المرور)
  • توزيع الحمل على الخادم الخلفي بشكل متساوٍ
  • الامتثال لاتفاقيات مستوى الخدمة (SLA)
  • منع تجاوز حصص الخدمات الخارجية


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

قبل اختيار المكتبة، من المهم فهم الخوارزميات الأساسية:



1. Token Bucket (Bucket4j، Guava)

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

// مثال بكود شبه حقيقيclass TokenBucket {    private int tokens;    private long lastRefillTime;    private final int capacity;    private final double refillRate; // رمز في الثانية

synchronized boolean tryConsume() { refill(); if (tokens > 0) { tokens--; return true; } return false; }}


2. Sliding Window Log

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



3. Fixed Window Counter

عداد بسيط لفاصل زمني ثابت (مثل 100 طلب في الدقيقة). يتم إعادة تعيينه كل دقيقة. عرضة للأحمال "الذروية" على حدود النافذة.



مكتبات Java الشائعة لتحديد معدل الطلبات



1. Bucket4j

Bucket4j هي مكتبة ناضجة تنفذ بالكامل خوارزمية Token Bucket. تدعم السيناريوهات الموزعة عبر Redis و Hazelcast و JCache. توفر واجهة برمجة تطبيقات Java 8+.

التثبيت (Maven):

<dependency>    <groupId>com.github.vladimir-bukhtoyarov</groupId>    <artifactId>bucket4j-core</artifactId>    <version>8.7.0</version></dependency>

مثال على الاستخدام:

import io.github.bucket4j.*;import java.time.Duration;

public class Bucket4jExample { public static void main(String[] args) { // إنشاء سلة: 10 رموز، إضافة رمز واحد في الثانية Bandwidth limit = Bandwidth.simple(10, Duration.ofSeconds(1)); Bucket bucket = Bucket4j.builder().addLimit(limit).build();

for (int i = 0; i < 15; i++) { if (bucket.tryConsume(1)) { System.out.println("تم تنفيذ الطلب #" + i); } else { System.out.println("تم رفض الطلب #" + i + " (تم تجاوز الحد)"); } } }}


2. Resilience4j RateLimiter

جزء من إطار العمل الشهير لتحمل الأخطاء. يعمل استنادًا إلى SemaphoreBasedRateLimiter أو AtomicRateLimiter. يتكامل بسهولة مع Spring Boot.

مثال على التكوين:

import io.github.resilience4j.ratelimiter.*;import java.time.Duration;

public class Resilience4jExample { public static void main(String[] args) { RateLimiterConfig config = RateLimiterConfig.custom() .limitForPeriod(5) // 5 طلبات .limitRefreshPeriod(Duration.ofSeconds(1)) // كل ثانية .timeoutDuration(Duration.ofMillis(100)) .build();

RateLimiter rateLimiter = RateLimiter.of("myService", config);

for (int i = 0; i < 8; i++) { Runnable task = R

توصيات