الخطأ ٥٠٢ هو Nginx يقول لك إنه طلب من شيءٍ آخر أن ينتج الصفحة فجاءه جوابٌ لا يصلح. وNginx نفسه يعمل — ولو لم يكن يعمل لما رأيت شيئًا أصلًا — فالعلّة خلفه، وهي في PHP في الغالب الأعمّ.

اعرف أيَّ الأربعة هو

اقرأ سجلّ الأخطاء أوّلًا. فهو يسمّي السبب في سطرٍ واحد، وكلُّ دقيقة تُنفَق في التخمين دقيقةٌ لم تُنفَق في قراءته.

tail -50 /var/log/nginx/error.log
  • connect() failed (111: Connection refused) — خدمة PHP-FPM لا تعمل.
  • upstream timed out — PHP تعمل لكنها استغرقت أطول من المهلة.
  • recv() failed (104: Connection reset by peer) — مات عاملُ PHP في منتصف الطلب، ونفادُ الذاكرة هو السبب عادةً.
  • no live upstreams — لم يبقَ في المجمّع عاملٌ ليجيب.

خدمة PHP-FPM لا تعمل

  1. افحصها — systemctl status php8.3-fpm — الخدمةُ المتوقّفة تقول ذلك في السطر الأول.
  2. شغّلها — systemctl start php8.3-fpm
  3. اعرف لماذا توقّفت — journalctl -u php8.3-fpm --since "1 hour ago" — سطرٌ خاطئ في إعداد مجمّع يوقفها عند الإقلاع، وستتوقّف مرّةً أخرى.
وإن بدأت ثم توقّفت فورًا فشغّل php-fpm8.3 -t. فهو يتحقّق من ملفّات المجمّعات ويسمّي السطر الذي لا يعجبه.

PHP أبطأ من المهلة

الافتراضُ يمنح PHP ستّين ثانية. واستيرادٌ بطيء أو واجهةٌ خارجية توقّفت عن الجواب سيتجاوز ذلك، فيُرجِع Nginx الخطأ ٥٠٢ بدل أن ينتظر إلى الأبد.

location ~ \.php$ {
    fastcgi_read_timeout 300;
}
ورفعُ المهلة يخفي العَرَض. فصفحةٌ تحتاج خمس دقائق تحتاج طابورًا لا انتظارًا أطول — والزائر ينصرف قبل ذلك بكثير.

مات العامل

طلبٌ يتجاوز memory_limit يقتل عامله، فيرى Nginx الاتّصال وقد أُعيد ضبطه. وسجلُّ أخطاء PHP يسمّي الملفّ والسطر.

grep -i "allowed memory size" /var/log/php8.3-fpm.log | tail

لا عمّال في المجمّع

كلُّ عاملٍ مشغول، فلا مكان لطلبٍ جديد. وتلك مشكلةُ سَعة، والعلاج الصادق إمّا طلباتٌ بطيئة أقلّ وإمّا عمّالٌ أكثر — غير أن عمّالًا أكثر على الذاكرة نفسها ينقل العطل لا غير.

pm.max_children = 20
pm.max_requests = 500
على استضافة EGPHP يُدار المجمّع عنك وتُعالَج هذه الحالة قبل أن تراها. وعلى خادمٍ افتراضي فحجمُه أمرك، والرقمُ الذي يهمّ هو ذاكرتك مقسومةً على متوسّط حجم العامل.