إدارة الحوادث والمناوبة

تشريح الحادث

18 دقيقة الدرس 1 من 28

تشريح الحادث

كل حادث إنتاجي — من ارتفاع طفيف في زمن الاستجابة اختفى تلقائياً في ثوانٍ، إلى انقطاع مطوّل استمر ساعات وظهر في الأخبار — يتبع دورة حياة متشابهة في جوهرها. في Google وAmazon وNetflix وكل منظمة هندسية جادة، القدرة على معرفة أين أنت بالضبط في تلك الدورة في أي لحظة هي الفرق بين فريق يحل الحوادث بشكل متوقع وفريق يتخبط. هذا الدرس يرسم تلك الدورة بالتفصيل، ويربط كل مرحلة بالأدوات والقرارات البشرية وأوضاع الفشل التي ستواجهها في الإنتاج.

لماذا تهم دورة الحياة: معظم المهندسين يحسّنون مرحلة "الإصلاح" ويهملون الكشف وتحديد النطاق. على نطاق الشركات الكبرى، تحسين دقيقة واحدة في زمن الكشف (TTD) يساوي أضعاف تحسين خمس دقائق في زمن الإصلاح، لأن كل دقيقة من التأثير غير المكتشف تتضاعف عبر ملايين المستخدمين أو آلاف الخدمات المترابطة.

المراحل الست لدورة حياة الحادث

دورة حياة الحادث ليست قائمة مرجعية صارمة — إنها نموذج ذهني يبقي الجميع موجّهين. يمكن للمراحل أن تتداخل، وتنضغط تحت الضغط، أو تتراجع مؤقتاً (اعتقدت أنك وجدت السبب الجذري ثم اكتشفت أنك لم تفعل). معرفة النموذج هي ما يجعلك تلاحظ حين تنجرف.

The Incident Lifecycle: Six Phases from Detection to Resolution 1. Detection Alert fires / user reports 2. Triage Severity? Scope? Who owns it? 3. Comm. Incident channel Status page Stakeholders 4. Mitigation Stop the bleed Rollback / fix 5. Resolution SLOs restored Incident closed 6. Postmortem Root cause Action items Learning ← TTD → ← TTM (mitigation) → ← TTR (resolution) → Incident window: starts at first user impact, ends when SLOs are restored The Incident Lifecycle TTD = Time to Detect | TTM = Time to Mitigate | TTR = Time to Resolve
المراحل الست لدورة حياة الحادث. كل فريق هندسي جاد يتابع TTD وTTM وTTR بوصفها المقاييس الأساسية لصحة الحوادث — تحسينها يُحقق مكاسب موثوقية منهجية.

المرحلة الأولى: الكشف

يبدأ الحادث في اللحظة التي يبدأ فيها التأثير على المستخدم — وليس حين يرسل التنبيه الأول. هذا التمييز جوهري. هناك دائماً فجوة الكشف: الفاصل الزمني بين تدهور النظام وبين من لاحظه. تضييق هذه الفجوة هو أول استثمار في الموثوقية وأكثره أثراً.

مصادر الكشف تقع في ثلاث فئات، بترتيب تقريبي للموثوقية:

  1. المراقبة الاصطناعية — مسابر تتحكم بها، تعمل باستمرار من خارج نظامك (مُصدّرو Prometheus للصندوق الأسود، Pingdom، Datadog Synthetics). هذه تكشف الإخفاقات من منظور المستخدم وليست عرضة لأوضاع الفشل ذاتها لبنيتك التحتية. إذا انهار موازن الحمل وأخذ معه المراقبة الداخلية، فإن المسابر الاصطناعية ستستمر في الإطلاق.
  2. التنبيهات المستندة إلى المقاييس — تنبيهات بحدود أو حالات شاذة على الإشارات الذهبية: زمن الاستجابة، والحركة، والأخطاء، والتشبع (USE: الاستخدام، التشبع، الأخطاء). قواعد AlertManager في Prometheus، مراقبات Datadog، إنذارات CloudWatch. هذه تُطلق بسرعة لكنها تتطلب حدوداً جيدة قائمة على SLO — التنبيه على CPU عند 80% لا يكشف تقريباً شيئاً ذا معنى؛ التنبيه على معدل حرق ميزانية أخطاء SLO يكشف ما يشعر به المستخدمون.
  3. تقارير المستخدم — أسوأ آليات الكشف. بحلول وقت إبلاغ مستخدم عن مشكلة عبر تذكرة دعم، تكون قد فاتك هدف TTD بدقائق أو ساعات. تقارير المستخدم إشارة إلى أن مراقبتك بها ثغرة.
