هندسة موثوقية المواقع (SRE)

التنبيه على أهداف مستوى الخدمة

18 دقيقة الدرس 8 من 29

التنبيه على أهداف مستوى الخدمة

تعتمد معظم الفرق على التنبيه بناءً على الأعراض: استخدام المعالج أكثر من 80 %، أو معدل الأخطاء أكثر من 1 %، أو زمن الاستجابة p99 أكثر من 500 مللي ثانية. هذه العتبات اعتباطية، تُطلق إنذارات بلا داعٍ، وتصمت أمام الأعطال البطيئة التي تستنزف ميزانية الخطأ خلال أيام. التنبيه المبني على SLO يعكس هذا المنطق — تُنبَّه فقط عندما تستهلك ميزانية خطئك أسرع مما تستطيع تحمله، وذلك بقياس متعدد النوافذ الزمنية في آنٍ واحد. هكذا تحقق شركات مثل Google وSpotify وCloudflare موثوقية عالية مع حد أدنى من إجهاد التنبيهات.

الفكرة الأساسية: معدل الاستهلاك

ميزانية الخطأ الخاصة بـ SLO لمدة 30 يومًا هي الجزء من الطلبات المسموح لك بتقديمها بشكل سيئ. هدف 99.9 % يمنحك 0.1 % أحداث سيئة — أي 43.2 دقيقة من التوقف الكامل، أو تسرب 0.1 % مستمر لمدة 30 يومًا. معدل الاستهلاك يخبرك بالسرعة التي تستهلك فيها تلك الميزانية قياسًا بالوتيرة الطبيعية.

  • معدل الاستهلاك = 1 — ستستهلك 100 % من ميزانيتك بالضبط خلال 30 يومًا. مقبول.
  • معدل الاستهلاك = 2 — ستنفد الميزانية في 15 يومًا. تحقق قريبًا.
  • معدل الاستهلاك = 14.4 — بهذه الوتيرة تنتهي ميزانية الشهر كاملة في ساعتين. تنبيه فوري.
  • معدل الاستهلاك = 36 — تنتهي الميزانية في 48 دقيقة. عطل حرج جارٍ.

الصيغة هي: burn_rate = (bad_event_rate / (1 - SLO_target)). لهدف SLO بنسبة 99.9 %، معدل أحداث سيئة بنسبة 1.44 % يعني معدل استهلاك 14.4 (أي 1.44 % / 0.1 %).

لماذا تفشل تنبيهات النافذة الواحدة

نافذة قصيرة واحدة (5 دقائق) تكتشف الارتفاعات المفاجئة بسرعة لكنها تولد ضوضاء هائلة — 10 ثوانٍ من أخطاء 503 تُطلق التنبيه حتى لو كان أثرها على الميزانية تافهًا. نافذة طويلة واحدة (ساعة) تُخمد الضوضاء لكنها بطيئة جدًا لرصد العطل الكبير الذي يستنزف الميزانية في دقائق. الحل هو التنبيه متعدد النوافذ متعدد معدلات الاستهلاك: دمج نافذة قصيرة سريعة (للكشف السريع) مع نافذة طويلة بطيئة (لتأكيد استمرار الحالة)، مع تدرج العتبات بحسب سرعة تراكم الضرر.

مستويات التنبيه الموصى بها من Google

كتاب SRE Workbook (2018) وما تلاه من ممارسات صناعية يتقاربان على أربعة مستويات للتنبيه لنافذة SLO مدتها 30 يومًا. يُطلق كل مستوى فقط عندما تتجاوز النافذتان القصيرة والطويلة في آنٍ واحد عتبة معدل الاستهلاك — هذا هو شرط النوافذ المتعددة الذي يلغي معظم التنبيهات الكاذبة:

Multi-Window Multi-Burn-Rate Alert Tiers TIER 1 — CRITICAL PAGE Burn rate ≥ 14.4 · Short window: 5 min · Long window: 1 hr Budget exhausted in < 2 hours. Both windows must fire. Immediate page. TIER 2 — HIGH PAGE Burn rate ≥ 6 · Short window: 30 min · Long window: 6 hr Budget exhausted in < 5 days. Both windows must fire. Page (may wait for ack). TIER 3 — TICKET Burn rate ≥ 3 · Short window: 2 hr · Long window: 24 hr Budget at risk. File a ticket; investigate next business day. TIER 4 — INFO / WATCH Burn rate ≥ 1 · Window: 3 day rolling Budget consumption on trend. Log and review in SLO report. Urgency
أربعة مستويات للتنبيه: عتبات معدل الاستهلاك والنوافذ الزمنية المزدوجة التي يجب أن تُطلق معًا قبل الإنذار.

