المدوّنة · الخوادم ولينكس

«502 Bad Gateway»: ما معناه وكيف تصلحه على Nginx

· 6 دقائق قراءة

«502 Bad Gateway»: ما معناه وكيف تصلحه على Nginx

ظهور رسالة «502 Bad Gateway» يعني أن خادم الويب Nginx يعمل بنجاح واستقبل طلب الزائر، لكنه عندما حاول تمرير هذا الطلب إلى المعالج الخلفي (وعادةً ما يكون معالج لغة بي إتش بي PHP-FPM) لم يتلقَّ استجابة صالحة أو وجده مغلقاً. المشكلة ليست في اتصال جهازك بالإنترنت، ولا في سقوط خادم الويب بالكامل؛ بل في انقطاع حلقة الوصل بين Nginx ومعالج الأكواد البرمجية خلفه.

في بيئات ووردبريس وخوادم لينكس، ينحصر هذا الخطأ غالباً في خمسة أسباب متتالية: توقف خدمة PHP-FPM، أو خطأ في مسار ملف السوكيت (Socket)، أو وصول المعالج للحد الأقصى للذاكرة، أو انتهاء مهلة تنفيذ السكربتات الطويلة، أو تضارب تصاريح المستخدمين.

مخطط انقطاع الاتصال بين خادم الوسيط العكسي Nginx وخادم التطبيق الخلفي
مخطط انقطاع الاتصال: كيف يفشل خادم Nginx في استلام استجابة صالحة من معالج PHP أو التطبيق الخلفي.

الخطوة الأولى: قراءة سجل أخطاء Nginx لمعرفة السبب الدقيق#

قبل تعديل أي ملف، اطلب من Nginx أن يخبرك حرفياً بالسبب وراء إرجاع رمز 502 عبر عرض آخر أسطر في سجل الأخطاء:

sudo tail -n 30 /var/log/nginx/error.log

ستجد في السطر الأخير واحدة من الرسائل القياسية التالية، ولكل منها حل محدد:

السبب 1: خدمة PHP-FPM متوقفة تماماً عن العمل#

نص رسالة السجل:

connect() to unix:/run/php/php8.2-fpm.sock failed (2: No such file or directory)

أو:

connect() to unix:/run/php/php8.2-fpm.sock failed (111: Connection refused)

التشخيص:#

يعني هذا الخطأ أن Nginx يبحث عن معالج PHP في مساره المعتاد لكنه لا يجده يعمل. افحص حالة الخدمة في النظام:

sudo systemctl status php8.2-fpm

(إذا كنت تستخدم إصداراً آخر مثل 8.1 أو 8.3، استبدل الرقم برقم إصدارك المثبت).

إذا ظهرت الحالة باللون الأحمر أو كُتب inactive (dead) أو failed، فالخدمة متوقفة.

الحل:#

أعد تشغيل الخدمة فوراً وتأكد من تفعيلها لتبدأ تلقائياً عند إقلاع الخادم:

sudo systemctl restart php8.2-fpm
sudo systemctl enable php8.2-fpm

أعد تحديث الصفحة في متصفحك؛ إذا عاد الموقع للعمل، فقد حُلّت المشكلة.

السبب 2: تفاوت رقم إصدار PHP أو خطأ في مسار السوكيت#

يحدث هذا غالباً بعد ترقية حزم النظام أو تحديث PHP من إصدار قديم (مثلاً 8.1) إلى إصدار أحدث (مثل 8.2)، فيبقى Nginx يطلب السوكيت القديم المحذوف.

التشخيص:#

تحقق أولاً من ملف السوكيت الفعلي الموجود حالياً داخل مجلد /run/php/:

ls -la /run/php/

انظر إلى الملف الذي ينتهي بـ .sock. لنفترض أنك وجدت الملف باسم: php8.2-fpm.sock.

افحص الآن ملف إعدادات موقعك في Nginx:

sudo nano /etc/nginx/sites-available/example.com

ابحث عن كتلة معالجة ملفات PHP (كتلة location ~ \.php$). ستجد سطراً يشبه:

fastcgi_pass unix:/run/php/php8.1-fpm.sock;

الحل:#

عدل رقم الإصدار ليتطابق تماماً مع الملف الموجود في /run/php/:

fastcgi_pass unix:/run/php/php8.2-fpm.sock;

احفظ الملف، ثم افحص سلامة قواعد Nginx وأعد تحميله:

sudo nginx -t
sudo systemctl reload nginx

السبب 3: اختناق المعالج ونفاد العمليات التابعة (Max Children Reached)#

إذا كان الخطأ يظهر ويختفي بصورة متقطعة (تحديث الصفحة يعمل وتحديث آخر يعيد خطأ)، أو يظهر فقط أثناء ذروة الزيارات، فهذا يعني أن جميع قنوات المعالجة المخصصة لـ PHP مشغولة بالكامل وتتجاهل الطلبات الجديدة. توثيق PHP لا يربط هذه الحالة برمز HTTP بعينه؛ فالرمز الذي يراه الزائر (502 أو 503 أو 504) يتوقف على خادم الويب وإعداداته.

نص رسالة السجل في /var/log/php8.2-fpm.log:#

WARNING: [pool www] server reached pm.max_children setting (5), consider raising it

الحل:#

افتح ملف تكوين مجمع PHP-FPM:

