ترقيات بدون توقف

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

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

الخطوة 1: الترقية إلى الإصدار الجديد وتشغيل هجرات آمنة:

  • قم بتحديث جميع الإضافات والقوالب الخاصة بك لتكون متوافقة مع الإصدار الجديد. (هذا يتطلب جهدًا كبيرًا إلى حد ما اعتمادًا على إعدادك).
  • قم بتوليد ملف web_only.yml يحتوي على:
    version: <NEW_VERSION>
    SKIP_POST_DEPLOYMENT_MIGRATIONS=1
  • قم بعمل التمهيد (./launcher bootstrap web_only)
  • أعد تشغيل خوادمك

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

  • قم بتوليد ملف web_only.yml يحتوي على:
    version: <NEW_VERSION>
    SKIP_POST_DEPLOYMENT_MIGRATIONS=0
  • قم بعمل التمهيد (./launcher bootstrap web_only)
  • أعد تشغيل خوادمك

المضاعفات:
قررنا تنفيذ الخطوة 1 و الخطوة 2 في تواريخ مختلفة، مما تسبب في بعض المشاكل. كان هناك إعادة هيكلة كبيرة لنموذج الاستبيانات (polls) بين الإصدارين 2.1 و 2.3. يبدو أنه في البداية كانت معظم بيانات الاستبيانات مخزنة ككائن JSON في جدول post_custom_fields. وبحلول الإصدار 2.3، تم نقلها إلى جدول polls الخاص بها. تطلب ذلك هجرة بيانات تم تنفيذها كجزء من هجرات ما بعد النشر (الخطوة 2).

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

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

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

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

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

سمح لنا هذا بالتحقق من أن إصلاحنا يعمل كما هو متوقع. كما تمكنا من تمهيد صورة جديدة في الإنتاج من نسخة Discourse المعدلة الخاصة بنا التي تحتوي على التصحيح، دون الحاجة إلى الانتظار لإصدار رسمي من Discourse.