استراتيجية النشر الخاصة بك تحدد مسبقاً مدى صعوبة عملية الاسترداد

معظم الفرق تتعامل مع الاسترداد كشيء يكتشفونه بعد حدوث العطل. يكتبون سكربت تراجع، يحتفظون بنسخة احتياطية من الأرتيفكت القديم، ويأملون ألا يحتاجوه أبداً. لكن الحقيقة أن أصعب جزء في الاسترداد ليس التراجع نفسه. بل الموقف الذي تجد نفسك فيه عندما تدرك أنك لا تستطيع التراجع بشكل نظيف بسبب طريقة النشر التي اخترتها من البداية.

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

قارن ذلك الآن بفريق يستخدم النشر الأزرق-الأخضر (Blue-Green Deployment). لديهم بيئتان متطابقتان. واحدة تعمل وتخدم المستخدمين. الأخرى تحتوي على الإصدار الجديد جاهز. عندما يحين وقت الإصدار، يقومون فقط بتحويل حركة المرور من البيئة الزرقاء إلى الخضراء. إذا حدث خطأ ما، يعيدون تحويل حركة المرور مرة أخرى. البيئة القديمة لا تزال تعمل. التراجع يستغرق ثوانٍ. لا تغييرات في الكود، لا تغييرات في الإعدادات، لا انتظار حتى ينتهي خط أنابيب (Pipeline).

الفرق ليس في وجود سكربت تراجع أفضل. الفرق هو في اختيار استراتيجية نشر تحد من نصف قطر الانفجار (Blast Radius) قبل حدوث أي خطأ.

النشر الأزرق-الأخضر يجعل الاسترداد شبه فوري

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

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

إليك إعداد خدمة Kubernetes بسيط يجعل التبديل ممكناً. المحدد (Selector) يشير إلى البيئة النشطة، وتغييره من blue إلى green (أو العكس) يعيد توجيه كل حركة المرور فوراً.

apiVersion: v1
kind: Service
metadata:
  name: my-app
spec:
  selector:
    app: my-app
    environment: blue   # قم بالتبديل إلى 'green' للتراجع
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080

عندما يفشل الإصدار الجديد، تقوم بتحديث المحدد إلى environment: green وتطبق التغيير. لا إعادة بناء، لا انتظار لخط الأنابيب — مجرد تحديث لحقل واحد.

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

النشر الكناري (Canary) يحد من عدد المستخدمين المتأثرين

النشر الكناري يتبع نهجاً مختلفاً. بدلاً من تحويل كل حركة المرور دفعة واحدة، ترسل نسبة صغيرة من المستخدمين إلى الإصدار الجديد. ربما خمسة بالمئة. إذا لم تظهر تلك المجموعة أي مشاكل، تزيد النسبة تدريجياً حتى يصبح جميع المستخدمين على الإصدار الجديد.

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

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

المقايضة هي التعقيد. تحتاج إلى منطق توجيه حركة المرور، ومراقبة يمكنها مقارنة المجموعات، وعملية لاتخاذ قرار متى تزيد نسبة الكناري. لكن بالنسبة للفرق التي تنشر بشكل متكرر ولا تستطيع تحمل التراجعات الكاملة، فإن التعقيد يستحق العناء.

أعلام الميزات (Feature Flags) تسمح لك بالاسترداد دون نشر أي شيء

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

إذا حدث خطأ ما، تقوم بإطفاء المفتاح. لا تراجع، لا إصلاح عاجل (Hotfix)، لا انتظار لخط أنابيب. الاسترداد يحدث في ثوانٍ مع تغيير إعداد واحد. هذا هو النهج الأكثر جراحية لتحديد نصف قطر الانفجار. يمكنك تفعيل ميزة للمستخدمين الداخليين أولاً، ثم مستخدمي البيتا، ثم نسبة من حركة مرور الإنتاج، وأخيراً للجميع. في أي نقطة، يمكنك تعطيل الميزة فوراً.

