تحديد المعدل في Kotlin: المكتبات والتنفيذ

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

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

ابدأ الدورة

تحديد المعدل في Kotlin: المكتبات والاستراتيجيات والأمثلة العملية

\n\n

تحديد المعدل (تقييد سرعة الطلبات) هو آلية بالغة الأهمية لحماية واجهات API والخدمات المصغرة وتطبيقات الويب من الأحمال الزائدة وهجمات DDoS والارتفاعات المفاجئة في حركة المرور. في نظام Kotlin البيئي، الذي يعمل فوق JVM، توجد عدة مكتبات ناضجة تسمح بتنفيذ هذه المنطق بمرونة. في هذه المقالة، سنستعرض ثلاثة مناهج وأدوات رئيسية: Bucket4j، Resilience4j و RateLimiter المدمج من Guava.

\n\n

1. Bucket4j — تنفيذ متقدم لـ Token Bucket

\n\n

Bucket4j هي مكتبة Java متوافقة تمامًا مع Kotlin. وهي تنفذ خوارزمية Token Bucket (سلة الرموز) وتدعم التقييد المحلي والموزع (عبر Redis، Hazelcast، Infinispan).

\n\n

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

\n
    \n
  • تحديد عدد الرموز وسرعة إعادة تعبئتها.
  • \n
  • دعم "الانفجارات" (الارتفاعات القصيرة) من خلال تراكم الرموز.
  • \n
  • العمل في بيئة متعددة الخيوط دون أقفال.
  • \n
  • التكامل مع Spring Boot عبر المُشغّل bucket4j-spring-boot-starter.
  • \n
\n\n

مثال على محدد معدل بسيط في Kotlin:

\n
import io.github.bucket4j.Bandwidth\nimport io.github.bucket4j.Bucket\nimport io.github.bucket4j.Refill\nimport java.time.Duration\n\nfun main() {\n    // 10 طلبات في الدقيقة، مع إمكانية تراكم حتى 20 رمزًا\n    val limit = Bandwidth.classic(20, Refill.greedy(10, Duration.ofMinutes(1)))\n    val bucket = Bucket.builder()\n        .addLimit(limit)\n        .build()\n\n    // التحقق من توفر الرمز\n    if (bucket.tryConsume(1)) {\n        println("✅ الطلب مسموح به")\n    } else {\n        println("❌ تم تجاوز الحد، حاول لاحقًا")\n    }\n}
\n\n

للسيناريو الموزع (على سبيل المثال، عدة نسخ من الخدمة المصغرة) استخدم Bucket4j مع Redis:

\n
import io.github.bucket4j.distributed.proxy.ProxyManager\nimport io.github.bucket4j.redis.lettuce.Bucket4jLettuce\nimport io.lettuce.core.RedisClient\n\nval redisClient = RedisClient.create("redis://localhost:6379")\nval proxyManager: ProxyManager<String> = Bucket4jLettuce\n    .builder(redisClient)\n    .build()\n\nval bucket = proxyManager.builder()\n    .build("user:123", Bucket4jConfiguration(\n        Bandwidth.classic(100, Refill.intervally(100, Duration.ofMinutes(1)))\n    ))\n
\n\n

2. Resilience4j — RateLimiter كجزء من Circuit Breaker

\n\n

Resilience4j هي مكتبة مرونة شائعة لـ Java/Kotlin، لا تشمل فقط محدد المعدل، بل أيضًا circuit breaker و retry و bulkhead. تعمل وحدة RateLimiter الخاصة بها بناءً على خوارزمية Sliding Window (النافذة المنزلقة).

\n\n

الميزات:

\n
    \n
  • تكامل سهل مع coroutines في Kotlin عبر دوال suspend.
  • \n
  • تحديد فترة النافذة وحد الطلبات.
  • \n
  • معالجة مرنة للأخطاء: إرجاع استثناء، fallback، أو انتظار.
  • \n
\n\n

مثال مع coroutines:

\n
import io.github.resilience4j.ratelimiter.RateLimiter\nimport io.github.resilience4j.ratelimiter.RateLimiterConfig\nimport io.github.resilience4j.kotlin.ratelimiter.awaitRateLimiter\nimport java.time.Duration\nimport kotlinx.coroutines.runBlocking\n\nval config = RateLimiterConfig.custom()\n    .limitForPeriod(10)           // 10 طلبات\n    .limitRefreshPeriod(Duration.ofSeconds(1)) // خلال ثانية واحدة\n    .timeoutDuration(Duration.ofMillis(500))   // مهلة الانتظار\n    .build()\n\nval rateLimiter = RateLimiter.of("api-limiter", config)\n\nsuspend fun fetchData(): String {\n    return awaitRateLimiter(rateLimiter) {\n        // استدعاء API الخاص بك\n        "تم الحصول على البيانات"\n    }\n}\n\nfun main() = runBlocking {\n    val result = fetchData()\n    p                    

توصيات