الحد من المعدل في إدارة API
September 16, 2022
مع تطور الإنترنت، بدأت المزيد والمزيد من الشركات في تبني الحلول السحابية الأصلية والخدمات المصغرة. ومع ذلك، بسبب الخصائص التقنية للحلول السحابية الأصلية والخدمات المصغرة، أصبح علينا إدارة مئات الخدمات المختلفة في نفس الوقت. لذلك، لا نحتاج فقط إلى التفكير في تشغيل النظام بأكمله بسلاسة، ولكن أيضًا علينا الاهتمام بأمان واستقرار كل خدمة تعتمد على واجهات برمجة التطبيقات (API).
يعد تحديد معدل الطلبات (Rate Limiting) أحد الحلول الأكثر أهمية لضمان استقرار الخدمات المعتمدة على واجهات برمجة التطبيقات. ومع ذلك، سيصبح التطبيق ثقيلًا للغاية إذا كانت كل خدمة تحتاج إلى تحديد معدل الطلبات بشكل منفصل. كبوابة لدخول وخروج كل حركة المرور في العالم الرقمي، تساعد بوابة واجهات برمجة التطبيقات (API Gateway) في تحقيق إدارة موحدة لجميع الخدمات. وهي تحمي التشغيل المستقر لخدمات النظام. تشرح هذه المقالة كيفية تحقيق تحديد معدل الطلبات من خلال بوابة واجهات برمجة التطبيقات Apache APISIX وتصف استراتيجيات وتقنيات تحديد معدل الطلبات.
ما هو تحديد معدل الطلبات
تحديد معدل الطلبات هو استراتيجية للتحكم في حركة مرور الإنترنت وتعظيم الإنتاجية. باستخدام تحديد معدل الطلبات، يتم السماح فقط للطلبات التي تلتزم بقيود معينة بالوصول إلى النظام؛ بينما يتم وضع أي طلبات إضافية تتجاوز هذه القيود في قائمة الانتظار، أو تخفيض أولويتها، أو حتى رفضها أو التخلي عنها. كما يحمي تحديد معدل الطلبات النظام من الحوادث غير المتوقعة مثل الارتفاعات المفاجئة في حركة المرور أو الهجمات الخبيثة، مما يمكن النظام من تقديم خدمات متسقة ومستقرة.
على سبيل المثال، عندما يسبب تغريدة شائعة ارتفاعًا مفاجئًا في حركة المرور، يتعين على تويتر تطبيق تحديد معدل الطلبات لمنع تعطل الخوادم بسبب الحمل الزائد.
لماذا تحتاج إليه
أولاً، دعونا نلقي نظرة على بعض حالات الاستخدام البسيطة في حياتنا اليومية التي تستخدم تحديد معدل الطلبات. على سبيل المثال، يمكن للمعالم السياحية بيع عدد معين فقط من التذاكر في العطلات. أيضًا، عادة ما نحتاج إلى الحجز مسبقًا أو الانتظار لفترة طويلة قبل الاستمتاع بالطعام في المطاعم الشهيرة.
في بوابة واجهات برمجة التطبيقات، يقدم تحديد معدل الطلبات العديد من الفوائد. سيضع تحديد معدل الطلبات بعض القيود على خدماتنا المعتمدة على واجهات برمجة التطبيقات، مما يضمن تشغيلها بسلاسة ويتجنب الخسائر غير الضرورية الناتجة عن تعطل الخوادم بسبب الارتفاعات المفاجئة في حركة المرور. هنا قمنا بإدراج خمسة قيود عملية مختلفة:
- تحديد معدل الطلبات.
- تحديد عدد الطلبات لكل وحدة زمنية.
- تأخير الطلبات.
- رفض طلبات العميل.
- تحديد معدل الاستجابة.
متى تحتاج إليه
بالإضافة إلى التعريف والمصادقة، يمكن أن يزيد تحديد معدل الطلبات من فوائده ويحسن توفر النظام بالطرق التالية:
- تجنب الهجمات الخبيثة.
- ضمان التشغيل المستقر للنظام وتجنب تعطل الخوادم بسبب الارتفاعات المفاجئة في حركة المرور.
- منع تعطل الخوادم بسبب الارتفاعات المفاجئة في الطلبات الناتجة عن أخطاء في الخدمات العلوية أو السفلية.
- تجنب استدعاءات واجهات برمجة التطبيقات المكلفة بشكل متكرر.
- تقليل الهدر غير الضروري للموارد عن طريق تحديد تكرار استدعاءات واجهات برمجة التطبيقات.
النظرية وراء تحديد معدل الطلبات
في الأقسام السابقة، قدمنا فوائد تحديد معدل الطلبات. في هذا القسم، دعونا نتعرف على النظريات الكامنة وراءه! يتم تحقيق التنفيذ منخفض المستوى لتحديد معدل الطلبات من خلال خوارزميات محددة. تشمل الخوارزميات الشائعة الاستخدام:
- خوارزمية العداد
- النافذة الثابتة
- النافذة المنزلقة
- خوارزمية الدلو المتسرب
- خوارزمية دلو الرموز
خوارزمية العداد
خوارزمية العداد سهلة الفهم نسبيًا، ولها نوعان:
النوع الأول هو خوارزمية النافذة الثابتة، التي تحافظ على عداد في وحدة زمنية ثابتة وسيتم إعادة تعيين العداد إلى الصفر إذا اكتشفت أن الوحدة الزمنية قد انقضت.
النوع الثاني هو خوارزمية النافذة المنزلقة، وهي تحسين يعتمد على النوع الأول؛ وتشمل الخطوات التالية:
- تقسيم الوحدات الزمنية إلى عدة فترات (يُطلق على كل منها كتلة).
- كل كتلة لديها عداد؛ أي طلبات واردة ستزيد العداد بمقدار 1.
- بعد فترة زمنية محددة، تتحرك هذه النافذة الزمنية للأمام بمقدار كتلة واحدة.
- سيتم حساب إجمالي الطلبات في تلك النافذة الزمنية عن طريق جمع جميع العدادات للكتل في النافذة الزمنية؛ إذا تجاوز إجمالي الطلبات القيد، سيتم إسقاط جميع الطلبات في تلك النافذة الزمنية.
خوارزمية الدلو المتسرب
لنفترض وجود دلو متسرب؛ ستقف جميع الطلبات في قائمة الانتظار أولاً، ثم سيرسل الدلو المتسربها بمعدل ثابت.
إذا تجاوزت الطلبات سعة الدلو، سيتخلى النظام عن أي طلبات زائدة ويرفضها. يمكن لخوارزمية الدلو المتسرب تحديد معدل الطلبات وضمان إرسال جميع الطلبات بمعدل ثابت، مما يخلق وضعًا سهل الدخول وصعب الخروج.
الخطوات الأساسية في هذه الخوارزمية:
- يتم تخزين جميع الطلبات في دلو بحجم ثابت.
- سيرسل الدلو الطلبات بمعدل ثابت حتى يصبح الدلو فارغًا.
- عندما يكون الدلو ممتلئًا، سيتخلى النظام عن أي طلبات إضافية.
خوارزمية دلو الرموز
تتكون خوارزمية دلو الرموز من جزأين: توليد الرموز والتخلص منها. يولد دلو الرموز رموزًا بمعدل ثابت ويخزنها في دلو تخزين ثابت. عندما تمر طلبة عبر دلو الرموز، تأخذ الطلبة رمزًا واحدًا أو أكثر. عندما يصل عدد الرموز في دلو الرموز إلى السعة القصوى، سيتخلى دلو الرموز عن الرموز التي تم توليدها حديثًا. أيضًا، سيرفض دلو التخزين الطلبات الواردة إذا لم يتبقى أي رمز.
الخطوات الأساسية لخوارزمية دلو الرموز:
- سيولد دلو الرموز رموزًا بمعدل ثابت ويضعها في دلو التخزين.
- إذا كان دلو الرموز ممتلئًا، سيتم التخلص من الرموز التي تم توليدها حديثًا مباشرة. عندما تصل طلبة، تأخذ رمزًا واحدًا أو أكثر من دلو التخزين.
- إذا لم يتبقى أي رمز في دلو الرموز، سيرفض النظام أي طلبات واردة.
تحقيق تحديد معدل الطلبات عبر بوابة واجهات برمجة التطبيقات
إذا كانت هناك حاجة لإدارة عدد قليل فقط من الخدمات المعتمدة على واجهات برمجة التطبيقات، يمكننا استخدام خوارزميات تحديد معدل الطلبات مباشرة في الخدمة. على سبيل المثال، إذا كنت تستخدم Go لتطوير نظامك، فسيستخدم tollbooth
أو golang.org/x/time/rate
لتنفيذ الخوارزميات. إذا كنت تستخدم Lua، يمكنك استخدام وحدات NGINX مثل limit_req
، limit_conn
، وLua-resty-limit-traffic
لتنفيذ الخوارزميات.
إذا تم تنفيذ تحديد معدل الطلبات بناءً على خدمة معتمدة على واجهات برمجة التطبيقات، سيتم تعيين قيود تحديد معدل الطلبات من قبل الخدمة نفسها، وقد يكون لكل خدمة قيود مختلفة. ستؤدي هذه القيود والاختلافات إلى مشاكل إدارية إذا زاد عدد الخدمات المعتمدة على واجهات برمجة التطبيقات بشكل كبير. عندها، لن نتمكن من استخدام بوابة واجهات برمجة التطبيقات لإدارة جميع خدمات واجهات برمجة التطبيقات بشكل موحد. يمكنك أيضًا تنفيذ ميزات أعمال غير مرتبطة على البوابة، مثل التعريف، المصادقة، التسجيل، المراقبة، إلخ. عند استخدام بوابة واجهات برمجة التطبيقات لحل مشاكل تحديد معدل الطلبات.
Apache APISIX هي بوابة سحابية أصلية ديناميكية وفعالة وعالية الأداء. يدعم APISIX حاليًا أكثر من 80 مكونًا إضافيًا مختلفًا، وقد بنى بالفعل نظامًا بيئيًا غنيًا. يمكننا إدارة حركة مرور الخدمات المعتمدة على واجهات برمجة التطبيقات باستخدام مكونات APISIX الإضافية، بما في ذلك limit-req
، limit-conn
، وlimit-count
. هنا، سأشارك حالة استخدام لتوضيح كيفية استخدام مكونات تحديد معدل الطلبات في APISIX.
لنفترض وجود خدمة معتمدة على واجهات برمجة التطبيقات (/user/login
) تساعد المستخدمين على تسجيل الدخول. لتجنب الهجمات الخبيثة واستنزاف الموارد، نحتاج إلى تمكين وظيفة تحديد معدل الطلبات لضمان استقرار النظام.
تحديد الطلبات
يحدد المكون الإضافي limit-req
معدل الطلبات، ويستخدم خوارزمية الدلو المتسرب، ونقوم بربطه بالمسارات المقابلة أو العملاء المحددين.
يمكننا استخدام واجهة برمجة التطبيقات الإدارية لـ APISIX مباشرة لإنشاء مثل هذا المسار:
X-API-Key
هو admin_key في تكوين APISIX.
curl http://127.0.0.1:9080/apisix/admin/routes/1 \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"methods": ["POST"],
"uri": "/user/login",
"plugins": {
"limit-req": {
"rate": 3,
"burst": 2,
"rejected_code": 503,
"key": "remote_addr"
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:1980": 1
}
}
}'
معنى هذا المقتطف: نستخدم عنوان IP العميل كشرط لتحديد معدل الطلبات.
- إذا كان معدل الطلبات أقل من 3 طلبات/ثانية (
rate
)، فإن الطلب طبيعي؛ - إذا كان معدل الطلبات أكبر من 3 طلبات/ثانية وأقل من 5 طلبات/ثانية (
rate+burst
)، سنخفض أولوية هذه الطلبات الزائدة؛ - إذا كان معدل الطلبات أكبر من 5 طلبات/ثانية (
rate+burst
)، سيتم إرجاع أي طلبات تتجاوز الحد الأقصى مع رمز HTTP 503.
إذا كنت ترغب في معرفة المزيد عن limit-req
، يرجى الاطلاع على هذا المستند: APISIX limit-req
تحديد الاتصالات
يحدد المكون الإضافي limit-conn
الطلبات المتوازية (أو الاتصالات المتوازية). فيما يلي مقتطف كود لتمكين هذا المكون الإضافي لـ /user/login
:
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"methods": ["POST"],
"uri": "/user/login",
"id": 1,
"plugins": {
"limit-conn": {
"conn": 3,
"burst": 2,
"default_conn_delay": 0.1,
"rejected_code": 503,
"key": "remote_addr"
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:1980": 1
}
}
}'
معنى هذا المقتطف: نستخدم عنوان IP العميل كشرط لتحديد الاتصالات المتوازية.
- إذا كانت الاتصالات المتوازية لنفس العميل أقل من 3 (
conn
)، فإنها تستجيب بحالة طبيعية 200؛ - إذا كانت الاتصالات المتوازية أكبر من 3 (
conn
) ولكن أقل من 5 (conn+burst
)، سنبطئ الطلبات الزائدة، ونزيد وقت التأخير بمقدار 0.1 ثانية؛ - إذا كانت الاتصالات المتوازية أكبر من 5 (
conn+burst
)، سيتم رفض هذا الطلب وإرجاع رمز HTTP 503.
إذا كنت ترغب في معرفة المزيد عن limit-conn
، يرجى الاطلاع على هذا المستند: APISIX limit-conn
تحديد العدد
يشبه المكون الإضافي limit-count
تحديد معدل الطلبات في واجهة برمجة التطبيقات الخاصة بـ Github؛ سيحدد عدد الطلبات الإجمالية في فترة زمنية محددة ويرجع عدد الطلبات المتبقية في رأس HTTP. فيما يلي مقتطف كود لتمكين هذا المكون الإضافي لـ /user/login
:
curl -i http://127.0.0.1:9080/apisix/admin/routes/1 \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"uri": "/user/login",
"plugins": {
"limit-count": {
"count": 3,
"time_window": 60,
"rejected_code": 503,
"key": "remote_addr",
"policy": "local"
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:9001": 1
}
}
}'
معنى هذا المقتطف: نستخدم عنوان IP العميل كشرط لتحديد عدد الطلبات؛ يتم حفظ العداد محليًا في الذاكرة.
إذا كان هناك أكثر من 3 (count
) طلبات خلال 60 ثانية (time_window
)، سيتم إرجاع الطلبات التي يتم إرسالها أكثر من 3 مرات مع رمز HTTP 503 (rejected_code
).
إذا كنت ترغب في معرفة المزيد عن limit-count
، يرجى الاطلاع على هذا المستند: APISIX limit-count
مزايا تحديد معدل الطلبات في Apache APISIX
عندما نستخدم NGINX لإدارة حركة المرور، إذا تسبب عدد طلبات واجهات برمجة التطبيقات في ارتفاع مفاجئ في حركة المرور، فإن NGINX سيكشف عن نقاط ضعفه، وأحد هذه النقاط هو عدم قدرته على تحميل التكوينات ديناميكيًا. من ناحية أخرى، يمكن لخدمات APISIX (مثل Route وService) دعم إعادة تحميل التكوينات الساخنة. حتى إذا كان هناك ارتفاع مفاجئ في حركة المرور، يمكن لـ APISIX تعديل تحديد معدل الطلبات وتكوينات المكونات الإضافية الأمنية الأخرى على الفور. بفضل آلية المراقبة في etcd، تسمح لـ APISIX بتحديث طبقة البيانات في غضون أجزاء من الثانية دون إعادة تحميل الخدمات.
بالإضافة إلى ذلك، يدعم APISIX أيضًا تحديد معدل الطلبات على مستوى الكتلة. على سبيل المثال، يمكننا استخدام limit-count
لتعديل تكوين policy
إلى redis
أو redis-cluster
. وبالتالي، يمكننا تحديد معدلات الطلبات على مستوى الكتلة عن طريق مشاركة نتائج الحساب بين عقد APISIX المختلفة.
كـ DevOps، فإن استخدام لوحة تحكم رسومية لإدارة جميع خدمات واجهات برمجة التطبيقات سيعزز الإنتاجية. يوفر APISIX لوحة تحكم مرئية dashboard لجعل تعديل تكوينات واجهات برمجة التطبيقات أكثر ملاءمة.
الخلاصة
تحديد معدل الطلبات هو حاجة شائعة في سيناريوهات الأعمال الفعلية، وهو طريقة حاسمة لحماية النظام من الارتفاعات المفاجئة في حركة المرور وضمان تشغيله بسلاسة. تحديد معدل الطلبات هو مجرد جزء واحد من إدارة خدمات واجهات برمجة التطبيقات؛ يمكننا أيضًا استخدام العديد من التقنيات الأخرى لتوفير دعم أمني قوي وتحسين تجربة المستخدم.