مصادر الأحداث والمشغّلات
مصادر الأحداث والمشغّلات
دالة Lambda في حالة خمول تام حتى يُستدعى تنفيذها. تُصنِّف AWS نماذج الاستدعاء في ثلاثة أنواع: متزامن (API Gateway وALB ومشغّلات Cognito)، وغير متزامن (أحداث S3 وSNS وEventBridge)، واستطلاع تدفقي (SQS وKinesis وDynamoDB Streams). يختلف كل نموذج في دلالات إعادة المحاولة ومعالجة الأخطاء وسلوك ضغط الظهر. اختيار النموذج الخاطئ هو الجذر الأساسي لمعظم أخطاء الإنتاج في الأنظمة المدفوعة بالأحداث.
API Gateway — نقطة الدخول HTTP المتزامنة
يُعدّ API Gateway (HTTP API v2 أو REST API v1) المشغِّل المتزامن السائد. يظل المُستدعي محجوبًا في انتظار الرد؛ وبالتالي يصبح حدّ التزامن في Lambda هو سقف الإنتاجية لخدمتك مباشرةً. تُضيف HTTP API v2 زمن استجابة لا يتجاوز 1–2 مللي ثانية، في حين تُضيف REST API قرابة 5–10 مللي ثانية لقوالب التعيين والمُفوِّضين.
قواعد عملية على نطاق واسع: عيِّن Reserved Concurrency لكل دالة حتى لا تستنزف طفرات حركة المرور الحدود المشتركة للحساب (الافتراضي 1,000 لكل منطقة، حدّ مرن). استخدم provisionedConcurrencyConfig للقضاء على البدايات الباردة في المسارات الحيوية. فعِّل ضغط الحمولة (minimumCompressionSize: 1024) وتخزين الاستجابات المؤقت لنقاط نهاية GET. ربِّط مُفوِّض Lambda (JWT أو IAM) بدلًا من إجراء التحقق داخل الدالة — إذ يُخزَّن مؤقتًا وفق TTL ويُبقي منطق العمل نظيفًا.
SQS — فصل غير متزامن مع ضبط ضغط الظهر
يُعدّ SQS من أكثر مشغّلات Lambda متانةً تشغيليًا. يتدرّج مستطلع Lambda الداخلي من 5 دفعات متزامنة حتى 1,000 (طوابير Standard) أو 300 × عدد الأقسام (FIFO). أهم المعاملات ذات الأثر في الإنتاج:
- BatchSize (من 1 إلى 10,000): الدُّفعات الأكبر تعني إنتاجية أعلى لكن زمن استجابة أطول لكل عنصر. لعمليات معالجة قواعد البيانات، يكون 100–500 هو النطاق النموذجي.
- MaximumBatchingWindowInSeconds (من 0 إلى 300): ينتظر Lambda هذه المدة لملء دفعة قبل الاستدعاء. يُقلّل الاستدعاءات على حساب زمن الاستجابة؛ اضبطه على 0 للأنابيب الآنية.
- FunctionResponseTypes: [ReportBatchItemFailures]: أكثر إعداد مؤثّر في SQS. بدونه، يؤدي فشل عنصر واحد في دفعة إلى إعادة جميع العناصر إلى الطابور مما يُسبّب تكرارًا. بتفعيله، تُعيد الدالة مصفوفة
batchItemFailuresوتُعاد فقط العناصر الفاشلة إلى الطابور. - طابور الرسائل الميتة (DLQ): أرفقه بطابور SQS (لا بالدالة) كي تستقر الرسائل التي استنفدت
maxReceiveCountفي مكان معروف للتحليل.
VisibilityTimeout في SQS على ما لا يقل عن 6 أضعاف مهلة Lambda. إذا انتهت مهلة الدالة عند 60 ثانية لكن مهلة الرؤية 30 ثانية، تصبح الرسالة مرئية مجددًا بينما الدالة لا تزال تعمل — ما يُفضي إلى استدعاء مكرر في منتصف التنفيذ.
EventBridge — حافلة الأحداث والقواعد المجدولة
يُعدّ EventBridge (المعروف سابقًا بـCloudWatch Events) موجِّه الأحداث في AWS. يقع في مركز معظم بنى الأحداث لأنه يفصل المنتجين عن المستهلكين كليًا — يُرسل المنتج حدث JSON منظَّم إلى حافلة؛ تُرشِّح القواعد وتُوزِّع على الأهداف (Lambda وSQS وSNS وStep Functions وAPI destinations وحتى حافلات عبر الحسابات). تتلقى حافلة الأحداث الافتراضية أحداث خدمات AWS؛ أما الحافلات المخصصة فهي الممارسة المُثلى لأحداث التطبيقات.
EventBridge غير متزامن بطبيعته: تتلقى Lambda الحدث ولا ينتظر EventBridge الرد. إعادة المحاولة قابلة للضبط لكل هدف (من 0 إلى 185) مع تراجع أسي يصل حتى 24 ساعة. أرفق DLQ على قاعدة هدف EventBridge، لا على الدالة وحدها، لالتقاط الأحداث التي فشلت قبل أن تُستدعى Lambda أصلًا.
يتيح Schema Registry توليد ارتباطات مكتوبة تلقائيًا من مخططات أحداثك — أمر بالغ الأهمية للفرق الكبيرة لتجنب انجراف المخطط الصامت. فعِّله على حافلتك المخصصة وضع إصدارًا لمخططاتك عبر بيانات وصفية SchemaVersion في كل حدث.
أحداث S3 — إشعارات مستوى الكائن
تُسلَّم إشعارات أحداث S3 (s3:ObjectCreated:* وs3:ObjectRemoved:* وغيرها) بصورة غير متزامنة. كل إشعار عبارة عن حمولة JSON تصف الدلو والمفتاح والحجم وETag. نقاط عملية تُعاني منها الفرق في الإنتاج:
- التسليم مرة واحدة على الأقل: أحداث S3 ليست بالضبط مرة واحدة. تحت معدلات إنشاء كائنات مرتفعة جدًا يمكن استلام إشعارات مكررة للكائن نفسه. صمِّم معالجك ليكون معطوف النتيجة (idempotent) — مثلًا: اكتب علامة معالجة في DynamoDB بتعبير شرطي قبل القيام بالعمل المُكلف.
- لا ضمان تسليم للكائنات الصغيرة جدًا: عمليات الكتابة المتقاربة جدًا على المفتاح ذاته قد تتدمج في إشعار واحد. استخدم توصيل أحداث EventBridge من S3 (المسار الأحدث) إذا احتجت إلى دقة أعلى — فهو يمر عبر حافلة الأحداث مع دعم إعادة المحاولة وDLQ.
- تصفية الأحداث: أضف فلاتر بادئة/لاحقة على إعداد الإشعار لتجنب استدعاء دالتك على مخرجاتها (خطأ الحلقة اللانهائية الكلاسيكي: الدالة تقرأ من raw/ وتكتب إلى processed/ لكن الإشعار يغطي كل المفاتيح).
قواعد EventBridge — التصفية والتوزيع
تطابق قواعد EventBridge الأحداث باستخدام تصفية قائمة على المحتوى — يمكنك الفلترة على أي حقل في JSON بما في ذلك الحقول المتداخلة والمصفوفات. مخطط حدث جيد البنية مع detail-type وsource مكتوبَيْن يُقلّل تعقيد القواعد بشكل كبير عبر شبكة خدمات ضخمة.
اختيار المشغِّل المناسب
يُأطِّر المهندسون المتقدمون اختيار المشغِّل حول أربعة محاور: تحمُّل زمن الاستجابة، ومتطلبات الترتيب، وضغط الظهر، ورؤية الفشل. API Gateway حين يحتاج المُستدعي إلى إجابة فورية. SQS حين تحتاج إلى قوائم انتظار متينة وضغط ظهر ومعالجة فشل جزئي للدفعة. EventBridge حين تحتاج إلى توجيه قائم على المحتوى عبر الخدمات والحسابات. أحداث S3 (عبر EventBridge) حين يكون المشغِّل دورة حياة كائن. Kinesis Data Streams حين تحتاج إلى تدفق مرتَّب قابل للإعادة وعالي الإنتاجية.
نمط مضادّ يتكرر في الإنتاج: سلسلة استدعاءات Lambda المتزامنة (lambda.invoke من داخل دالة). هذا يُقرِّن زمن الاستجابة ويستهلك التزامن مضاعفًا ويُخفي الأعطال. استبدل كل سلسلة متزامنة بـSQS أو EventBridge — يُرسل المُستدعي، يستطلع المُستقبل، ويتدرّج كلاهما ويفشل باستقلالية تامة.