# Prometheus AlertManager: تنبيه بمعدل حرق SLO (الطريقة الصحيحة للتنبيه) # يُطلق هذا حين تحرق ميزانيتك الشهرية بمعدل 14 ضعفاً عن الحالة الاعتيادية # — أي إذا استمر، ستستنفد الميزانية في ~يومين. groups: - name: slo_burn_rate rules: - alert: HighErrorBudgetBurn expr: | ( rate(http_requests_total{status=~"5.."}[1h]) / rate(http_requests_total[1h]) ) > (14 * 0.001) for: 2m labels: severity: critical team: payments annotations: summary: "معدل حرق ميزانية أخطاء مرتفع على {{ $labels.service }}" description: "معدل الأخطاء {{ $value | humanizePercentage }} — حرق الميزانية 14 ضعفاً أسرع من الهدف. الاستنفاد المقدر في < يومين." runbook: "https://wiki.internal/runbooks/payments-high-error-rate"

المرحلة الثانية: الفرز

الفرز هو نافذة الدقيقتين إلى الخمس دقائق بعد الكشف حيث تجيب عن ثلاثة أسئلة: ما مدى خطورته؟ كم عدد المستخدمين/الأنظمة المتأثرة؟ من يملك الاستجابة؟ نتيجة الفرز هي مستوى خطورة (مقياس S0/S1/S2/S3 أو P0/P1/P2 في منظمتك) وقائد حادث معيّن. الخطأ في هذا مكلف — التقليل من تقدير حادث بالغ الخطورة يُضيع دقائق ثمينة؛ المبالغة في تقدير حادث بسيط يُرهق الناس ويآكل انضباط الاستجابة.

الفرز الفعّال يستخدم لوحات القيادة والسجلات، لا الحدس. يبحث مهندس المناوبة المدرّب أولاً في الإشارات الذهبية — زمن الاستجابة، ومعدل الأخطاء، والإنتاجية — ثم في النطاق: هل هذه منطقة واحدة، أم منطقة توفر واحدة، أم خدمة واحدة، أم كاسكادة؟ التحقق من ارتفاع معدل الأخطاء مع نشر حديث (git log --oneline -20 أو أداة تتبع النشر) يستغرق ثلاثين ثانية وكثيراً ما يعطيك 80% من الإجابة.

المرحلة الثالثة: التواصل

يبدأ التواصل بالتوازي مع الفرز، لا بعده. هذا يفاجئ المهندسين الذين يعتقدون "يجب أن أفهم المشكلة قبل أن أقول أي شيء." في Google ومعظم شركات التقنية الكبرى، التعارف المهني معاكس: افتح قناة حادث فوراً، انشر تقييماً أولياً مختصراً ("نحقق في ارتفاع معدل أخطاء API المدفوعات، يُرجَّح أنه مرتبط بنشر 14:32، انتظر تحديثاً في 10 دقائق")، وحدّث بانتظام. الصمت في قناة حادث أسوأ من تحديث غير مؤكد — يملأ المعنيون الصمت بافتراضات الحالة الأسوأ، مما يُطلق سلاسل تصعيد تشتت مهندسيك عن إصلاح المشكلة.