sudo nano /etc/php/8.2/fpm/pool.d/www.conf

ابحث عن الإعدادات التالية وعدلها لتناسب حجم ذاكرة خادمك:

pm = dynamic
pm.max_children = 25
pm.start_servers = 5
pm.min_spare_servers = 3
pm.max_spare_servers = 8
pm.max_requests = 500

انتبه لموارد السيرفر: قيمة pm.max_children تعتمد على الذاكرة العشوائية المتوفرة. إذا كان موقع ووردبريس يستهلك نحو 60 ميجابايت لكل عملية، وسيرفرك يمتلك 2 جيجابايت RAM، فإن قيمة 20 إلى 25 هي الحد الأقصى الآمن لتجنب انهيار الخادم بسبب نفاد الذاكرة (OOM).

بعد الحفظ، أعد تشغيل الخدمة:

sudo systemctl restart php8.2-fpm

السبب 4: انتهاء مهلة استجابة السكربتات (Upstream Timed Out)#

يحدث هذا عند تنفيذ عمليات برمجية تستغرق وقتاً طويلاً (مثل استيراد قاعدة بيانات ضخمة، أو توليد نسخ احتياطي، أو معالجة صور كبيرة)، فيفقد Nginx صبره ويقطع الاتصال قبل أن ينتهي PHP.

نص رسالة السجل:#

upstream timed out (110: Connection timed out) while reading response header from upstream

الحل:#

يجب رفع مهلة الانتظار في Nginx و PHP معاً:

1. في ملف إعدادات Nginx للموقع:

sudo nano /etc/nginx/sites-available/example.com

داخل كتلة location ~ \.php$ أضف قيم المهلة التالية:

fastcgi_read_timeout 300;
fastcgi_send_timeout 300;

لا ترفع fastcgi_connect_timeout معهما؛ فهي مهلة إنشاء الاتصال لا مهلة انتظار الرد، وتوثيق Nginx ينص على أنها لا تتجاوز عادةً 75 ثانية.

2. في ملف php.ini:

sudo nano /etc/php/8.2/fpm/php.ini

عدل القيمتين:

max_execution_time = 300
memory_limit = 256M

ثم أعد تشغيل الخدمتين لتطبيق الإعدادات الجديدة:

sudo systemctl restart php8.2-fpm
sudo systemctl reload nginx

السبب 5: خطأ تصاريح مستخدم ملف السوكيت (Permission Denied)#

إذا كان Nginx يعمل بمستخدم، وPHP-FPM ينشئ السوكيت بمستخدم آخر يمنع Nginx من القراءة والكتابة فيه.

نص رسالة السجل:#

connect() to unix:/run/php/php8.2-fpm.sock failed (13: Permission denied)

الحل:#

افتح ملف /etc/php/8.2/fpm/pool.d/www.conf، وتأكد من أن مستخدم السوكيت ومجموعته يطابقان مستخدم Nginx (وهو www-data في أوبونتو ودبيان):

listen.owner = www-data
listen.group = www-data
listen.mode = 0660

احفظ وأعد تشغيل PHP-FPM:

sudo systemctl restart php8.2-fpm

كيف تتأكد أن الإصلاح نجح تماماً؟#

لا تكتفِ بتحديث صفحة واحدة؛ اختبر الموقع بالخطوات التالية:

  1. فحص الاستجابة عبر cURL: نفذ الأمر التالي في الطرفية للتأكد من استلام رمز النجاح HTTP/2 200 أو HTTP/1.1 200 OK:
    curl -I https://example.com
  2. مراقبة السجلات الحية أثناء التصفح: افتح مراقبة السجل الحي وتصفح صفحات موقعك ولوحة التحكم:
    sudo tail -f /var/log/nginx/error.log
    إذا ظل السجل صامتاً دون تسجيل أسطر جديدة تبدأ بـ [error]، فقد استقر خادمك تماماً.
  3. فحص استهلاك العمليات الحية:
    top -b -n 1 | grep php-fpm
    تأكد من أن عمليات PHP تعمل بنسب استهلاك طبيعية ولا تتجاوز الذاكرة المتاحة.

خلاصة سريعة للتشخيص الطارئ#

رسالة الخطأ في السجل السبب المباشر أمر الحل السريع
Connection refused خدمة PHP-FPM متوقفة sudo systemctl restart php8.2-fpm
No such file or directory مسار السوكيت غير متطابق تعديل مسار fastcgi_pass في Nginx
server reached pm.max_children اختناق العمليات لكثرة الزوار رفع pm.max_children في www.conf
upstream timed out السكربت استغرق وقتاً طويلاً رفع fastcgi_read_timeout إلى 300 ثانية
Permission denied صلاحيات ملف السوكيت غير كافية ضبط listen.owner = www-data في PHP

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

المصادر#

التعليقات

كن أول من يشارك رأيه أو تجربته.

أضف تعليقاً أو سؤالاً

سجّل الدخول لتعجب بالتعليقات المفيدة وترفعها لأعلى النقاش. سجّل الدخول

لا يُنشر، ولا نرسل إليه شيئاً.

يظهر التعليق بعد مراجعته. الروابط لا تُفعَّل.

تبني موقعاً عربياً؟

سكربتات وقوالب وإضافات وخوادم — مصمّمة للمواقع العربية.

تصفّح المنتجات