أعلام الميزات قوية، لكن لها تكاليفها الخاصة. تحتاج إلى نظام لإدارة الأعلام، وعملية لتنظيف الأعلام القديمة، وانضباط لتجنب انتشار الأعلام (Flag Sprawl). كل علم في كودك يضيف منطقاً شرطياً يجعل الاختبار أصعب. إذا لم تقم أبداً بإزالة الأعلام بعد استقرار الميزة، تتحول قاعدة الكود الخاصة بك إلى متاهة من الفروع الميتة.

القيمة الحقيقية لأعلام الميزات ليست في النشر بشكل أسرع. إنها في وجود آلية استرداد لا تتطلب نشراً على الإطلاق. هذا يغير ملف المخاطر (Risk Profile) لكل إصدار.

استراتيجية النشر الخاصة بك هي خطة الاسترداد الخاصة بك

إليك الفكرة الأساسية التي تربط كل هذا معاً. لا يمكنك فصل استراتيجية النشر الخاصة بك عن خطة الاسترداد. القرارات التي تتخذها حول كيفية طرح إصدار جديد تحدد خيارات الاسترداد المتاحة لك عندما يحدث خطأ ما.

الرسم البياني أدناه يوضح كيف تتعامل كل استراتيجية مع الفشل، من الاكتشاف إلى الاسترداد.

flowchart TD A[نشر إصدار جديد] --> B{استراتيجية النشر؟} B -->|أزرق-أخضر| C[تحويل حركة المرور إلى البيئة الجديدة] C --> D{هل فشل الإصدار الجديد؟} D -->|نعم| E[إعادة تحويل حركة المرور إلى البيئة القديمة] D -->|لا| F[إبقاء البيئة الجديدة قيد التشغيل] B -->|كناري| G[توجيه 5% من حركة المرور إلى الإصدار الجديد] G --> H{هل توجد أخطاء في الكناري؟} H -->|نعم| I[إيقاف الكناري، إعادة المستخدمين للخلف] H -->|لا| J[زيادة حركة المرور تدريجياً] B -->|أعلام الميزات| K[نشر الكود مخفياً خلف علم] K --> L[تفعيل العلم لمجموعة صغيرة] L --> M{هل تم اكتشاف مشكلة؟} M -->|نعم| N[تعطيل العلم فوراً] M -->|لا| O[توسيع جمهور العلم]

إذا قمت بالنشر عن طريق استبدال جميع الخوادم دفعة واحدة، فإن خيار الاسترداد الوحيد لديك هو التراجع الكامل. إذا كنت تستخدم الأزرق-الأخضر، لديك إمكانية التبديل الفوري. إذا كنت تستخدم الكناري، فإنك تحد من عدد المستخدمين المتأثرين. إذا كنت تستخدم أعلام الميزات، يمكنك تعطيل الميزة الإشكالية دون لمس خط أنابيب النشر.

كل استراتيجية لها مقايضاتها. الأزرق-الأخضر يتطلب بنية تحتية مضاعفة. الكناري يتطلب مراقبة جيدة وتوجيه حركة مرور. أعلام الميزات تتطلب نظام إدارة أعلام وانضباط في التنظيف. لكن جميعها أفضل من عدم وجود استراتيجية والأمل في أن يعمل سكربت التراجع عندما تحتاج إليه.

الفرق التي تتعافى بأسرع وقت ليست تلك التي لديها أفضل سكربتات التراجع. إنها تلك التي صممت عملية النشر الخاصة بها لجعل الاسترداد سهلاً من البداية.

قائمة مراجعة سريعة لنشرك القادم

  • هل يمكنك التراجع دون تغيير الكود أو الإعدادات؟
  • كم عدد المستخدمين الذين سيتأثرون إذا فشل الإصدار الجديد؟
  • هل يمكنك اختبار الإصدار الجديد في الإنتاج دون تعريض جميع المستخدمين؟
  • هل لديك طريقة لتعطيل ميزة معينة دون إعادة النشر؟
  • هل بيئتك القديمة لا تزال قيد التشغيل ومتوافقة مع قاعدة البيانات الحالية؟

إذا أجبت بـ "لا" على معظم هذه الأسئلة، فإن عملية الاسترداد القادمة ستكون أصعب مما ينبغي.

ماذا يعني هذا لفريقك

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