يضع هذا الدرس الختامي كل ما تعلمناه في البرنامج التعليمي موضع التطبيق الفعلي. ستصمم برنامج فوضى كاملًا مبنيًا على الفرضيات لنظام إنتاج واقعي — ليس نموذجًا تجريبيًا، بل النوع من البرامج المنظمة التي تُشغّله شركات Netflix وGoogle وAmazon ضد بنيتها التحتية الحية. المخرج هو وثيقة خطة تجارب فوضى يستطيع أي مهندس كبير في فريقك التقاطها وتنفيذها والتعلم منها.
النظام النموذجي المستهدف
النظام المستهدف هو خدمة دفع تجارة إلكترونية متعددة المناطق. إنها بنية معمارية واقعية تُمرّن كل أنماط الفشل التي تناولناها في هذا البرنامج التعليمي. يضم النظام المكونات التالية:
API Gateway — NGINX ingress في منطقتين (us-east-1, eu-west-1)، مع Route 53 للتوجيه القائم على الكمون.
Checkout Service — نشر Kubernetes (6 نسخ لكل منطقة)، مكتوب بـ Go. يستدعي ثلاث خدمات خلفية: Inventory وPayment وFraud.
Inventory Service — بلا حالة، 4 نسخ لكل منطقة، مع كاش Redis وقاعدة بيانات PostgreSQL احتياطية للقراءة.
Payment Service — يستدعي Stripe API الخارجية بمهلة 2 ثانية وقاطع دائرة.
Fraud Service — خدمة استنتاج تعلم آلي بتأخير p99 يبلغ 180 ملي ثانية تحت الحمل الطبيعي.
PostgreSQL — أساسي في us-east-1 مع نسخة متزامنة في eu-west-1 يديرها Patroni للتحويل التلقائي.
Redis Cluster — 3 شظايا، نسخة احتياطية لكل شظية، للجلسات وكاش المخزون.
مكدس الرؤية — Prometheus/Grafana للمقاييس، Jaeger للتتبع، Loki للسجلات. SLO: نجاح 99.9% من عمليات الدفع على نافذة 28 يومًا.
الخطوة الأولى: تعريف الحالة المستقرة
كل تجربة فوضى تحتاج إلى خط أساس قابل للقياس وغير مبهم. التعريفات الضبابية كـ"النظام بصحة جيدة" عديمة الفائدة — لا يمكنك اكتشاف الانحراف عن خط أساس لا تستطيع قياسه. عرّف حالتك المستقرة بمصطلحات SLIs مرتبطة مباشرة بالـ SLO:
# تعريفات SLI للحالة المستقرة (PromQL)
# 1. معدل نجاح الدفع (إشارة SLO الرئيسية)
sum(rate(checkout_requests_total{status="success"}[5m]))
/
sum(rate(checkout_requests_total[5m]))
# الهدف: >= 0.999 (99.9%)
# 2. تأخير الدفع p99
histogram_quantile(0.99, sum by (le) (rate(checkout_duration_seconds_bucket[5m])))
# الهدف: <= 2.0 ثانية
# 3. حالة قاطع دائرة الدفع
payment_circuit_breaker_state{state="open"}
# الهدف: == 0 (الدائرة مغلقة)
# 4. معدل إصابة كاش المخزون
sum(rate(inventory_cache_hits_total[5m]))
/
sum(rate(inventory_cache_requests_total[5m]))
# الهدف: >= 0.85 (85% معدل إصابة)
# 5. تأخير تزامن قاعدة البيانات (لتجارب تحويل المنطقة)
postgres_replication_lag_seconds{replica="eu-west-1"}
# الهدف: <= 5.0 ثوانٍ
مبدأ أساسي: حالتك المستقرة هي عقد. اكتبها في وثيقة مشتركة قبل التجربة وليس بعدها. إذا كسرتها التجربة فقد اكتشفت ضعفًا حقيقيًا. وإذا لم تكسرها فقد اكتسبت ثقة حقيقية. كلا النتيجتين ذات قيمة — الفشل الوحيد هو تجربة لا تستطيع تفسيرها لأن خط الأساس كان غير معرَّف.
الخطوة الثانية: قائمة التجارب المعلقة — مرتبة حسب المخاطر
لا تُشغّل التجارب بالترتيب الذي يبدو مثيرًا للاهتمام. شغّلها بالترتيب الذي يعالج أعلى مخاطر الأعمال أولًا. قيّم كل تجربة على بعدين: الاحتمالية (كم مرة يحدث هذا النمط من الفشل فعليًا؟) والتأثير (ما مدى سوء تجربة المستخدم عند حدوثه؟). اضرب الاثنين للحصول على درجة المخاطر. التجارب ذات الدرجة الأعلى تأتي أولًا.
مصفوفة مخاطر تجارب الفوضى: أولوية التجارب في الربع العلوي الأيمن (احتمالية عالية، تأثير تجاري كبير).
الخطوة الثالثة: كتابة وثيقة الفرضية
يجب أن تمتلك كل تجربة وثيقة فرضية مكتوبة قبل تشغيل أي أمر. الصيغة هي: بافتراض [حالة النظام]، عندما يحدث [حدث الفشل]، يجب أن تكون النتيجة [مخرج قابل للقياس]، لأن [آلية المرونة]. إليك التجربة الأولى كاملة:
# EXPERIMENT-001: حقن تأخير خدمة الدفع
# الأولوية: P0 (احتمالية عالية، تأثير مباشر على الإيراد)
# المالك: فريق payments
# المجدول: الثلاثاء 2025-09-09 14:00 UTC (ساعات العمل)
# نطاق التأثير: 10% من حركة المرور في شريحة canary بـ us-east-1
## الفرضية
بافتراض: خدمة الدفع تعمل في الحالة المستقرة (>= 99.9% نجاح، p99 <= 2.0 ثانية)
عندما: وقت استجابة Payment Service يتدهور إلى 4 ثوانٍ (ضعفا المهلة الطبيعية) لـ 10% من الطلبات
يجب أن: يبقى معدل نجاح الدفع >= 99.5% (بميزانية تراجع سلس)،
وأن تتحول payment_circuit_breaker_state إلى "open" خلال 30 ثانية،
ويتلقى المستخدمون المتأثرون رسالة "حاول مرة أخرى قريبًا" وليس خطأ 500
لأن: قاطع الدائرة (العتبة: 5 إخفاقات في 10 ثوانٍ) يجب أن يفتح ويُعيد
استجابة "الدفع غير متاح" المخزنة؛ ومنطق إعادة المحاولة يوجه المستخدمين غير المتأثرين بشكل طبيعي
## محفز التراجع
- إذا انخفض معدل نجاح الدفع تحت 99.0% لأكثر من 60 ثانية
- أي ملاحظة يدوية لتلف البيانات في جدول payment_events
## إجراء التراجع
kubectl exec -n chaos deploy/chaos-mesh-controller -- chaosctl recover EXPERIMENT-001
# يُنظف Chaos Mesh مورد NetworkChaos؛ يُغلق قاطع الدائرة خلال 30 ثانية
## المقاييس المراد رصدها (احفظ لقطة اللوحة قبل + أثناء + بعد)
- معدل checkout_requests_total{status="success"}
- checkout_duration_seconds p99
- payment_circuit_breaker_state
- معدل payment_client_timeout_total
- downstream_payment_latency_seconds p50/p99
## مانيفست Chaos Mesh
apiVersion: chaos-mesh.org/v1alpha1
kind: NetworkChaos
metadata:
name: experiment-001-payment-latency
namespace: chaos-testing
spec:
action: delay
mode: fixed-percent
value: "10"
selector:
namespaces: [production]
labelSelectors:
app: checkout-service
direction: to
target:
selector:
namespaces: [production]
labelSelectors:
app: payment-service
mode: all
delay:
latency: "4000ms"
correlation: "50"
jitter: "500ms"
duration: "15m"
معيار كبار الشركات: في Google وAmazon، كل تجربة فوضى لها مالك مسمى وتذكرة حادث مرتبطة وقناة Slack مثبتة طوال فترة التجربة. المالك مسؤول عن تفعيل التراجع دون انتظار الموافقة. الفوضى بلا إنسان مسمى يراقب المقاييس في الوقت الحقيقي هي تهور في الإنتاج، وليست انضباطًا هندسيًا.
الخطوة الرابعة: قائمة التجارب الكاملة (جدول ملخص)
يحتفظ برنامج الفوضى الناضج بقائمة تجارب مرتبة حسب درجة المخاطر. فيما يلي خطة التجارب الكاملة لهذا النظام، مهيكلة كما تُقدّمها في مراجعة التصميم الهندسي:
ID | نمط الفشل | النطاق | الأولوية | ملخص الفرضية
--------------------------------------------------------------------------------------------
EXPERIMENT-001 | Payment API +4s تأخير | 10% canary | P0 | قاطع الدائرة يفتح؛ تراجع سلس
EXPERIMENT-002 | Redis: إيقاف الشظية الأساسية | 1 من 3 شظايا | P0 | الترقية < 30s؛ كاش ميس مؤقت
EXPERIMENT-003 | قتل checkout pods (3 من 6) | us-east-1 فقط | P1 | K8s يعيد الجدولة؛ لا خرق SLO
EXPERIMENT-004 | تجاوز فشل primary PostgreSQL | us-east-1 | P1 | Patroni يُرقي الاحتياطي < 45s؛ لا فقدان بيانات
EXPERIMENT-005 | فشل Fraud Service 100% | كل الحركة | P1 | يتم الدفع (Fraud غير معيق)
EXPERIMENT-006 | انقطاع شبكة منطقة التوافر | us-east-1 AZ-b | P1 | Route 53 + ALB يُخلّيان AZ-b؛ لا خرق SLO
EXPERIMENT-007 | تشبع المعالج (90%) في checkout | 2 من 6 pods | P2 | HPA يُفعّل؛ توسع < 60s
EXPERIMENT-008 | فشل DNS (Fraud) | canary 5% | P2 | مسار انتهاء المهلة؛ Fraud لا يعيق الدفع
EXPERIMENT-009 | استنزاف الذاكرة + OOMKill | pod واحد | P2 | K8s يُعيد التشغيل؛ لا حركة تُفقد
EXPERIMENT-010 | تحويل منطقة كاملة (us-east-1) | مرآة التجهيز | P3 | Route 53 يتحول لـ eu-west-1 < 2 دقيقة
الخطوة الخامسة: التكامل مع دليل التشغيل والتحقق من التنبيهات
كل تجربة فوضى هي أيضًا اختبار تحقق من التنبيهات. أثناء حقن الفشل، تحقق من أن تنبيهات المناوبة تنطلق ضمن SLA المتوقع. إذا قتلت EXPERIMENT-003 ثلاثًا من ستة pods ولم يصل تنبيه PagerDuty خلال 90 ثانية، فمنظومة التنبيه لديك معطوبة — وهذه النتيجة بنفس أهمية سلوك المرونة ذاته.
بعد كل تجربة، حدّث دليل التشغيل الخاص بنمط الفشل الذي اختبرته. دليل تشغيل موثَّق بتجربة فوضى يساوي عشرة أدلة مكتوبة من المبادئ الأولى. أدرج فيه: TTD الملاحظ (وقت الكشف)، TTR (وقت التعافي)، إشارات الرصد التي اندلعت أولًا، وما يجب على مهندس المناوبة فعله الذي يختلف عن النظرية.
الخطوة السادسة: توثيق النتائج وتتبع التحسينات
لكل تجربة سجّل النتيجة مقارنةً بالفرضية. ثلاثة نتائج ممكنة:
مؤكَّدة: تصرف النظام تمامًا كما افترضنا. وثّقها دليلًا على المرونة. جدول إعادة التشغيل بعد التغيير الجوهري التالي في الاعتماديات.
مدحوضة — الاتجاه المتوقع: فشل النظام بشكل أسوأ مما افترضنا (مثال: استغرق فتح قاطع الدائرة 90 ثانية بدلًا من 30). سجّل علة تقنية بمستوى خطورة يتناسب مع درجة المخاطر. أوقف الـ sprint التالي حتى الإصلاح.
مدحوضة — اتجاه غير متوقع: فشل النظام بطريقة لم تتوقعها (مثال: فتح قاطع الدائرة لكنه تسبب في تسلسل أسقط Fraud أيضًا). هذه أقيم نتيجة على الإطلاق. اكتب تقرير ما بعد الحادث لا مجرد تذكرة علة — فشيء ما في نموذجك الذهني للنظام كان خاطئًا جوهريًا.
فخ إنتاجي: أكثر إخفاقات برامج الفوضى شيوعًا هو تشغيل التجارب دون تتبع عمل التحسين المنبثق عنها. إذا كشفت EXPERIMENT-002 أن ترقية شظية Redis تستغرق 45 ثانية بدلًا من الـ 10 ثوانٍ المفترضة، ولم تُرتبط هذه النتيجة بعنصر عمل هندسي له مالك وتاريخ استحقاق وخطة تحقق، فقد أنتج برنامج الفوضى فوضى لا تحسينًا. كل فرضية مدحوضة يجب أن تُولّد تذكرة لها مالك وتاريخ استحقاق وخطة تحقق — وهي عادةً تشغيل نفس تجربة الفوضى مرة أخرى بعد الإصلاح.
نضج برنامج الفوضى — إلى أين نتجه بعد ذلك
نموذج نضج هندسة الفوضى: ابدأ بالتجارب اليدوية، وتطور نحو فوضى إنتاج مستمرة على مدى 12-18 شهرًا.
برنامج فوضى صحي في السنة الأولى لمنظمة من 50 مهندسًا يبدو هكذا: ثماني تجارب يدوية كل ربع سنة (المستوى 1)، يومان للعب سنويًا (المستوى 2)، وبوابات فوضى في CI للخدمات الأكثر أهمية بنهاية السنة الأولى (بداية المستوى 3). الفوضى المستمرة في الإنتاج (المستوى 4) تستلزم رؤية ناضجة وثقافة لا تلوم الأفراد وسنوات من نتائج التجارب المتراكمة التي تبني ثقة المنظمة. لا تتخطى المستويات.
إجراء ختامي: خذ خطة التجارب هذه وكيّفها لنظام تُشغّله الآن. حدد أخطر خمسة أنماط فشل باستخدام مصفوفة المخاطر، اكتب وثيقة الفرضية للتجربة الأولى، وجدولها الثلاثاء القادم الساعة الثانية ظهرًا. أهم خطوة في أي برنامج فوضى هي التجربة الأولى — ليس لأن النتيجة ستكون مثالية، بل لأنها تجعل الممارسة حقيقية. كل فريق SRE في Google يُشغّل تجربة فوضى واحدة على الأقل قبل أن تُسمى أي خدمة جاهزة للإنتاج. اجعل هذا معيارك الجديد أيضًا.
نستخدم ملفات تعريف الارتباط لتشغيل هذا الموقع وتحليل الزيارات وعرض إعلانات مخصّصة. يمكنك قبول كل ملفات تعريف الارتباط أو رفض غير الأساسية منها.
سياسة الخصوصية