أنماط المعمارية

الخوادم اللاخادمية والدوال كخدمة

18 دقيقة الدرس 9 من 10

الخوادم اللاخادمية والدوال كخدمة

لا تعني الحوسبة اللاخادمية (Serverless) غياب الخوادم — بل تعني أنك توقف إدارتها. تكتب دالة، تنشرها لدى مزود سحابي (AWS Lambda أو Google Cloud Functions أو Azure Functions أو Cloudflare Workers)، ويتكفّل المزود بالتوفير والتحجيم والتحديثات والصيانة كلياً. تُحاسَب لكل استدعاء ولكل ميلي ثانية تنفيذ، لا على طاقة خاملة. عند انعدام الحركة تدفع صفراً. عند مليون حدث في الثانية تتوسّع المنصة تلقائياً.

التجريد الجوهري هو وحدة الدالة كخدمة (FaaS): معالج عديم الحالة قصير العمر يُستدعى عند وقوع حدث، ينجز عمله ثم يخرج. كل استدعاء مستقل — لا حالة مشتركة داخل العملية، ولا خيوط طويلة الأمد لإدارتها.

كيف يعمل الاستدعاء المُشغَّل بالأحداث

كل دالة FaaS مرتبطة بـمصدر حدث. تستمع وقت التشغيل بالنيابة عنك وتستدعي دالتك عند وقوع الحدث. المصادر الشائعة:

  • HTTP / بوابة API — طلب HTTPS يصل إلى نقطة نهاية API Gateway التي تُحيله إلى دالة. AWS API Gateway + Lambda هو النمط الأكثر شيوعاً.
  • قوائم الرسائل / التدفقات — تصل رسالة إلى قائمة SQS أو تدفق Kinesis/Kafka؛ تُسلّم المنصة دفعةً من السجلات إلى دالتك.
  • أحداث التخزين — يُرفع ملف إلى S3/GCS؛ يُطلق المستودع حدثاً وتستلم دالتك بيانات الكائن.
  • المشغّلات الجدولية (كرون) — يستدعي AWS EventBridge Scheduler أو Cloud Scheduler دالتك وفق تعبير كرون (مثلاً توليد تقرير ليلي).
  • تدفقات تغيير قواعد البيانات — تُسلّم DynamoDB Streams أو مشغّلات Firestore سجلات التغيير شبه الآنية.
Serverless Event-Triggered Architecture EVENT SOURCES HTTP / API Gateway Queue / Stream Storage Event (S3) Cron / Scheduler DB Change Stream FaaS Platform (AWS Lambda / Cloud Functions) auto-scales instances bills per ms DOWNSTREAM Database External API Storage Write HTTP Response 1,000 events = 1,000 concurrent function instances (automatic)
البنية المُشغَّلة بالأحداث في الحوسبة اللاخادمية: مصادر أحداث متعددة تستدعي نسخ دوال عديمة الحالة؛ تضبط المنصة التوازي تلقائياً وتُحاسب على وقت التنفيذ فحسب.

مشكلة البداية الباردة

حين لم تُستدعَ الدالة مؤخراً، يجب على المنصة تشغيل حاوية جديدة، وتحميل وقت التشغيل (Node.js أو Python أو JVM...)، وتهيئة كودك قبل تنفيذ المعالج. تُضيف هذه البداية الباردة عادةً 100 مللي ثانية — ثانيتين من الكمون الإضافي. تُعيد الاستدعاءات اللاحقة استخدام الحاوية الدافئة دون أي عقوبة. حقائق رئيسية:

  • بدايات باردة لـNode.js وPython: عادةً 100–300 مللي ثانية على AWS Lambda.
  • بدايات باردة لـJVM (Java/Kotlin): 1–3 ثوانٍ لأن تهيئة JVM ثقيلة. يستطيع AWS SnapStart خفضها إلى ~200 مللي ثانية باستعادة لقطة مهيّأة مسبقاً.
  • Cloudflare Workers (عوازل V8 لا حاويات): بداية باردة أقل من 5 مللي ثوانٍ — نموذج تنفيذ مختلف جوهرياً.
  • استراتيجيات التخفيف: احتفظ بالدوال صغيرة (أقل تحميلاً)، استخدم التزامن المُجهَّز (نسخ مُسخَّنة مسبقاً مُحاسَبة حتى حين خاملة)، أو صمّم التدفقات بحيث لا تكون مسارات البداية الباردة حرجة.
البدايات الباردة تستبعد serverless للمسارات المتزامنة الحساسة للكمون — مثل مسار الدفع الرئيسي في متجر إلكتروني حيث يجب أن يكون كمون p99 تحت 100 مللي ثانية. استخدم حاويات دائمة التشغيل أو نسخاً مُسخَّنة مسبقاً لتلك المسارات. البدايات الباردة مقبولة للمهام الخلفية والمعالجة غير المتزامنة ومعالجات الـwebhook حيث يكون تأخير بضع مئات من المللي ثانية محتملاً.

انعدام الحالة ونموذج التنفيذ

