كلاود
development

نشر بدون توقف: استراتيجيات Blue-Green وRolling وSymlink عملياً

كلاود|١٦ سبتمبر ٢٠٢٦|6 دقائق قراءة|٢٠٩ مشاهدة
نشر بدون توقف: استراتيجيات Blue-Green وRolling وSymlink عملياً

النشر بدون توقف ثلاث طرق: تبديل رابط رمزي على سيرفر واحد يكفي أغلب التطبيقات، وBlue-Green بنسختين متوازيتين للترقيات الحرجة، وRolling عبر عدة سيرفرات خلف موازن. الفرق في التكلفة والتعقيد لا في النتيجة.

النشر بدون توقف يعني تحديث تطبيقك دون أن يرى أي زائر خطأ أو صفحة صيانة، ويتحقق بثلاث استراتيجيات مرتبة من الأبسط للأعقد. الأولى: تبديل الرابط الرمزي (Symlink releases)، وهي كافية لأغلب تطبيقات PHP وLaravel على سيرفر واحد، تبني الإصدار الجديد في مجلد منفصل ثم تحوّل رابطاً رمزياً واحداً باسم current نحوه في عملية شبه لحظية. الثانية: Blue-Green، تشغّل نسختين كاملتين متطابقتين (زرقاء حية وخضراء جديدة) وتحوّل الحركة كلها دفعة واحدة بعد التأكد، وتحتاج ضعف الموارد أو سيرفرين. الثالثة: Rolling، تحدّث عدة سيرفرات واحداً تلو الآخر خلف موازن أحمال، فتبقى الخدمة قائمة على البقية أثناء التحديث.

لأغلب الشركات ذات النظام المخصص على خادم سحابي واحد، تبديل الرابط الرمزي (نمط Deployer وEnvoyer) هو الخيار الصحيح: صفر توقف، تراجع فوري، وبلا تكلفة إضافية. لا تحتاج Blue-Green أو Rolling إلا عند ترقية إصدار PHP نفسه، أو تغيير بنية قاعدة البيانات بشكل غير متوافق، أو عند تشغيل عدة سيرفرات أصلاً. المشكلة الحقيقية في كل الطرق ليست التبديل، بل الحالة المشتركة: الجلسات والكاش والملفات المرفوعة وهجرات قاعدة البيانات. نفصّل الطرق الثلاث بالأرقام والخطوات ثم نعالج الحالة المشتركة.

مقارنة الاستراتيجيات الثلاث

المعيارSymlinkBlue-GreenRolling
عدد السيرفرات11 بموارد مضاعفة أو 22 أو أكثر
زمن التوقفصفرصفرصفر
سرعة التراجعفوري (تبديل الرابط)فوري (تحويل الحركة)تدريجي
التعقيدمنخفضمتوسطعالٍ
التكلفة الإضافيةلا شيءضعف الموارد لحظة النشرعدة سيرفرات + موازن
الأنسب لـتطبيق PHP/Laravel على سيرفر واحدترقيات حرجة، تغيير إصدار المنصةحركة عالية موزّعة

الاستراتيجية الأولى: تبديل الرابط الرمزي

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

  • releases/: كل إصدار في مجلد باسم التاريخ والوقت.
  • current: رابط رمزي يشير إلى الإصدار الحي.
  • shared/: ملفات ثابتة عبر الإصدارات (env، ملفات مرفوعة، سجلّات).

خطوة التبديل نفسها آمنة لأن ln -sfn على لينكس عملية ذرية، فلا توجد لحظة يكون فيها current معطوباً. الطلب الجاري يكمل على الإصدار القديم، والطلب التالي يبدأ على الجديد. للتراجع، تعيد الرابط إلى الإصدار السابق في أقل من ثانية. احتفظ بآخر خمسة إصدارات لتراجع سريع واحذف الأقدم لتوفير المساحة، فكل إصدار يستهلك من مساحة القرص، وأضف 100GB SSD بـ500 ريال سنوياً إن لزم.

خطوات نشر عملية بتبديل الرابط

التدفق النموذجي لنشرة واحدة يمر بهذه الخطوات المرتبة:

  • اسحب الكود الجديد إلى مجلد إصدار جديد بطابع زمني داخل releases.
  • اربط الملفات المشتركة (env والملفات المرفوعة) من مجلد shared إلى الإصدار الجديد.
  • ثبّت الحزم (composer install) وابنِ الأصول (npm build) داخل الإصدار الجديد وهو خارج الخدمة.
  • شغّل هجرات قاعدة البيانات المتوافقة للأمام.
  • بدّل رابط current نحو الإصدار الجديد بأمر ln -sfn الذري.
  • أعد تحميل PHP-FPM لتفريغ opcache من ملفات الإصدار القديم.
  • تحقق من صحة الإصدار الجديد، ولو فشل أعد الرابط للسابق فوراً.

خطوة حاسمة: أعد تحميل PHP-FPM بعد التبديل

PHP يخزّن مسارات الملفات في opcache، فبعد تبديل الرابط قد يخدم FPM ملفات الإصدار القديم من الكاش. الحل تشغيل reload لـPHP-FPM بعد التبديل، أو تفعيل opcache.revalidate_freq، وهذا خطأ شائع يجعل النشر يبدو ناجحاً بينما المستخدمون على كود قديم.

الاستراتيجية الثانية: Blue-Green

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

الاستراتيجية الثالثة: Rolling

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

الحالة المشتركة: أين تقع الأعطال فعلاً

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

  • الجلسات (Sessions): لو خزّنت الجلسات في ملفات داخل مجلد الإصدار، يخرج كل مستخدم عند كل نشر. خزّنها في Redis أو قاعدة البيانات أو مجلد shared ثابت.
  • الكاش: امسح كاش الإعداد والمسارات بعد التبديل لا قبله، وأعد بناءه على الإصدار الجديد، وإلا يخدم مسارات قديمة.
  • الملفات المرفوعة: ضعها في مجلد shared خارج الإصدارات، وإلا تختفي مع حذف الإصدارات القديمة.
  • هجرات قاعدة البيانات: اجعلها متوافقة للأمام والخلف. أضف الأعمدة قبل نشر الكود الذي يستخدمها، واحذف القديمة في نشرة لاحقة بعد أن يستقر الجديد، فلا يكسر إصدار واحد الآخر أثناء التداخل.
  • الطوابير (Queues): أعد تشغيل عمّال الطابور بعد النشر ليحمّلوا الكود الجديد، فهم لا يلتقطون التغيير تلقائياً.
  • المهام المجدولة (Cron): تأكد أنها تشير إلى current لا إلى مسار إصدار قديم محذوف.

التحقق من الصحة قبل إعلان النجاح

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

أتمتة النشر بأداة

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

القرار العملي

لأغلب الشركات: ابدأ بتبديل الرابط الرمزي على سيرفر واحد، فهو صفر توقف وصفر تكلفة وتراجع فوري، ويكفي 95% من الحالات. انتقل إلى Blue-Green فقط عند ترقية إصدار المنصة أو تغيير جذري في البيئة. لا تلجأ إلى Rolling إلا لو كنت تشغّل عدة سيرفرات خلف موازن أصلاً. في كل الطرق، ثبّت الحالة المشتركة أولاً: جلسات في Redis، ملفات مرفوعة في shared، هجرات متوافقة، إعادة تحميل FPM بعد التبديل، وفحص صحة تلقائي. رتّب هذه العناصر مرة واحدة، ويصبح كل نشر لاحق حدثاً غير مرئي لعملائك.

مشاركة