نشر PHP بدون توقف: دليل كامل للنشر الآمن | PythonLib

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

عندما تكلفك ثانية التوقف مليونًا

\n\n

تخيل: أنت تُحدّث متجرًا إلكترونيًا يعمل بـ PHP، ترفع الإصدار الجديد عبر FTP، وفجأة يتوقف الموقع لمدة 5 دقائق. خمس دقائق تعني 300 ثانية. خلال هذا الوقت، يغادر 100 عميل محتمل إلى منافسيك، وتخسر ليس فقط المال بل أيضًا السمعة. هل هذا الألم مألوف لك؟

\n\n

في عالم اليوم، حيث لا يغفر المستخدمون الأخطاء، نشر PHP بدون توقف (Zero-Downtime Deployment) ليس ترفًا بل ضرورة حتمية. ولكن كيف تنفذ نشرًا سلسًا إذا كانت بيئتك تعتمد على PHP وNginx وخوادم متعددة؟ دعنا نتعرف على ذلك من خلال أمثلة واقعية.

\n\n

لماذا PHP أصعب مما تبدو؟

\n\n

على عكس Node.js أو Python، لا يدعم PHP تعدد المهام (Multithreading) بالمعنى التقليدي. كل طلب يُعالج بواسطة عملية PHP-FPM منفصلة. هذا يفرض قيودًا: لا يمكنك ببساطة "إعادة تحميل" الكود دون فقدان الجلسات الحالية. لكن هذه الخاصية نفسها تمنحنا قوة هائلة — القدرة على تحويل حركة المرور بسلاسة بين الإصدارات.

\n\n

المشاكل الرئيسية عند نشر PHP:

\n
    \n
  • قطع الاتصالات — يفقد المستخدم بيانات النموذج أو الجلسة
  • \n
  • التخزين المؤقت القذر — يعيد الكود القديم بيانات من ذاكرة تخزين مؤقت قديمة
  • \n
  • ترحيلات قاعدة البيانات المكسورة — الإصدار الجديد من قاعدة البيانات غير متوافق مع الكود القديم
  • \n
\n\n

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

\n\n

الاستراتيجية الأولى: النشر الأزرق-الأخضر (Blue-Green Deployment)

\n\n

الطريقة الأكثر موثوقية هي الاحتفاظ بنسختين كاملتين من التطبيق: "الزرقاء" (الحالية) و"الخضراء" (الجديدة). يعمل Nginx كموازن أحمال.

\n\n

كيف يبدو هذا عمليًا

\n

لنفترض أن لديك خادمين: app1.example.com (أزرق) و app2.example.com (أخضر). كلاهما يشغل PHP-FPM. حاليًا، الخادم الأزرق نشط. تقوم بنشر الإصدار الجديد على الخادم الأخضر، وتختبره، ثم تحوّل Nginx إلى الخادم الأخضر.

\n\n

مثال على إعدادات Nginx للتحويل:

\n\n
# nginx.conf\nupstream php_backend {\n    # في البداية، الخادم الأزرق نشط\n    server app1.example.com:9000 weight=1;  # أزرق\n    server app2.example.com:9000 weight=0;  # أخضر (معطل)\n}\n\nserver {\n    listen 80;\n    server_name myshop.com;\n\n    location ~ \\.php$ {\n        fastcgi_pass php_backend;\n        include fastcgi_params;\n        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;\n    }\n}\n
\n\n

بعد النشر على الخادم الأخضر، نغير الأوزان:

\n\n
# بعد النشر — نوجه حركة المرور\nupstream php_backend {\n    server app1.example.com:9000 weight=0;  # أزرق (معطل)\n    server app2.example.com:9000 weight=1;  # أخضر (نشط)\n}\n
\n\n

نعيد تحميل Nginx دون توقف: nginx -s reload. جميع الاتصالات الحالية تُنهى بشكل صحيح، والجديدة تتجه إلى الخادم الأخضر. نشر PHP بدون توقف مضمون!

\n\n

المزايا والعيوب

\n

المزايا: تحمل كامل للأعطال، يمكنك التراجع بسرعة (ببساطة أعد الأوزان).
\nالعيوب: تحتاج إلى ضعف الموارد (خوادم أو حاويات).

\n\n

الاستراتيجية الثانية: التحديث التدريجي (Rolling Update)

\n\n

إذا كانت ميزانيتك محدودة، استخدم التحديث التدريجي. الفكرة: نقوم بتحديث خوادم PHP واحدًا تلو الآخر، دون إيقاف الباقي. لا يلاحظ المستخدمون أي توقف، لأن Nginx يعيد توجيه الطلبات إلى الخوادم الحية.

\n\n

التنفيذ باستخدام PHP-FPM

\n

لنفترض أن لديك 3 خوادم تعمل بـ PHP-FPM. نخرجها واحدًا تلو الآخر من التناوب، نحدّث الكود، ثم نعيدها.

\n\n

الخطوة 1: إيقاف الخادم عن موازن الأحمال (Graceful Shutdown):

\n\n
# على الخادم الذي نحدّثه\nsudo systemctl stop php8.1-fpm\n# سيتوقف Nginx تلقائيًا عن إرسال الطلبات إلى هذا الخادم لأنه غير متاح\n
\n\n

الخطوة 2: تحديث الكود (عبر git pull أو rsync أو Docker).

\n\n

الخطوة 3: إعادة تشغيل PHP-FPM:

\n\n
sudo                

المدونات

توصيات الكتب