Table of Contents
فهم الحد من المبيت وأهمية ذلك في مراقبة حركة المرور على الشبكة
والحد من المعدل هو أسلوب أساسي لإدارة تدفق طلبات الشبكة بين العملاء والخواديم، إذ إن تنفيذ الحد الأقصى من الأسعار يتطلب اهتماما دقيقا بالأداء والتوافق والتفاعلات ذات المستويات الدنيا في النظام، مما يحد من استنفاد الموارد، ويقلل من سرعة الاحتياطات، ويكفل وصول جميع المستعملين إلى الخدمات، وفي جيم، يتطلب تطبيق حد أقصى للمعدلات اهتماما دقيقا بالأداء، والتوافق، والتفاعلات ذات المستويات الدنيا في النظام.
الحاجة إلى الحد من المعدل
وبدون الحد من المعدل، يمكن أن يحجب زبون واحد يسيئ التصرف أو تدفق حركة المرور المفاجئ خادماً، كما أن تطبيقات مثل بوابات نظام المعلومات الإدارية المتكامل، وخواديم الشبكة، والخدمات الحالية تعتمد على الحد من الأسعار لحماية الموارد الاحتياطية والحفاظ على جودة الخدمة، فعلى سبيل المثال، قد تحد نقطة النهاية للتوثيق من محاولات قطع الأشجار لمنع الهجمات التي تستهدف القوة الكدمية، في حين أن خدمات تدفق البيانات قد تحدد معدلات الرفض لضمان الاتساق بين جميع المشتركين في نظام النتائج.
المعدل المشترك للحد من الخوارزميات
وتتيح الخوارزميات المختلفة المبادلات بين الدقة واستخدام الذاكرة، ويساعد فهم هذه الخيارات المطورين على اختيار النهج الصحيح في حالة استخدامهم المحددة.
باكيت المكسور
(أ) إن خوارزمية الدلو المكسور هي واحدة من أكثر الناس شعبية، ويحتفظ الدلو بعدد ثابت من المكسور، ويستهلك كل طلب رمزاً واحداً؛ ويضاف الكسور بمعدل ثابت حتى يكتمل الدلو، وعندما يكون الدلو فارغاً، تُرفض الطلبات، ويسمح هذا الخوارزمي باختصار ازدحام حجم الدلو بينما يُنفِّذ متوسطاً طويلاً.
Leaky Bucket
ويطرح نموذج " الدلويات " التسربية على هيئة " FIFO " سؤالاً مفاده أن " الراكب " يطلب بسعر ثابت، وإذا كان الطلب قد تم قبوله، فإن الطلبات الجديدة تسقط، وهذا يخفف من حدة الانفجارات عن طريق تطبيق معدل ثابت للنواتج، وفي حين أنه يمنع التكرار كلياً، فإنه يمكن أن يُحدث حالات انتظار حتى يتم تجهيزها.
Fixed Window Counter
وهذا هو النهج الأبسط: تقسيم الوقت إلى نوافذ متفاوتة (مثلا، دقيقة واحدة) وعد الطلبات لكل نافذة، وإذا تجاوز العد عتبة أثناء النافذة الحالية، فإن الطلبات اللاحقة تُحجب، واستعادة النوافذ عند حد ثابت، والمثال في المادة الأصلية يستخدم نافذة ثابتة، والعقبة الرئيسية هي " المشكلة الكبيرة " : أي أن انفجار الطلبات قبل أن تنفجر الصواعق الحسنة بعد مرور فترة زمنية محددة، على نحو فعال.
Sliding Window Log
ويحتفظ هذا الأسلوب بسجل زمني لكل طلب (أو زبون) - عندما يصل طلب جديد، يزيل جميع المصابيح التي تزيد عن فترة النوافذ، ثم يتأكد من أن العدد المتبقي أقل من الحد، وهو دقيق جداً، ولكنه كثيف الذاكرة لأنه يخزن مر الزمن لكل طلب، وفي جيم، يمكن استخدام قائمة عازلة أو مترابطة من أجل الركض بكفاءة، ومن المثالي أن يكون سجل النافذة المزروعة عند الحاجة إلى حدود دقيقة للذاكرة.
Sliding Window Counter
ويستخدم نموذجاً مُثلى يجمع بين النوافذ الثابتة والاستقطاب، ويستخدم مضادين: واحد للنافذة الحالية والآخر للنافذة السابقة، ويقدر المعدل الفعال بأنه مجموع مرجح لكلا الواجهتين، مما يقلل من مشكلة الحدود دون تخزينها كل مرة، وهذا الخوارزمي يوفر توازناً جيداً بين الدقة والكفاءة في الذاكرة، ويستخدم هذا النهج العديد من أجهزة الحد من معدلات الإنتاج، بما فيها تلك الموجودة في البوابات الشعبية.
تصميم حدائق في جيم
ويتطلب بناء حد أقصى للمعدلات في C تصميما دقيقا حول إدارة الدولة، ومناولة الوقت، والسلامة في خيط، وتسير الأقسام التالية من خلال التنفيذ العملي.
المبادئ الأساسية: الدولة، ويندو، ولوك المقرر
كل حد للمعدلات يحتاج إلى الاحتفاظ بثلاثة قطع على الأقل من الدولة لكل عميل أو على الصعيد العالمي: منضدة للطلبات، ومؤخرة ترمز إلى بداية النافذة، والحد الأقصى المهيأ، وبالنسبة للنافذة الثابتة، فإن منطق القرار واضح:
- إذا كانت الفترة الحالية التي تُقلل من نافذة التشغيل أكبر من حجم النافذة أو مساوية له، أعيدوا تشغيل العداد وتحديث النافذة.
- وإذا كان المنصّر أقل من الحدّ، فإنّه يُسمح بالطلب؛ وإلاّ، إنكره.
وهذا النمط يظهر في المثال الأصلي على شكل دلو مكسيكي، رغم أن المادة تصنفه على نحو غير صحيح دلو مكسيكي، فهو في الواقع منضد للنوافذ الثابتة باستخدام العمليات الذرية.
الاختناق بين البساطة والجائزة
وبالنسبة للعديد من التطبيقات، فإن منافذ ثابتة كافية، وبالنسبة للاحتياجات العالية الدقة (مثلاً، مؤشرات الأداء المالي أو 5xxx-حد من)، تنظر في تنفيذ سجل النافذة المتدهورة أو منضدة نافذة مائلة، والمقايضة هي استخدام الذاكرة مقابل وقت التجهيز، وفي جيم، يمكنك تخزين الدولة الطرف المتداعية في جدول مائل للحد من السعر العالمي، أو استخدام هيكل ثابت للحد من أسعار السلع الأساسية الوحيدة.
نموذج الرمز: النافذة الثابتة مع العمليات الذرية
ويتوسع التنفيذ التالي على المستوى الأصلي بإضافة مواصفات حدودية دينامية ومناولة مناسبة للاحتكار باستخدام ساعة واحدة ، ويشمل أيضا جدولا بسيطا لإدارة عملاء متعددين (مصمما بصفيفة ثابتة من أجل الإرضاء).
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdatomic.h>
#include <string.h>
typedef struct {
atomic_ullong request_count;
struct timespec window_start;
} RateLimiter;
// Returns 1 if the request is allowed, 0 otherwise.
int allow_request(RateLimiter *rl, unsigned long long limit, unsigned long long window_sec) {
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now); // monotonic avoids clock adjustments
// Check if window has expired
if (now.tv_sec - rl->window_start.tv_sec >= window_sec) {
// Reset atomically - careful: window_start is not atomic, but we use a double‑check lock or re‑read
rl->window_start = now;
atomic_store_explicit(&rl->request_count, 0, memory_order_release);
}
unsigned long long count = atomic_load_explicit(&rl->request_count, memory_order_acquire);
if (count < limit) {
atomic_fetch_add_explicit(&rl->request_count, 1, memory_order_relaxed);
return 1;
}
return 0;
}
// Example: rate limiter for a single global endpoint
int main() {
RateLimiter rl = {0, {0, 0}};
const unsigned long long LIMIT = 10;
const unsigned long long WINDOW = 1; // 1 second
for (int i = 0; i < 15; i++) {
if (allow_request(&rl, LIMIT, WINDOW))
printf("Request %d: allowed\n", i+1);
else
printf("Request %d: denied\n", i+1);
struct timespec ts = {0, 100000000}; // 0.1 sec sleep
nanosleep(&ts, NULL);
}
return 0;
}
وتستخدم هذه النسخة [(FLT:2]] لتجنب المسائل التي تطرأ على ساعات النظام، ولا يكون منطق إعادة فتح النافذة ذريعاً تماماً: إذ يمكن أن تعيد خيوط متعددة في وقت واحد فتح النافذة إذا ما رأت حالة منتهية، وفي الإنتاج، ستحمي إعادة ضبطها بسلسلة من الفم أو حلقة من المقارنات والمبادلات، وبالنسبة لخادم واحد مصمم، فإن هذه المدونة تعمل بشكل صحيح.
معالجة مسألة السلامة من حيث الضبط
وكثيرا ما تكون خواديم الشبكة الحديثة متعددة الخيوط أو تستخدم حلقات أحداث تعالج الطلبات في خيوط متعددة، ويجب على الحد الأقصى للمعدل أن يعالج التعديلات المتزامنة بأمان.
استخدام الموسفات لحماية المهبل
ويغلف أبسط نهج أمني في نظام الخيط جميع القراء ويكتب إلى الدولة الحدية للمعدل داخل المتحول، وهذا يعمل جيدا عندما يُسمى الحد الأقصى للمعدلات بصورة متكررة أو عندما يكون القسم الحاسم قصيرا.
#include <pthread.h>
typedef struct {
pthread_mutex_t lock;
unsigned long long request_count;
time_t window_start;
} RateLimiterMutex;
void init_mutex(RateLimiterMutex *rl) {
pthread_mutex_init(&rl->lock, NULL);
rl->request_count = 0;
rl->window_start = time(NULL);
}
int allow_request_mutex(RateLimiterMutex *rl, unsigned long long limit, unsigned long long window_sec) {
pthread_mutex_lock(&rl->lock);
time_t now = time(NULL);
if (now - rl->window_start >= window_sec) {
rl->window_start = now;
rl->request_count = 0;
}
int allowed = 0;
if (rl->request_count < limit) {
rl->request_count++;
allowed = 1;
}
pthread_mutex_unlock(&rl->lock);
return allowed;
}
ويضمن هذا المتحول الوصول الحصري، ولكن يمكن أن يصبح الزعم عقبة تحت تأثير ناتج كبير، وبالنسبة للعديد من النظم العملية، فإنه مقبول لأن عملية تحديد المعدل سريعة جدا مقارنة بالتجهيز الفعلي للطلبات.
نُهج خالية من القفل مع الذرة C11
(أ) بالنسبة إلى أقصى أداء، استخدام التفاصيل الذرية كما في المثال السابق، غير أن معالجة النافذة المعادة للذرية هي غير قابلة للانتعاش، لأن عليك قراءة النوافذ الذرية وتحديثها إلى جانب المنضدة، ويتمثل أحد الحلول في تخزين وقت بدء تشغيل النافذة والعد إلى حد ما يصل إلى 64 درجة، مع تزييف فترات الاختراق العالية والعكس في القطع المنخفضة.
إدماج الحد من المعدل مع الشبكة الأولى/الشبكة
الحد الأقصى للمعدلات مفيد فقط عندما يكون مرتبطاً بحركة الشبكة الحقيقية في خادم الشبكة سي يمكنك أن تتصل بعامل الحد الأقصى عند قبول الطلب أو قبل تجهيز الطلب
استخدام شبكة الإنترنت لخدمة كبار المسؤولين
وفي خادم محرك في حالة ما باستخدام ، عادة ما يكون لديك خيط واحد (أو مجموعة صغيرة من الخيوط) يتولى مسؤولية I/O. ويمكن التذرع بمقياس السعر في حلقة الحدث قبل قراءة البيانات أو كتابتها، ويخزن كل زبون في جدول مطاطي يُعدّه عنوان IP أو مفتاح نظام API.() وعندما يصل طلب جديد، ينظر الخادم إلى الحد الأقصى للموكل()
typedef struct {
char ip[16];
RateLimiter rl;
} ClientEntry;
// Hash, lookup, etc. – omitted for brevity
// On connection:
ClientEntry *entry = lookup_or_create(ip);
if (allow_request(&entry->rl, LIMIT, WINDOW)) {
// process request
} else {
// send 429 and close
}
The Beej’s Guide to Network Programming] provides excellent examples of socket programming in C that can be combined with rate limiting.
معرض عملي: رُفعت رُهبة من طراز HTTP Server Snippet
(ب) النظر في حد أدنى من خادم برنامج نقل الأسلحة البشرية الذي يستند إلى أو . وبعد قبول اتصال، يقرأ الخادم الخط الأول لطلب شركة HTTP ويستخرج العميل IP (من ) ثم يفحص الحد الأقصى للمعدل، وإذا ما نُفي منه، فإنه يكتب رداً طفيفاً قدره 429 رداً ويغلق هذا النهج.
النظر في المسائل المتقدمة وتحقيق الحد الأمثل
كفاءة الذاكرة للعديد من العملاء
وعندما يكون الحد من المعدل هو العامل الواحد (مثلاً، لكل عنوان من عنوان IP)، يمكن أن ينمو جدول الحد الأقصى للمعدلات بدرجة كبيرة، واستخدام سياسة إخلاء وحدات خفض الانبعاثات لإزالة القيود التي تخص العملاء الذين لم يتواصلوا مؤخراً.() وتبسّط المكتبات مثل إدارة جداول العجلات في C. Alternatively، وتخزن الدولة في الذاكرة المشتركة لحواسيب الخدمة المتعددة الجوانب.
حدود المحميات وحمولات ساخنة
فالحديات المثبتة بقوة غير مرنة، إذ أن تصميم الحد الأقصى للمعدلات بحيث يصبح قراءته للحدود من ملف التشكيلة أو متغيرات البيئة، ولإعادة الشحن الساخنة (الحدود المستكملة دون إعادة تشغيل الخادم)، واستخدام متغير ذري عالمي أو نقطة مرجعية إلى هيكل تشكيلي يمكن أن يُعاد توزيعه بذرية.
الإدماج مع تنظيم الأراضي ورصدها
(د) أن تسجل كل طلب مُنكر إلى جانب هوية العميل وزمن الزمان، وهذه البيانات تساعد على ضبط الحدود وكشف التجاوزات، وأن تدمج مع نظم القياس مثل بروميثيوس عن طريق تصدير قيم مضادة أو كتابة إلى سجلات مُهيَّلة، ويمكن للخادمات استخدام الشعار أو حاجز للسجلات الجمركية.
الرواسب المشتركة وأفضل الممارسات
تجنب الوقت
(د) استخدام ساعة واحدة (]) بدلاً من أو (التي تستخدم وقت الجدار) ويمكن أن يقفز الجدار إلى الأمام أو إلى الخلف بسبب تعديلات النظام الوطني للأفضليات، مما يتسبب في ظهور نوافذ قبل الأوان أو لا على الإطلاق، ويضمن الوقت المغنطيسي للمضي قدماً بمعدل ثابت.
معالجة حواجز القفل
وحتى الساعات الأحادية يمكن أن يكون لها حل محدود، ففي النظم التي يمكن فيها أن تعيد القيم الثابتة على بعض البيئات المتجهة إلى الافتراض، تدرج فيها تسامحاً صغيراً أو تستخدم جهاز توقيت مختلط يستكمل كل ملي ثانية.
تصاريح الاختبار
وتختبر الوحدة المعدل الذي يحد من المنطق بشكل منفصل عن الشبكة الأولى/الشبكة، وتستخدم وظائف الساعة المحاكاة لتحفيز الوقت المتجاوز، وتتأكد من أنه بعد رفض الطلب التالي بالضبط، وبعد انتهاء النوافذ، يسمح مرة أخرى بالطلب، وينبغي أن تتحقق اختبارات الإجهاد التي تتضمن خيوط متعددة من أن الطلبات لا تتجاوز تنجح في النافذة.
خاتمة
إن تطبيق حد للمعدل في جيم مهارة عملية لأي مطور يعمل على تطبيقات الربط الشبكي، وقد يوفر اختيار النافذة المثبتة للخرافيم، والنافذة المنهارة، والبوكيت المكسور، أو الأسطول المسرب، الحد الأقصى للمبادلات بين الدقة والذاكرة والتعقيد، وذلك باستخدام نظام أحادي التوقيت، وإدارة الدولة القائمة على الترميز، والإدماج الدقيق مع نظام I/O.