التطبيق في Prometheus و Alertmanager

يستخدم نمط PromQL دالتي increase() أو rate() على كل نافذة ثم يقسم على معدل ميزانية الخطأ. النهج الأمثل هو تسجيل قاعدة تسجيل job:slo_errors:rate5m وبناء التنبيهات عليها. في ما يلي مثال كامل جاهز للإنتاج لـ SLO توافر بنسبة 99.9 % على خدمة HTTP:

# recording_rules.yml — حساب معدلات الخطأ لكل نافذة مسبقًا groups: - name: slo_http_availability interval: 30s rules: - record: job:http_errors:rate5m expr: | sum by (job) (rate(http_requests_total{status=~"5.."}[5m])) / sum by (job) (rate(http_requests_total[5m])) - record: job:http_errors:rate30m expr: | sum by (job) (rate(http_requests_total{status=~"5.."}[30m])) / sum by (job) (rate(http_requests_total[30m])) - record: job:http_errors:rate1h expr: | sum by (job) (rate(http_requests_total{status=~"5.."}[1h])) / sum by (job) (rate(http_requests_total[1h])) - record: job:http_errors:rate6h expr: | sum by (job) (rate(http_requests_total{status=~"5.."}[6h])) / sum by (job) (rate(http_requests_total[6h]))
# alerts.yml — تنبيهات SLO متعددة النوافذ متعددة معدلات الاستهلاك (هدف 99.9% → ميزانية = 0.001) groups: - name: slo_http_alerts rules: # المستوى 1: معدل الاستهلاك ≥ 14.4 لمدة 5 دقائق و1 ساعة - alert: HttpAvailabilityCritical expr: | job:http_errors:rate5m{job="api"} > (14.4 * 0.001) and job:http_errors:rate1h{job="api"} > (14.4 * 0.001) for: 2m labels: severity: critical slo: http_availability annotations: summary: "SLO CRITICAL: {{ $labels.job }} burning budget at 14x rate" description: "Error rate {{ $value | humanizePercentage }}. Budget exhausted in ~2h." runbook: "https://wiki.example.com/runbook/slo-critical" # المستوى 2: معدل الاستهلاك ≥ 6 لمدة 30 دقيقة و6 ساعات - alert: HttpAvailabilityHigh expr: | job:http_errors:rate30m{job="api"} > (6 * 0.001) and job:http_errors:rate6h{job="api"} > (6 * 0.001) for: 5m labels: severity: high slo: http_availability annotations: summary: "SLO HIGH: {{ $labels.job }} burning budget at 6x rate" description: "Budget will exhaust in ~5 days at current rate."
شرط "for" والنافذة المزدوجة يؤديان دورين مختلفين. for: 2m في Prometheus يعني أن الشرط يجب أن يكون صحيحًا باستمرار لمدة دقيقتين قبل الإطلاق. مقترنًا بشرط AND للنافذتين، تحصل على ثلاثة مرشحات مستقلة للضوضاء: يجب أن يكون كلا معدلي الخطأ مرتفعَين، وأن يستمر هذا الارتفاع. أزِل أيًا منها وستعود التنبيهات الكاذبة.

التوجيه والتثبيط في Alertmanager

ضبط العتبات ليس سوى نصف المهمة. وجِّه تنبيهات المستوى 1 و2 إلى PagerDuty مع repeat_interval مدته 30 دقيقة؛ ووجِّه المستوى 3 إلى Jira أو Slack. أضف قاعدة تثبيط حتى عندما يُطلَق تنبيه critical لخدمة ما، يُكتَم تنبيه high للخدمة ذاتها — وإلا سيتلقى المناوب إنذارَين لنفس الحادثة.

# alertmanager.yml — التوجيه والتثبيط route: group_by: [job, slo] group_wait: 30s group_interval: 5m repeat_interval: 30m receiver: slack-ops routes: - matchers: - severity =~ "critical|high" receiver: pagerduty-oncall continue: false - matchers: - severity = "ticket" receiver: jira-slo inhibit_rules: - source_matchers: - severity = critical target_matchers: - severity = high equal: [job, slo] # اكتم "high" عندما يُطلَق "critical" لنفس الخدمة والـ SLO

