خطای 502 Bad Gateway چیست و چطور رفع می شود؟

خطای 502 Bad Gateway یعنی سروری که درخواست شما را گرفته، معمولاً Nginx یا یک لودبالانسر یا Cloudflare، آن را به سرویس پشت خودش فرستاده و پاسخ درستی برنگشته است. این سرویس پشتی می‌تواند PHP-FPM، یک برنامه Node.js یا پایتون، یا Apache پشت Nginx باشد. در بیشتر موارد مشکل روی سرور است و از مرورگر یا اینترنت بازدیدکننده نیست.

اگر فقط بازدیدکننده سایت هستید، کار زیادی از دستتان برنمی‌آید: چند ثانیه بعد صفحه را دوباره باز کنید و اگر خطا ماند، به مدیر سایت خبر بدهید. بقیه این راهنما برای کسی است که به سرور یا هاست دسترسی دارد و می‌خواهد علت را پیدا کند. دستورها برای Ubuntu و Debian نوشته شده‌اند و تفاوت‌های AlmaLinux و Rocky جداگانه آمده است.

خطای 502 دقیقاً کجا اتفاق می‌افتد؟

درخواست مرورگر اول به وب‌سرور جلویی می‌رسد. Nginx فایل‌های ثابت مثل تصویر و CSS را خودش می‌دهد، ولی برای صفحه‌های PHP یا برنامه‌ها، درخواست را به سرویس دیگری پاس می‌دهد که به آن upstream می‌گویند. اگر این سرویس خاموش باشد، اتصال را رد کند، وسط کار قطع شود یا پاسخ نامعتبر بدهد، Nginx به مرورگر 502 برمی‌گرداند. اگر upstream زنده باشد ولی بیش از حد طول بکشد، خطا 504 می‌شود.

کدناممعنای معمول
500Internal Server Errorخود برنامه یا تنظیمات سرور خطا داده، مثلاً خطای PHP یا فایل .htaccess خراب
502Bad Gatewayسرور واسط از upstream پاسخ معتبر نگرفته یا اصلاً به آن وصل نشده
503Service Unavailableسرویس عمداً یا به‌خاطر فشار زیاد موقتاً درخواست نمی‌پذیرد
504Gateway Timeoutupstream جواب داده ولی دیرتر از زمان مجاز

تفاوت 502 و 500 در عیب‌یابی مهم است. خطای 500 را معمولاً خود برنامه تولید می‌کند و ردش را در لاگ PHP یا برنامه پیدا می‌کنید. خطای 502 را واسط تولید می‌کند و اولین جایی که باید نگاه کنید لاگ همان واسط است. اگر با خطای 500 سروکار دارید، راهنمای خطای 500 Internal Server Error را ببینید.

اول لاگ خطای Nginx را بخوانید

بیشتر وقت‌ها علت در یک خط از لاگ نوشته شده است. خطا را یک بار دیگر در مرورگر تکرار کنید و بلافاصله انتهای لاگ را ببینید:

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

اگر برای هر سایت لاگ جدا تعریف کرده‌اید، مسیر آن را در بلوک server فایل کانفیگ سایت، جلوی error_log پیدا می‌کنید. پیام‌های زیر رایج‌ترین‌ها هستند:

بخشی از پیام در لاگمعنی
(2: No such file or directory) while connecting to upstreamفایل سوکت PHP-FPM وجود ندارد؛ سرویس خاموش است یا مسیر اشتباه است
(13: Permission denied) while connecting to upstreamNginx اجازه دسترسی به سوکت را ندارد، یا SELinux اتصال را بسته است
(111: Connection refused) while connecting to upstreamروی آن آدرس و پورت کسی گوش نمی‌دهد
upstream prematurely closed connectionupstream وسط پاسخ قطع شده؛ معمولاً کرش پروسه یا کمبود حافظه
upstream sent too big headerهدر پاسخ از بافر Nginx بزرگ‌تر است
(11: Resource temporarily unavailable)صف اتصال PHP-FPM پر شده است

علت‌های رایج خطای 502 و راه رفع هر کدام

PHP-FPM خاموش است یا بالا نمی‌آید

اول وضعیت سرویس را ببینید. عدد نسخه را با نسخه PHP سرور خودتان عوض کنید:

systemctl status php8.3-fpm
sudo journalctl -u php8.3-fpm -n 50 --no-pager

اگر سرویس بعد از تغییر تنظیمات بالا نمی‌آید، معمولاً فایل کانفیگ خطای نگارشی دارد. پیش از ری‌استارت، کانفیگ را تست کنید تا خطا را با شماره خط ببینید:

sudo php-fpm8.3 -t
sudo systemctl restart php8.3-fpm

مسیر سوکت یا پورت با کانفیگ Nginx نمی‌خواند