قاعدة التحديث كل 10 دقائق: اضبط مؤقتاً. كل 10 دقائق خلال حادث نشط، انشر تحديثاً في قناة الحادث، حتى لو كان التحديث "لا يزال قيد التحقيق، لا معلومات جديدة." هذه الممارسة الواحدة تُزيل 80% من مقاطعات "ما الحالة؟" لقائد الحادث. أدوات مثل PagerDuty وFireHydrant وRootly تستطيع أتمتة تذكيرات التحديث.

المرحلة الرابعة: التخفيف

التخفيف وتحليل السبب الجذري نشاطان منفصلان، والخلط بينهما أحد أكثر أخطاء الإنتاج شيوعاً. التخفيف يعني إيقاف التأثير على المستخدم بأسرع ما يمكن، بأي وسيلة متاحة. تحليل السبب الجذري يأتي لاحقاً. الفريق الذي يقضي 40 دقيقة في تتبع السبب الدقيق لتوقف قاعدة البيانات بينما المستخدمون لا يستطيعون إتمام الشراء يتخذ المقايضة الخاطئة — أعِد النشر أولاً، ثم حقق.

مجموعة أدوات التخفيف المعيارية بترتيب التفضيل:

  1. التراجع عن النشر — إذا تسبب نشر في المشكلة، تراجع عنه. هذا أسرع وأكثر موثوقية للتخفيف لفئة كبيرة من الحوادث. يجب أن يدعم خط النشر الخاص بك هذا في أقل من دقيقتين ليكون فعّالاً.
  2. علامة ميزة / قاطع دائرة — عطّل الميزة أو التبعية المحددة التي تفشل دون إعادة نشر كاملة. LaunchDarkly وStatsig أو علامة بسيطة مدعومة بقاعدة بيانات تستطيع تقليص النطاق في ثوانٍ.
  3. تحويل الحركة — أعِد توجيه الحركة بعيداً عن المنطقة أو إصدار الخدمة الفاشل. خدمات Kubernetes الموزونة، أو أوزان مجموعة الهدف في ALB، أو سياسات حركة Istio تمنحك هذا على الطبقة 7.
  4. التوسع الأفقي — إذا كان السبب تشبع الموارد (لا خللاً برمجياً)، فإن إضافة سعة تكسب الوقت. kubectl scale deployment payments --replicas=20. هذا إجراء مؤقت، لا إصلاح.
# Kubernetes: التراجع السريع إلى ReplicaSet السابق # تحقق من تاريخ النشر الحالي أولاً kubectl rollout history deployment/payments-api -n prod # التراجع إلى المراجعة السابقة kubectl rollout undo deployment/payments-api -n prod # تأكيد اكتمال النشر kubectl rollout status deployment/payments-api -n prod --timeout=120s # تحقق من انخفاض معدل الأخطاء — راجع Prometheus أو شغّل اختبار curl سريعاً for i in $(seq 1 10); do curl -sf https://api.example.com/healthz && echo "OK" || echo "FAIL" sleep 2 done

المرحلة الخامسة: الحل

يُحَل الحادث حين يتحقق شرطان: عادت مؤشرات SLO للمستخدم إلى المستويات المستهدفة، والتخفيف مستقر (لا مجرد "يبدو بخير الآن"). الحل إعلان متعمد، لا مجرد لحظة تصمت فيها التنبيهات. يُغلق قائد الحادث الحادث صراحةً، يسجل وقت الانتهاء (أمر بالغ الأهمية لحساب MTTR واستهلاك ميزانية الأخطاء)، ويحيل أي عمل متبقٍّ إلى القنوات الهندسية الاعتيادية.

تجنّب النمط المضاد للـ"إغلاق الناعم" — ترك قناة الحادث مفتوحة بلا مالك معلن بينما يواصل المهندسون العمل بهدوء عليها. هذا يُعتم على مقاييس MTTR الحقيقية ويُبقي المعنيين غير متأكدين من حالة النظام.