كل استدعاء FaaS معزول. لا يمكنك تخزين حالة في متغيّر عام وتوقّع أن الاستدعاء التالي سيراها — فقد يعمل على نسخة مختلفة كلياً. النمط الصحيح:

  • تنتمي الحالة خارج الدالة — في قاعدة بيانات (RDS أو DynamoDB) أو ذاكرة تخزين مؤقت (ElastiCache/Redis) أو تخزين كائنات (S3). تقرأ الدالة ما تحتاجه، تعالج، تكتب النتائج، وتخرج.
  • الإعداد المكلف لمرة واحدة (اتصال قاعدة البيانات، تهيئة عميل SDK) يوضع على مستوى الوحدة، خارج المعالج. في الحاوية الدافئة تُعيد المنصة استخدام الوحدة فيجري الإعداد مرة واحدة. في البداية الباردة يجري مرة واحدة قبل الاستدعاء الأول. هذا تحسين آمن لا نمط ذو حالة.
قيد جوهري: يفرض AWS Lambda حداً أقصى لمهلة التنفيذ يبلغ 15 دقيقة. إذا استغرق عملك وقتاً أطول، قسّمه إلى خطوات أصغر مُنسَّقة بآلة حالة (AWS Step Functions) أو نمط توزيع قائمة. المهام طويلة الأمد تنتمي للحاويات أو العمال المخصصين لا لـFaaS.

متى يناسب Serverless — ومتى لا يناسب

Serverless Good Fit vs Poor Fit GOOD FIT Spiky / unpredictable traffic (event bursts) Async background jobs (image resize, ETL) Webhook handlers (GitHub, Stripe, Twilio) Scheduled data pipelines / nightly jobs Low-to-medium throughput APIs (<1k RPS) Glue code / orchestration steps POOR FIT Latency-critical sync paths (p99 < 50 ms) Long-running jobs (> 15 min execution) In-process shared state / sticky sessions Very high sustained throughput (>50k RPS) WebSocket / streaming connections GPU / memory-intensive compute (>10 GB RAM)
مقارنة الحالات المناسبة وغير المناسبة لـServerless — يتفوق النمط في أعباء العمل المُشغَّلة بالأحداث والحركة المتغيّرة، لكنه يعاني مع المسارات الحساسة للكمون والمهام طويلة الأمد.

نموذج التكلفة: أين يوفّر Serverless وأين يصبح مكلفاً

تسعير AWS Lambda (us-east-1، اعتباراً من 2024): 0.20 دولار لكل مليون استدعاء و0.0000166667 دولار لكل GB-ثانية من الذاكرة. أول مليون استدعاء شهرياً مجاني. دالة تستخدم 512 ميغابايت تعمل 200 مللي ثانية تكلف نحو 0.0000017 دولار لكل استدعاء. مليون استدعاء كهذا = 1.70 دولار. قارن بمثيل t3.small بـ~15 دولاراً شهرياً يعالج المليون استدعاء ذاته لكنه خامل 99.9% من الوقت.

ينعكس الحساب عند الحمل المرتفع المتواصل. إذا عمل خدمتك بـ10,000 طلب في الثانية باستمرار على مدار الساعة، فأسطول صغير من الحاويات أرخص من Lambda. عادةً ما يقع نقطة التقاطع (Lambda مقابل الحاويات) بين 5,000 و20,000 طلب في الثانية مستدام حسب مدة الدالة والذاكرة.

نمط حقيقي — بنية هجينة: تستخدم كثير من أنظمة الإنتاج Serverless للذيل الطويل من العمل المُشغَّل بالأحداث (معالجة الصور، الإشعارات، ETL، الـwebhooks) مع الإبقاء على مسار API المتزامن الساخن في حاويات دائمة التشغيل أو حاويات Kubernetes. الأعباء غير المتزامنة غالباً ما تمثّل 80% من عدد الاستدعاءات لكن 5% فقط من الحساسية للكمون — ملاءمة طبيعية لاقتصاديات FaaS.

المراقبة في أنظمة Serverless

تصحيح أخطاء Serverless أصعب من تصحيح المونوليث لأن الطلبات تتشعّب عبر نسخ مؤقتة لكل منها سجلاتها الخاصة. الممارسات الإلزامية:

  • السجلات المُهيكَلة — أصدر سجلات JSON تحمل requestId (يُضيفه المزود السحابي تلقائياً) لتتمكن من تتبّع كل سطور سجل استدعاء واحد.
  • التتبّع الموزّع — انقل سياق التتبّع (ترويسة W3C traceparent أو معرّف تتبّع AWS X-Ray) عبر كل قفزة غير متزامنة. بدونه يكون سلسلة من خمس دوال Lambda مُشغَّلة بأحداث عتيمة تماماً.
  • قوائم الرسائل الميتة (DLQ) — اضبط SQS DLQ على كل مصدر أحداث. الاستدعاءات الفاشلة تصل إليها للفحص وإعادة التشغيل بدلاً من الاختفاء صامتةً.
مبدأ معماري: لا تُزيل Serverless التعقيد التشغيلي — بل تُحوّله من إدارة البنية التحتية (التحديثات، التحجيم) إلى سبك الأحداث والمراقبة. تتطلب أنظمة Serverless المُدارة بشكل جيد تتبّعاً دقيقاً وتنبيهاً على عمق DLQ وميزانية مهل الوقت عبر سلسلة الاستدعاء بأكملها.