مقدار fastcgi_pass در کانفیگ سایت باید دقیقاً با listen در فایل pool یکی باشد. در Ubuntu این فایل معمولاً /etc/php/8.3/fpm/pool.d/www.conf است. این اشتباه بیشتر بعد از ارتقای نسخه PHP پیش می‌آید: سوکت از php8.1-fpm.sock به php8.3-fpm.sock عوض شده ولی کانفیگ Nginx هنوز نسخه قبلی را صدا می‌زند.

grep -R "fastcgi_pass" /etc/nginx/sites-enabled/
grep "^listen" /etc/php/8.3/fpm/pool.d/www.conf
ls -l /run/php/

دسترسی به سوکت (Permission denied)

Nginx در Ubuntu با کاربر www-data اجرا می‌شود و باید بتواند روی سوکت بنویسد. در فایل pool این سه خط را بررسی کنید و بعد PHP-FPM را ری‌استارت کنید:

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

در AlmaLinux و Rocky کاربر پیش‌فرض Nginx خود nginx است و سوکت معمولاً در /run/php-fpm/www.sock قرار دارد، پس مقدارها را متناسب با همان تنظیم کنید.

ظرفیت PHP-FPM پر شده است

وقتی همه پروسه‌های PHP-FPM مشغول باشند، درخواست‌های تازه در صف می‌مانند و بسته به تنظیمات به 502 یا 504 می‌رسند. نشانه‌اش این پیام در لاگ PHP-FPM است:

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

بالا بردن pm.max_children بدون حساب کار خطرناکی است، چون اگر حافظه کم بیاید سرور به swap می‌افتد یا پروسه‌ها کشته می‌شوند. اول میانگین مصرف حافظه هر پروسه را بگیرید:

ps --no-headers -o rss -C php-fpm8.3 | awk '{s+=$1} END {print s/NR/1024 " MB"}'

بعد حافظه‌ای را که برای PHP کنار گذاشته‌اید، بعد از کم کردن سهم دیتابیس و سیستم‌عامل، بر این عدد تقسیم کنید. مثلاً با ۲ گیگابایت حافظه آزاد برای PHP و میانگین ۶۰ مگابایت، حدود ۳۰ پروسه قابل تحمل است. اگر پروسه‌ها به‌خاطر کوئری‌های کند دیتابیس طولانی شده‌اند، بالا بردن این عدد فقط مشکل را عقب می‌اندازد. در این حالت سراغ بهینه سازی دیتابیس بروید.

کمبود حافظه و OOM Killer

اگر در لاگ Nginx پیام upstream prematurely closed را می‌بینید و خطا نامنظم است، احتمال دارد کرنل پروسه‌ها را به‌خاطر کمبود حافظه کشته باشد:

sudo journalctl -k | grep -i "killed process"
free -m

راه‌حل یا کم کردن مصرف است (تعداد پروسه‌ها، کش‌های بزرگ، سرویس‌های اضافه) یا افزایش حافظه سرور. دستورهای بیشتر برای بررسی مصرف منابع در دستورات مانیتورینگ سرور لینوکس آمده است.

هدر پاسخ از بافر بزرگ‌تر است

پیام upstream sent too big header معمولاً وقتی دیده می‌شود که برنامه کوکی یا هدرهای حجیم برمی‌گرداند. بافر را در بلوک location مربوط به PHP بزرگ‌تر کنید:

fastcgi_buffer_size 32k;
fastcgi_buffers 16 16k;

اگر Nginx با proxy_pass به یک برنامه وصل است، معادل آن proxy_buffer_size و proxy_buffers است. بعد از هر تغییر، کانفیگ را تست و Nginx را reload کنید:

sudo nginx -t && sudo systemctl reload nginx

برنامه پشت proxy_pass جواب نمی‌دهد

برای برنامه‌های Node.js، پایتون یا کانتینر Docker، از خود سرور مستقیم سراغ upstream بروید. اگر این درخواست هم خطا بدهد، مشکل از برنامه است و نه از Nginx:

curl -I http://127.0.0.1:3000
ss -ltnp | grep 3000

یک اشتباه رایج این است که برنامه فقط داخل کانتینر روی یک پورت گوش می‌دهد و پورت به میزبان منتشر نشده، یا برنامه روی آدرس دیگری غیر از آنچه در proxy_pass نوشته‌اید بالا آمده است. مفاهیم این نوع اتصال در راهنمای Reverse Proxy چیست توضیح داده شده است.

SELinux در AlmaLinux و Rocky

روی توزیع‌های خانواده RHEL، SELinux به‌طور پیش‌فرض اجازه نمی‌دهد Nginx به پورت‌های شبکه دلخواه وصل شود. در این حالت لاگ Nginx خطای Permission denied نشان می‌دهد، با اینکه دسترسی فایل‌ها درست است. این دستور اتصال را مجاز می‌کند:

sudo setsebool -P httpd_can_network_connect 1

خاموش کردن کامل SELinux راه درستی نیست و یک لایه امنیتی سرور را از بین می‌برد.

خطای 502 در Cloudflare