# PagerDuty CLI: حل حادث وتسجيل وقت الانتهاء # التثبيت: pip install pdpyras أو استخدم pd CLI (brew install pagerduty/tap/pd) pd incident resolve --id P1A2B3C # تسجيل ملاحظة الحل (مُلتقطة في الجدول الزمني للتحليل اللاحق) pd incident note add --id P1A2B3C \ --content "Resolved 15:47 UTC. Rolled back deploy abc123. Error rate returned to baseline. Postmortem scheduled for tomorrow 10:00 UTC. Owner: @jane"

المرحلة السادسة: التحليل اللاحق

التحليل اللاحق هو حيث تُغلق دورة الحياة الحلقة. التحليل اللاحق اللاوم — المكتوب خلال 48-72 ساعة بينما الذاكرة حية — يوثّق الجدول الزمني الكامل، والعوامل المساهمة (لا "سبباً جذرياً" واحداً، لأن الأنظمة المعقدة نادراً ما يكون لها سبب واحد)، ومجموعة من بنود الإجراءات مع أصحابها وتواريخ الاستحقاق. الهدف ليس تحميل المسؤولية بل جعل النظام أكثر مرونة والفريق أكثر استعداداً. يُغطى التحليل اللاحق بعمق في الدرس السابع؛ ما يهم هنا هو فهم أن التحليل اللاحق ليس أعباءً اختيارية — إنه الآلية التي تحوّل الحوادث من تكلفة بحتة إلى تعلم مؤسسي.

المقاييس الرئيسية: TTD وTTM وTTR

كل مرحلة من مراحل دورة الحياة تقابل قياساً يجب على فريقك تتبعه. هذه هي مقاييس صحة الحوادث المعيارية في الصناعة المستخدمة في Google وAWS وStripe:

  • زمن الكشف (TTD) — من أول تأثير على المستخدم حتى انخراط مهندس المناوبة. الهدف: أقل من 5 دقائق لـ P0/S0. يُحسَّن بتنبيهات أفضل ومراقبة اصطناعية.
  • زمن التخفيف (TTM) — من الانخراط حتى توقف التأثير على المستخدم. الهدف: أقل من 30 دقيقة لـ P0. يُحسَّن بأدلة التشغيل، وأدوات التراجع السريع، وقواطع الدائرة.
  • زمن الحل (TTR) — من الانخراط حتى كامل صحة النظام وإغلاق الحادث. يمكن أن يكون ساعات أو أياماً إذا كان التخفيف حلاً مؤقتاً والإصلاح الحقيقي يحتاج وقتاً.
  • متوسط الوقت بين الإخفاقات (MTBF) — متوسط الوقت بين الحوادث ذات الخطورة المماثلة. يُحسَّن بعمل الهندسة الموثوقية الذي يظهر في التحليلات اللاحقة.
مصيدة إنتاجية — الخلط بين التخفيف والحل: كثير من الفرق تُبلّغ عن TTR بينما تقصد فعلياً TTM. يعلنون الحادث "محلولاً" في اللحظة التي يكون فيها الحل المؤقت ساري المفعول، دون التأكد من صحة النظام الأساسي واستقرار التخفيف. بعد ست ساعات، ينهار الحل المؤقت ويُعاد فتح الحادث. تتبع TTM وTTR بشكل منفصل؛ كل منهما يروي قصة مختلفة عن قدرة فريقك.

دورة حياة الحادث في السياق

المراحل أعلاه تصف آليات حادث واحد. في الممارسة العملية، يدير فريق المناوبة الخاص بك مجموع جميع الحوادث على نافذة متحركة، مقاساً وفق ميزانية الأخطاء. الفريق الذي يستطيع الكشف بشكل موثوق في أقل من 3 دقائق، والتخفيف في أقل من 20 دقيقة، وإجراء تحليلات لاحقة لاومة مع بنود إجراءات مكتملة، سيقلل مع الوقت من تكرار الحوادث وخطورتها — تراكماً بنفس الطريقة التي تتراكم بها الهندسة الجيدة. يغطي هذا الدرس التعليمي الأدوات والممارسات التي تجعل كل مرحلة أسرع وأكثر موثوقية. الخطوة الأولى هي معرفة الخريطة.