SLOs الكمون ومشكلة الرسم البياني

تتبع SLOs الكمون نفس حساب معدل الاستهلاك، لكن يجب أن يأتي مؤشر الخدمة من رسم بياني تراكمي (histogram) لا من مقياس عادي. المقياس الصحيح هو نسبة الطلبات المُستجاب لها دون عتبة الكمون المستهدفة. استخدام متوسط الكمون كمؤشر هو خطأ على مستوى الإنتاج — المتوسطات تخفي الذيل الطويل حيث يشعر المستخدمون بالألم فعلًا.

# مؤشر الكمون: نسبة الطلبات المكتملة في أقل من 200 مللي ثانية (هدف 99.9% → ميزانية 0.001) - record: job:http_latency_ok:rate5m expr: | sum by (job) (rate(http_request_duration_seconds_bucket{le="0.2",job="api"}[5m])) / sum by (job) (rate(http_request_duration_seconds_count{job="api"}[5m])) # تنبيه معدل الاستهلاك على الكمون (المستوى 1) - alert: HttpLatencyCritical expr: | (1 - job:http_latency_ok:rate5m{job="api"}) > (14.4 * 0.001) and (1 - job:http_latency_ok:rate1h{job="api"}) > (14.4 * 0.001) for: 2m labels: severity: critical slo: http_latency

أنماط مضادة لإجهاد التنبيهات

حتى مع منطق النوافذ المتعددة، تتراكم لدى الفرق الإجهادُ من خلال أخطاء متكررة:

  • ضبط عتبة معدل الاستهلاك منخفضة جدًا — عتبة 2× تعني التنبيه عند معدل خطأ 0.2 % لـ SLO بنسبة 99.9 %. ستُطلَق عدة مرات أسبوعيًا على الخدمات السليمة.
  • تجاهل سياق ميزانية الخطأ — تنبيه يُطلَق عند معدل استهلاك 3 على خدمة تمتلك 25 يومًا من الميزانية المتبقية هو معلوماتي لا حرج.
  • عدم مراجعة سجل التنبيهات شهريًا — تُلزم Google بأن كل إنذار إما يفضي إلى إصلاح أو تغيير في العتبة. إذا أُطلِق نفس التنبيه دون أي إجراء، فالعتبة خاطئة.
ممارسة الإنتاج: ضع تعليقًا على التنبيهات يُظهر الميزانية المستهلكة. أضف استعلام PromQL إلى تعليق التنبيه يُظهر كم دقيقة من ميزانية الخطأ استُهلكت في الشهر الحالي. يدعم كل من Grafana OnCall وPagerDuty وضع نتائج استعلامات Prometheus في نص الحادثة. يتخذ مهندس المناوبة قرارات فرز أفضل عندما يرى فورًا "14 دقيقة من ميزانية شهرية مدتها 43 دقيقة مستهلكة" بدلًا من "معدل خطأ 1.44 %" المبهمة.
التسميات عالية الأساسية تُدمر قواعد التسجيل متعددة النوافذ. إذا قمت بالتجميع حسب user_id أو request_id في قواعد التسجيل، فإن تشعب السلاسل الزمنية الناتج سيُشغّل الذاكرة في Prometheus. اجمع دائمًا على مستوى الخدمة أو الوظيفة قبل حساب معدلات الاستهلاك. استخدم النماذج والتتبع (الموضح في درس التتبع الموزع) للتعمق في الطلبات الفردية بعد إطلاق التنبيه.

ربط التنبيهات بميزانيات الخطأ

الانضباط الأخير: كل تنبيه من المستوى 1 أو 2 يُطلَق يجب أن يظهر في تقرير ميزانية الخطأ. تتبع أوقات بدء وانتهاء كل حدث استنزاف للميزانية، واحسب كم دقيقة من الميزانية استُهلكت. هذه البيانات تُغذي المراجعة الفصلية لـ SLO التي تقرر فيها ما إذا كنت ستُشدد الهدف أو تُرخيه أو تستثمر وقت الهندسة في تحسينات الموثوقية. دون حلقة التغذية الراجعة هذه، تتحجر عتبات التنبيه وتنجرف عن الموثوقية الفعلية التي يختبرها مستخدموك.