اگر صفحه خطا لوگو و طراحی Cloudflare را دارد و در آن نوشته Cloudflare کار می‌کند ولی Host خطا دارد، مشکل روی سرور اصلی شماست و Cloudflare فقط پیغام را رسانده است. Cloudflare برای مشکلات اتصال به سرور اصلی کدهای خودش را هم دارد: 521 یعنی وب‌سرور اتصال را رد کرده، 522 یعنی اتصال به سرور در زمان مجاز برقرار نشده، 524 یعنی سرور دیر جواب داده و 525 و 526 به SSL بین Cloudflare و سرور مربوط‌اند.

برای اینکه مطمئن شوید مشکل از سرور است، سایت را بدون Cloudflare و مستقیم روی IP سرور امتحان کنید:

curl -I --resolve example.com:443:SERVER_IP https://example.com/

خطای 502 در هاست اشتراکی و وردپرس

روی هاست اشتراکی دسترسی ری‌استارت PHP-FPM یا خواندن لاگ Nginx را ندارید. در این حالت چند کار از دستتان برمی‌آید: زمان دقیق خطا و آدرس صفحه را یادداشت کنید، اگر خطا فقط در بخش مدیریت یا هنگام یک کار سنگین مثل ساخت بکاپ یا درون‌ریزی محصولات رخ می‌دهد این را هم بنویسید و برای پشتیبانی هاست بفرستید. برای اینکه ببینید افزونه‌ای مقصر است یا نه، از File Manager نام پوشه wp-content/plugins را موقتاً عوض کنید. اگر خطا رفت، افزونه‌ها را یکی‌یکی برگردانید تا مقصر پیدا شود.

اگر این خطا مرتب تکرار می‌شود، احتمالاً منابع هاست برای سایت کافی نیست. برای سایت‌های پرمصرف یا فروشگاهی، هاست وردپرس با منابع متناسب یا سرور مجازی مدیریت‌شده انتخاب بهتری است.

جلوگیری از تکرار خطای 502

خطای 502 را معمولاً اول کاربران می‌بینند، مگر اینکه سرور زیر نظر باشد. چند کار ساده احتمال غافلگیر شدن را کم می‌کند:

  • یک بررسی دسترس‌پذیری (Uptime Check) که هر یک یا دو دقیقه صفحه اصلی را باز کند و با خطای 5xx هشدار بدهد.
  • فعال کردن صفحه وضعیت PHP-FPM با pm.status_path تا تعداد پروسه‌های فعال و صف انتظار را ببینید.
  • هشدار برای مصرف حافظه و swap، چون بیشتر 502های نامنظم از کمبود حافظه شروع می‌شوند.
  • ثبت تغییرات: بیشتر 502ها بلافاصله بعد از ارتقای PHP، نصب افزونه یا تغییر کانفیگ ظاهر می‌شوند.

اگر هنوز مانیتورینگی ندارید، بررسی رایگان سلامت سرور نقطه شروع مناسبی است. برای جزئیات بیشتر درباره تنظیمات Nginx و Apache هم وب سرور لینوکس: نصب و پیکربندی پیشرفته را ببینید.

سوالات متداول

آیا خطای 502 از سمت کاربر است؟

تقریباً هیچ‌وقت. خطا بین وب‌سرور و سرویس پشت آن رخ می‌دهد. فقط در موارد نادر، مثلاً پروکسی یا فیلترینگ شبکه محل کار، ممکن است 502 بین کاربر و سایت ساخته شود. اگر سایت از اینترنت دیگری مثل موبایل درست باز می‌شود، به همین مورد شک کنید.

تفاوت خطای 502 و 504 چیست؟

در 502 واسط اصلاً پاسخ معتبری از upstream نگرفته است: اتصال رد شده، قطع شده یا پاسخ خراب بوده. در 504 اتصال برقرار بوده ولی پاسخ در زمان مجاز نرسیده است. راه‌حل 504 معمولاً پیدا کردن کار کند است، مثل کوئری سنگین یا فراخوانی یک سرویس بیرونی، نه بالا بردن بی‌حساب timeout.

آیا ری‌استارت Nginx خطای 502 را رفع می‌کند؟

گاهی، ولی علت را از بین نمی‌برد. در بیشتر موارد باید upstream یعنی PHP-FPM یا برنامه را بررسی کنید. اگر با ری‌استارت PHP-FPM خطا موقتاً رفع می‌شود و دوباره برمی‌گردد، به کمبود حافظه یا پر شدن ظرفیت پروسه‌ها شک کنید.

خطای 502 روی سئو اثر دارد؟

قطعی کوتاه اثر ماندگاری ندارد. اگر گوگل مدت طولانی با خطای 5xx روبه‌رو شود، سرعت خزیدن در سایت را کم می‌کند و در صورت ادامه، ممکن است آدرس‌ها را از نتایج حذف کند. برای همین 502 تکراری را باید زود ریشه‌یابی کرد.

پاسخی بگذارید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *