إطار عمل Go شامل لتنفيذ واختبار خوارزميات تحديد المعدل. يوفر هذا المشروع تطبيقات نموذجية لاستراتيجيات تحديد المعدل المختلفة بالإضافة إلى أدوات خادم-عميل للتحقق والمعايرة.
يتكون هذا المشروع من:
- عميل الاختبار: يرسل طلبات بمعدلات قابلة للتكوين
- خادم الاختبار: يعمل كخادم صدى
- أمثلة الخوارزميات: 4 تطبيقات مختلفة لتحديد المعدل
- قم بتشغيل الخادم:
go run server/main.go -protocol tcp -port 8080- في محطة طرفية أخرى، قم بتشغيل العميل:
go run main.go -server localhost:8080 -rate 100 -duration 30s# بدء خادم TCP مع تسجيل مفصل
go run server/main.go -protocol tcp -port 8080 -verbose
# اختبار معدل عالي (1000 طلب/ثانية، 10 اتصالات)
go run main.go -rate 1000 -connections 10 -duration 60s
# اختبار بروتوكول UDP
go run server/main.go -protocol udp -port 9090
go run main.go -protocol udp -server localhost:9090 -rate 500.
├── main.go # عميل الاختبار
├── server/
│ └── main.go # خادم الاختبار
└── sample/
├── token_bucket/ # تطبيق دلو الرموز
├── fixed_window/ # تطبيق النافذة الثابتة
├── sliding_window/ # تطبيق النافذة المنزلقة
└── concurrent/ # تطبيق آمن للتزامن
عميل اختبار تحديد المعدل عالي الأداء.
الميزات:
- دعم بروتوكولي TCP/UDP
- اتصالات متزامنة متعددة (TCP فقط)
- حجم رسالة قابل للتخصيص
- عرض الإحصائيات في الوقت الفعلي
خيارات سطر الأوامر:
-server string # عنوان الخادم (الافتراضي "localhost:8080")
-protocol string # البروتوكول: tcp أو udp (الافتراضي "tcp")
-rate int # الرسائل في الثانية (الافتراضي 100)
-duration duration # مدة الاختبار (الافتراضي 10s)
-connections int # الاتصالات المتزامنة، TCP فقط (الافتراضي 1)
-size int # حجم الرسالة بالبايتات (الافتراضي 64)مثال على المخرجات:
بدء عميل اختبار تحديد المعدل
البروتوكول: tcp
الخادم: localhost:8080
المعدل: 1000 رسالة/ثانية
المدة: 30s
الاتصالات: 10
حجم الرسالة: 64 بايت
--- إحصائيات الاختبار ---
المدة: 30s
الرسائل المرسلة: 30000
الرسائل الناجحة: 29850
الرسائل الفاشلة: 150
معدل النجاح: 99.50%
المعدل الفعلي: 1000.00 رسالة/ثانية
خادم بسيط يردد الرسائل المستلمة.
الميزات:
- دعم بروتوكولي TCP/UDP
- اتصالات عملاء متعددة متزامنة
- عرض الإحصائيات كل 5 ثوان
- إيقاف تشغيل سلس (Ctrl+C)
خيارات سطر الأوامر:
-protocol string # البروتوكول: tcp أو udp (الافتراضي "tcp")
-port int # منفذ الاستماع (الافتراضي 8080)
-verbose # تمكين التسجيل المفصلمثال على عرض الإحصائيات:
[15:30:45] مستلم: 5023، معالج: 5023، أخطاء: 0، المعدل: 1004.60 رسالة/ثانية
[15:30:50] مستلم: 10089، معالج: 10089، أخطاء: 0، المعدل: 1013.20 رسالة/ثانية
الميزات:
- يسمح بمعالجة الدفعات
- يحافظ على المعدل المتوسط مع السماح بارتفاعات قصيرة المدى
- كفاءة في الذاكرة
مثال الاستخدام:
limiter := NewTokenBucket(100, 10) // السعة 100، إعادة التعبئة 10/ثانية
if limiter.Allow() {
// معالجة الطلب
}حالات الاستخدام:
- تحديد معدل API
- التحكم في عرض النطاق الترددي للشبكة
- عندما تكون حركة المرور المتقطعة مقبولة
الميزات:
- تنفيذ بسيط
- استخدام أدنى للذاكرة
- مشاكل الحدود عند حواف النافذة
مثال الاستخدام:
limiter := NewFixedWindowLimiter(1000, time.Minute) // 1000 طلب في الدقيقة
if limiter.Allow() {
// معالجة الطلب
}حالات الاستخدام:
- عندما تكون هناك حاجة لتحديد معدل بسيط
- الأداء له الأولوية على الدقة
الميزات:
- تحديد معدل أكثر دقة
- يحل مشاكل حدود النافذة الثابتة
- استخدام ذاكرة أعلى قليلاً
مثال الاستخدام:
limiter := NewSlidingWindowLimiter(100, time.Minute) // 100 طلب في الدقيقة
if limiter.Allow() {
// معالجة الطلب
}حالات الاستخدام:
- عندما يكون تحديد المعدل الدقيق مطلوباً
- العدالة مهمة
الميزات:
- أداء عالي مع العمليات الذرية
- دعم البيئة الموزعة
- مثال على وسيط HTTP
استخدام وسيط HTTP:
// تحديد المعدل لكل مستخدم
userLimiters := &UserRateLimiters{
limiters: make(map[string]*ConcurrentTokenBucket),
limit: 100, // 100 طلب/دقيقة لكل مستخدم
}
mux := http.NewServeMux()
mux.HandleFunc("/api/", handler)
// تطبيق الوسيط
http.ListenAndServe(":8080", RateLimitMiddleware(userLimiters)(mux))مقارنة الخوارزميات (قيم مرجعية):
| الخوارزمية | الإنتاجية | استخدام الذاكرة | الميزات |
|---|---|---|---|
| دلو الرموز | عالية | منخفض | دعم الدفعات |
| النافذة الثابتة | الأعلى | الأدنى | بسيط |
| النافذة المنزلقة | متوسطة | متوسط | دقيق |
| المتزامن | عالية | منخفض | محسّن للتزامن |
# اختبار تحديد معدل خادم API (1000 طلب/ثانية، 5 دقائق)
go run main.go -server api.example.com:443 -rate 1000 -duration 5m -connections 50# اختبار زيادة الحمل التدريجي
for rate in 100 500 1000 2000 5000; do
echo "اختبار المعدل: $rate طلب/ثانية"
go run main.go -rate $rate -duration 1m
sleep 10
done# قياس عرض النطاق الترددي بحجم رسالة كبير
go run main.go -size 1024 -rate 1000 -protocol udp-
خطأ "Too many open files"
# زيادة حد واصف الملف ulimit -n 65536
-
أخطاء الاتصال عند معدلات عالية
- اضبط معامل
-connections - تحقق من أحجام المخزن المؤقت من جانب الخادم
- اضبط معامل
-
فقدان حزم UDP
- قلل المعدل أو حجم الرسالة
- اضبط حجم مخزن UDP المؤقت للنواة
# بناء العميل
go build -o rate-limit-client main.go
# بناء الخادم
go build -o rate-limit-server server/main.go# تشغيل اختبارات الوحدة
go test ./...
# تشغيل المعايير
go test -bench=. ./sample/...- أنشئ حزمة جديدة في دليل
sample/ - نفذ واجهة
RateLimiter:type RateLimiter interface { Allow() bool AllowN(n int) bool }
- أضف الاختبارات والمعايير
رخصة MIT
طلبات السحب مرحب بها. للتغييرات الكبيرة، يرجى فتح قضية أولاً لمناقشة ما تريد تغييره.