مشروع: خطة التسليم التدريجي
مشروع: خطة التسليم التدريجي
كل مفهوم في هذا الدرس — إصدارات الكناري، وأعلام الميزات، والتراجع، والتحليل الآلي، ونمط التوسع والتقليص — موجود لحل مشكلة واحدة: كيف تشحن تغييراً لخدمة بالغة الأهمية دون التسبب في انقطاع؟ يأخذك هذا الدرس الختامي خطوة بخطوة عبر تصميم نظام تسليم تدريجي متكامل وجاهز للإنتاج لخدمة عالية المخاطر: معالج مدفوعات يتعامل مع آلاف المعاملات في الدقيقة.
ستصمم النظام بالكامل من البداية إلى النهاية: مسار الكناري، وتسلسل الأعلام، وبوابات الترقية المقيّدة بـ SLO، واستراتيجية هجرة قاعدة البيانات، ودليل التراجع. هذه هي الطريقة التي تقترب بها فرق في Stripe وAmazon وGoogle من إصدارات مساراتهم الأكثر أهمية.
الخطوة 1 — رسم خريطة المخاطر
قبل كتابة ملف YAML واحد، احصِ ما يمكن أن يسوء. لكل خطر، ستعيّن إجراء تخفيف من مجموعة أدوات التسليم التدريجي:
- منطق التوجيه الجديد يرفض بطاقات صالحة — التخفيف: كناري بنسبة 1%، بوابة آلية لمعدل الأخطاء، مفتاح إيقاف طارئ عبر علم.
- تراجع في الأداء (الكمون) في المحرك الجديد — التخفيف: بوابة SLO لكمون p99؛ تراجع تلقائي إذا تجاوز p99 الـ 200ms لمدة 5 دقائق.
- مخطط قاعدة البيانات غير متوافق بين الكود القديم والجديد — التخفيف: هجرة بنمط التوسع والتقليص مع فترة كتابة مزدوجة.
- تحويل العملات الديناميكي يسبب أخطاء في التقريب — التخفيف: علم تحويل العملات يبدأ معطلاً؛ تجربة A/B مع بوابة دلالة إحصائية قبل الطرح الكامل.
- واجهة برمجة أسعار صرف طرف ثالث معطلة — التخفيف: مفتاح إيقاف طارئ للعمليات يعطّل التحويل الديناميكي ويعود فوراً للأسعار الثابتة.
الخطوة 2 — تصميم تسلسل الأعلام
تحتاج إلى ثلاثة أعلام متمايزة لهذا الإصدار، لكل منها دورة حياة مختلفة ومالك مختلف:
payments.new-router.enabled— علم إصدار. يتحكم في ما إذا كان حجم حركة المرور يمر عبر محرك التوجيه الجديد أصلاً. هذا هو مفتاح الإيقاف الرئيسي. القيمة الافتراضية:false. تاريخ الإزالة: 30 يوماً بعد الطرح بنسبة 100%.payments.dynamic-currency.enabled— علم تجربة. يتحكم في ما إذا كانت أسعار صرف ديناميكية تُعرض على المستخدم. يبدأ من 0%. مقيّد بالدلالة الإحصائية (p-value < 0.05، حد أدنى 10,000 تحويل لكل نسخة). تاريخ الإزالة: 14 يوماً بعد إعلان الفائز.payments.new-router.circuit-open— علم عمليات. عندما يكونtrue، يُحوّل فوراً 100% من حجم حركة المرور إلى المحرك القديم بصرف النظر عن أي علم آخر. هذا قاطع الدائرة الطارئ، ليس نفس التراجع — يعمل في ثوانٍ. طويل الأمد؛ يمتلكه فريق الاستجابة لدفعات المدفوعات بشكل دائم.
true، تحويل فوري إلى المسار القديم — لا تقيّم الأعلام الأدنى. هذا يضمن أن مفتاح الإيقاف يعمل في أقل من 10ms حتى تحت الحمل الشديد.
الخطوة 3 — تصميم مسار الكناري
مسار الكناري هو الإطار الذي ينقل payments.new-router.enabled من 0% إلى 100% بأمان. كل مرحلة لها معايير دخول صريحة (مقاييس SLO يجب أن تكون ناجحة) ومعايير خروج (مقاييس SLO إذا انتُهكت تُطلق تراجعاً تلقائياً).
رمّز هذا المسار كمانيفست Argo Rollouts حتى تكون التنسيقية محفوظة في نظام التحكم بالإصدارات وقابلة للتكرار:
الخطوة 4 — ربط التحليل الآلي
تُطبَّق بوابات SLO عبر AnalysisTemplate يستعلم من منظومة الرصد كل 5 دقائق. إذا انتهك أي مقياس حده، يتوقف Argo Rollouts ويُنبّه مهندس الاستجابة:
الخطوة 5 — تصميم هجرة قاعدة البيانات
يتطلب المحرك الجديد عموداً جديداً fx_rate_snapshot على جدول payment_transactions. هذا جدول على المسار الحرج يحتوي على 50 مليون سجل. لا يمكنك تنفيذ ALTER TABLE محجِّب في الإنتاج. استخدم نمط التوسع والتقليص عبر ثلاث عمليات نشر:
- التوسع (النشر رقم N): أضف العمود بصفة
NULLABLEبدون قيمة افتراضية — صفر توقف على MySQL/Postgres معALGORITHM=INSTANT. الكود القديم يتجاهل العمود. الكود الجديد يكتب فيه. يعمل الكودان في وقت واحد خلال نافذة الكناري. - الهجرة (النشر رقم N): شغّل مهمة خلفية عبر عامل يتحكم فيه علم لملء العمود للسجلات الموجودة على دفعات من 1,000 سجل مع توقف 10ms بين الدفعات لتجنب ضغط الإدخال/الإخراج على الخادم الرئيسي.
- التقليص (النشر رقم N+1، بعد الطرح الكامل): بعد التقاعد الكامل للكود القديم، أضف قيد
NOT NULLواحذف منطق الكتابة المزدوجة. هذا النشر التنظيفي — لا تشحنه قبل مرور 72 ساعة من الطرح الكامل للسماح بالتراجع الطارئ دون كسر عقد العمود.
الخطوة 6 — دليل التراجع
خطة التراجع المكتوبة خلال حادثة هي خطة سيئة. اكتبها قبل النشر واربطها من وصف طلب السحب. لهذه الخدمة، هناك ثلاثة محفزات للتراجع وثلاثة مستويات استجابة:
- المستوى 1 — تلقائي (0 إلى 60 ثانية): يكتشف Argo Rollouts انتهاك SLO عبر AnalysisTemplate. يضع الطرح في حالة
Pausedوينبّه مهندس الاستجابة. يشغّل المهندسkubectl argo rollouts abort payment-routerلتحويل 100% من حجم حركة المرور فوراً إلى البودات المستقرة. - المستوى 2 — قاطع الدائرة (0 إلى 10 ثوانٍ): إذا كان التراجع الآلي بطيئاً أو غير متاح، يقلب مهندس الاستجابة
payments.new-router.circuit-openإلىtrueفي لوحة الأعلام. يعود حجم حركة المرور إلى المسار القديم خلال دورة استطلاع واحدة. هذا أسرع من طرح Kubernetes لأنه لا يتطلب إعادة تشغيل البودات. - المستوى 3 — تراجع كامل (30 إلى 120 دقيقة): للأعطال الكارثية حيث البرنامج الثنائي الجديد نفسه تالف أو الحاوية لا تستطيع الإقلاع، أعِد رقم SHA في Git وشغّل بناء CI جديداً. هذا المسار نادر وبطيء — يجب أن يتعامل المستويان الأولان مع 99.9% من الحوادث.
الخطوة 7 — ربط كل شيء معاً
خطة التسليم التدريجي ليست مجرد تهيئة تقنية — إنها بروتوكول تواصل لمنظمتك بأكملها. قبل دمج أول PR لهذا الإصدار، يجب أن توجد المخرجات التالية ومرتبطة من وصف طلب السحب:
- وثيقة سطح المخاطر — الجدول من الخطوة 1، مراجَع من قِبَل قائد الفريق وفريق الاستجابة.
- قيد سجل الأعلام — الأعلام الثلاثة مسجّلة في لوحة إدارة الأعلام مع المالك وتاريخ الإزالة والوصف.
- YAML الطرح في Git — مانيفست Argo Rollouts محفوظ في نظام التحكم بالإصدارات بجوار كود الخدمة، لا يُدار بشكل عشوائي.
- AnalysisTemplate في Git — عتبات SLO مُراجَعة كـ-كود، لا يضبطها مهندس واحد في واجهة مستخدم منتصف الليل.
- دليل التراجع مرتبط من PagerDuty — عندما يُوقَظ مهندس الاستجابة الساعة 2 صباحاً، يكون الدليل هو أول رابط في تنبيه PagerDuty.
- تذاكر التنظيف المجدوَلة — ثلاث تذاكر Jira مُنشأة في اليوم الأول: إزالة علم الإصدار، تطبيق قيد NOT NULL، حذف كود التوجيه القديم. لكل منها تاريخ استحقاق ومالك.
هذا هو المعيار الذي تضع به منظمات الهندسة من المستوى الأول نفسها. يستغرق بناؤه وقتاً واستثماراً، لكن المردود يُقاس بالحوادث التي لا تحدث أبداً — النجاحات الخفية التي تُعرّف هندسة الموثوقية العالمية المستوى.