خطای 502 Bad Gateway در ظاهر شبیه خطای ۵۰۰ است، ولی از نظر معماری معنای کاملاً متفاوتی دارد: در این خطا، وب‌سرور جلویی پاسخ سالمی از سرویس پشتی نگرفته است. سال‌هاست روی پروژه‌های وردپرسی و سرورهای پرترافیک با این خطا کار می‌کنم و در تجربه‌ام، تفاوت درک همین یک جمله میان «خطای برنامه» و «خطای ارتباط بین سرویس‌ها»، نقطه‌ی تمایز میان چند دقیقه عیب‌یابی و چند ساعت سردرگمی است.

این مقاله را برای عیب‌یابی نظام‌مند نوشته‌ام، نه برای وصل کردن راه‌حل‌های آماده. اگر سایت شما همین حالا خطای ۵۰۲ می‌دهد، ترتیب بخش‌ها همان مسیری است که خودم در بحران‌های واقعی اجرا می‌کنم: اول سرویس را برگردان، بعد ریشه را پیدا کن.

خطای 502 دقیقاً از کجا می‌آید؟

برای درک درست خطای 502 Bad Gateway، باید معماری چندلایه‌ی سرورهای مدرن را بشناسید. در معماری استاندارد، سه لایه‌ی مجزا وجود دارد: لایه‌ی اول وب‌سرور جلویی (معمولاً Nginx یا Apache acting as proxy)، لایه‌ی دوم سرویس اجرای PHP (معمولاً PHP-FPM یا PHP-FPM pooling)، و لایه‌ی سوم دیتابیس و سرویس‌های جانبی. کد ۵۰۲ در پروتکل HTTP (Hypertext Transfer Protocol) به این معناست که لایه‌ی اول نتوانسته پاسخ معتبر از لایه‌ی دوم بگیرد. توضیح تکمیلی این مفهوم در ویکی‌پدیا آمده است، ولی جوهر ماجرا در همین یک جمله خلاصه می‌شود.

نکته‌ی حیاتی این است که خطای ۵۰۲ در بدنه‌ی خودش نمی‌گوید چرا آن پاسخ معتبر نگرفته. دلایل می‌تواند بسیار متنوع باشد: سرویس PHP-FPM از کار افتاده، سوکت UNIX یا پورت TCP باز نیست، timeout پیش از پاسخ رخ داده، ارتباط SSL بین دو لایه ناسازگار است، یا سرویس بک‌اند به دلیل مصرف بیش از حد حافظه کشته شده. این تنوع، دلیل اصلی سردرگمی در عیب‌یابی این خطاست.

خطای ۵۰۲ به شما نمی‌گوید چه چیزی خراب است؛ فقط می‌گوید سرویس پشتی پاسخ سالم نداد. یافتن «چرا» به عهده‌ی شماست و تمامش در لاگ‌ها نوشته شده است.

در تجربه‌ی چندساله‌ام روی سرورهای تولید، الگویی که بارها تکرار شده این است که خطای ۵۰۲ تقریباً همیشه یکی از دو ریشه را دارد: یا سرویس بک‌اند کاملاً از کار افتاده، یا ارتباط بین دو لایه به دلیل timeout یا خطای پروتکل قطع شده. تفکیک این دو حالت، اولین گام در عیب‌یابی است. مباحث عمومی مرتبط با معماری سرور در سرور چیست و چگونه کار می‌کند و بهبود عملکرد سرور باز شده است.

تفاوت بنیادی 502 با 500 و 504

سه کد خطای خانواده‌ی ۵xx که در عمل زیاد با هم اشتباه گرفته می‌شوند، معنای فنی متفاوتی دارند و مسیر عیب‌یابی هر یک جداست:

کدمعنامحل ریشهنشانه‌ی تشخیص
500Internal Server Errorکد اپلیکیشن یا پیکربندیلاگ PHP خطای کشنده دارد
502Bad Gatewayارتباط بین دو سرویسPHP-FPM یا پراکسی پاسخ نمی‌دهد
504Gateway Timeoutارتباط برقرار ولی کندPHP-FPM پاسخ می‌دهد ولی دیر

تفکیک ۵۰۲ از ۵۰۴ در عمل اهمیت زیادی دارد، چون راه‌حل‌ها متفاوتند. در ۵۰۲، مسئله‌ی اصلی «نرسیدن پاسخ» است؛ در ۵۰۴، مسئله «دیر رسیدن پاسخ» است. اگر ۵۰۲ را با افزایش timeout حل کنید، در واقع دیر رسیدن پاسخ را درمان کرده‌اید که ریشه‌ی متفاوتی داشته. مسیر دقیق عیب‌یابی ۵۰۴ در رفع خطای 504 Gateway Timeout آمده است. تفکیک خطای ۵۰۰ از بقیه هم در رفع خطای 500 Internal Server Error در وردپرس با جزئیات باز شده است.

شش علت ریشه‌ای خطای 502

در عیب‌یابی خطای ۵۰۲ روی سرورهای تولید، این شش علت بیش از بقیه تکرار می‌شوند:

علت اول: از کار افتادن سرویس PHP-FPM

شایع‌ترین دلیل. اگر سرویس PHP-FPM به دلیل مصرف بیش از حد حافظه کشته شده باشد یا به‌دلیل خطای پیکربندی نتواند بالا بیاید، تمام درخواست‌ها با ۵۰۲ پاسخ داده می‌شوند. نشانه‌ی این وضعیت: در لاگ Nginx، پیام‌هایی مثل connect() to unix:/var/run/php/php8.2-fpm.sock failed یا Connection refused دیده می‌شود. علت مرگ سرویس معمولاً با دستور sudo systemctl status php8.2-fpm و سپس بررسی dmesg | tail -50 برای یافتن پیام Out of memory: Killed process مشخص می‌شود.

علت دوم: سوکت یا پورت باز نبودن

PHP-FPM می‌تواند از طریق سوکت UNIX یا از طریق پورت TCP با وب‌سرور صحبت کند. اگر سوکت اشتباه تنظیم شده باشد، یا اگر تغییر نسخه‌ی PHP مسیر سوکت را عوض کرده باشد، وب‌سرور نمی‌تواند ارتباط برقرار کند. این خطا معمولاً بعد از آپدیت PHP یا بعد از مهاجرت سرور بروز می‌دهد. بررسی سریع:

ls -la /var/run/php/
ss -lntp | grep php

علت سوم: Timeout در پراکسی

اگر درخواست کاربر بیش از مقدار proxy_read_timeout در Nginx طول بکشد، Nginx اتصال را قطع می‌کند و به کاربر ۵۰۲ برمی‌گرداند. این سناریو در سایت‌های پرمحتوا یا فروشگاه‌های با عملیات سنگین (مثل جستجوی محصولات، بازیابی کوپن‌های پیچیده) بیشتر دیده می‌شود. اگر پیام دقیقاً upstream timed out (110: Connection timed out) while reading response header from upstream بود، ریشه در کندی PHP است نه قطعی سرویس.

علت چهارم: مصرف بیش از حد حافظه

وقتی مصرف حافظه‌ی سرور به سقف می‌رسد، کرنل لینوکس پروسه‌هایی را که مصرف بیشتری دارند (معمولاً PHP-FPM یا MySQL) به‌صورت خودکار می‌کشد. نتیجه، از کار افتادن ناگهانی سرویس و خطای ۵۰۲ است. برای پایش لحظه‌ای:

free -h
vmstat 1 5
dmesg -T | grep -i "out of memory"

اگر پیام Out of memory در لاگ کرنل تکرار می‌شود، باید یا حافظه‌ی سرور افزایش یابد یا محدودیت‌های PHP-FPM بازبینی شوند. مسیر دقیق مدیریت مصرف منابع در کاهش مصرف منابع هاست و رفع مصرف بالای CPU در وردپرس آمده است.

علت پنجم: ناسازگاری SSL بین لایه‌ها

اگر بین وب‌سرور جلویی و سرویس بک‌اند، ارتباط HTTPS برقرار باشد ولی گواهی یا پروتکل ناسازگار باشد، خطای ۵۰۲ رخ می‌دهد. این سناریو بیشتر در معماری‌های Cloudflare Full SSL دیده می‌شود که گواهی معتبر در لبه دارند ولی سرور اصلی گواهی ناسازگار یا منقضی دارد. راه‌حل معمولاً در رفع خطای SSL در سرور بررسی شده است.

علت ششم: تداخل با لودبالانسر یا CDN

در معماری‌های دارای لودبالانسر، اگر یکی از سرورهای پشتی به‌دلایل مختلف پاسخ ندهد، لودبالانسر خطای ۵۰۲ برمی‌گرداند. همین موضوع در CDNهای معروف مثل Cloudflare هم دیده می‌شود. بررسی سریع: سایت را با آی‌پی مستقیم سرور تست کنید. اگر مستقیم پاسخ داد ولی از دامنه خطا داد، ریشه در لایه‌ی پراکسی است. مباحث مرتبط با CDN در افزایش امنیت سرور هم پوشش داده شده است.

پنج حرکت سریع در بحران

اگر سایت شما همین حالا خطای ۵۰۲ می‌دهد و مشتری پشت سایت منتظر است، این پنج حرکت را به همین ترتیب اجرا کنید:

  1. ری‌استارت سریع سرویس‌ها: دستور sudo systemctl restart php8.2-fpm nginx در بسیاری از موارد، سایت را در چند ثانیه برمی‌گرداند. قبل از هر کار دیگری این را امتحان کنید.
  2. بررسی منابع سرور: با free -h و top ببینید آیا حافظه یا CPU کاملاً اشباع شده است. اگر بله، ریشه در منابع است نه پیکربندی.
  3. فعال‌سازی حالت نگهداری: اگر بازگردانی طول می‌کشد، از طریق .maintenance یا تنظیمات هاست، سایت را در حالت تعمیرات قرار دهید تا کاربران پیام آگاهانه ببینند.
  4. بررسی لاگ Nginx: خطوط آخر لاگ در /var/log/nginx/error.log در ۹۰ درصد موارد ریشه را نشان می‌دهد. به‌دنبال upstream بگردید.
  5. افزایش موقت منابع: اگر ریشه در timeout است، موقتاً proxy_read_timeout را افزایش دهید تا کاربران بتوانند از سایت استفاده کنند و شما فرصت تحلیل داشته باشید.

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

خواندن لاگ‌های Nginx، Apache و PHP-FPM

در عیب‌یابی خطای ۵۰۲، سه لاگ کلید هستند و ترتیب خواندنشان اهمیت دارد:

لاگ Nginx

فایل /var/log/nginx/error.log مهم‌ترین منبع اطلاعات است. الگوهای شایع و ترجمه‌ی آن‌ها:

  • connect() failed (111: Connection refused): سرویس PHP-FPM در حال اجرا نیست.
  • connect() to unix:/var/run/php/php8.2-fpm.sock failed (2: No such file or directory): سوکت وجود ندارد یا مسیر آن تغییر کرده.
  • upstream timed out (110: Connection timed out) while reading response header from upstream: سرویس پاسخ داده ولی دیر.
  • no live upstreams while connecting to upstream: تمام سرورهای پشتی از کار افتاده‌اند.
  • SSL_do_handshake() failed: ناسازگاری گواهی SSL بین لایه‌ها.

مسیر دقیق‌تر خواندن لاگ‌های وب‌سرور در بررسی خطاهای سرور در لاگ‌ها با جزئیات باز شده است.

لاگ Apache

اگر سرور شما روی Apache با ماژول proxy کار می‌کند، لاگ /var/log/apache2/error.log را بررسی کنید. الگوهای رایج مثل Nginx است، ولی بعضی پیام‌ها مثل AH00957: HTTP: attempt to connect to ... failed مخصوص Apache است.

لاگ PHP-FPM

مسیر لاگ PHP-FPM معمولاً /var/log/php8.2-fpm.log یا از طریق تنظیمات error_log در فایل php-fpm.conf قابل دسترسی است. اگر PHP-FPM به دلیل مصرف حافظه کشته شده باشد، در این فایل پیام FPM initialization failed یا گزارش‌های WARNING: [pool www] child ... exited on signal 9 (SIGKILL) دیده می‌شود. این الگو، دقیقاً نشان می‌دهد کرنل لینوکس سرویس را به دلیل کمبود منابع کشته است.

لاگ کرنل لینوکس

در سناریوهای کمبود منابع، لاگ کرنل مستقیماً مقصر را مشخص می‌کند:

dmesg -T | grep -iE "killed process|out of memory"
journalctl -xe | grep -i "oom"

اگر خروجی این دستورات، نام سرویس PHP-FPM یا MySQL را نشان دهد، ریشه‌ی خطا در کمبود حافظه است. راه‌حل، افزایش حافظه‌ی سرور یا کاهش مصرف سرویس‌ها است. مباحث مربوط به منابع در افزایش امنیت سرور و راهنماهای بهینه‌سازی باز شده است.

PHP-FPM و پیکربندی سوکت

PHP-FPM ستون فقرات اجرای کد در اکثر سرورهای وردپرسی مدرن است. سه تنظیم کلیدی در این سرویس می‌توانند خطای ۵۰۲ ایجاد کنند:

تعداد پروسه‌های فرزند (pm.max_children)

این مقدار مشخص می‌کند که PHP-FPM حداکثر چند درخواست را به‌طور همزمان پردازش کند. اگر مقدار پایین باشد، در ساعات پیک، درخواست‌های اضافی در صف می‌مانند و بعضی از آن‌ها با خطای ۵۰۲ رد می‌شوند. مقدار پیشنهادی به منابع سرور بستگی دارد، ولی برای سرور با ۴ گیگابایت RAM، معمولاً مقدار بین ۲۰ تا ۴۰ منطقی است:

pm = dynamic
pm.max_children = 30
pm.start_servers = 8
pm.min_spare_servers = 4
pm.max_spare_servers = 12
pm.max_requests = 500

مسیر سوکت (listen)

PHP-FPM می‌تواند از سوکت UNIX یا پورت TCP استفاده کند. سوکت UNIX سریع‌تر است ولی اگر در مسیر اشتباه قرار داشته باشد، ارتباط برقرار نمی‌شود. مسیر سوکت باید در دو جا هماهنگ باشد: در فایل پیکربندی PHP-FPM و در پیکربندی Nginx یا Apache. اگر آپدیت PHP نسخه را عوض کرده باشد، عدد در نام سوکت هم عوض می‌شود و این نقطه، منبع خطاهای بعد از آپدیت است.

timeout مربوط به request_terminate_timeout

این مقدار، حداکثر زمان اجرای یک درخواست PHP را تعیین می‌کند. اگر درخواست بیش از این زمان طول بکشد، PHP-FPM پروسه را متوقف می‌کند و Nginx خطای ۵۰۲ برمی‌گرداند. مقدار پیش‌فرض معمولاً صفر (بی‌نهایت) است، ولی بعضی پنل‌های هاست این مقدار را محدود می‌کنند. برای سایت‌های با عملیات سنگین مثل واردات محصولات، توصیه می‌شود این مقدار روی ۳۰۰ ثانیه یا بیشتر تنظیم شود.

نکته‌ی میدانی: در یکی از پروژه‌های فروشگاهی که با آن مواجه شدم، خطای ۵۰۲ فقط در زمان اجرای cron job بکاپ‌گیری شبانه رخ می‌داد. ریشه این بود که در آن لحظه، cron تمام پروسه‌های PHP-FPM را اشغال می‌کرد و درخواست‌های کاربران با ۵۰۲ رد می‌شدند. راه‌حل، اجرای cron در ساعات کم‌ترافیک و افزایش pm.max_children بود.

Timeout و محدودیت زمان اجرا

بسیاری از خطاهای ۵۰۲ در واقع timeout هستند که به‌شکل خطای Gateway ظاهر می‌شوند. سه نوع timeout که در عیب‌یابی باید بررسی شوند:

proxy_read_timeout در Nginx

این مقدار، مدت زمانی است که Nginx منتظر پاسخ از سرویس پشتی می‌ماند. مقدار پیش‌فرض ۶۰ ثانیه است. برای سایت‌هایی که بعضی عملیات‌شان بیش از این مقدار طول می‌کشد، باید افزایش یابد:

location ~ \.php$ {
    include fastcgi_params;
    fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
    fastcgi_read_timeout 300;
    fastcgi_send_timeout 300;
    fastcgi_connect_timeout 300;
}

max_execution_time در PHP

این مقدار، حداکثر زمان اجرای یک اسکریپت PHP است. اگر این مقدار پایین باشد و کد شما به زمان بیشتری نیاز داشته باشد، اسکریپت متوقف می‌شود و Nginx پاسخ کامل نمی‌گیرد. مسیر دقیق تنظیم این مقدار در رفع خطای Maximum execution time در PHP آمده است.

timeoutهای مربوط به اتصال به سرویس‌های بیرونی

اگر کد سایت شما به سرویس خارجی (مثل درگاه پرداخت یا API خارجی) درخواست بزند و آن سرویس پاسخ ندهد، ممکن است کل درخواست با ۵۰۲ برنگردد، ولی زمان اجرای طولانی آن، سرور را در وضعیتی قرار می‌دهد که درخواست‌های بعدی با ۵۰۲ رد شوند. این سناریو در فروشگاه‌هایی که به سرویس‌های متعدد متصل هستند شایع است. مباحث مربوط به این حوزه در اتصال درگاه پرداخت به ووکامرس پوشش داده شده است.

پراکسی معکوس، CDN و لودبالانسر

در معماری‌هایی که CDN یا پراکسی معکوس دارند، خطای ۵۰۲ می‌تواند از هر یک از سه لایه بیاید: CDN، پراکسی معکوس، یا سرور اصلی. تشخیص لایه‌ی مقصر اولین گام است:

بررسی پاسخ CDN

اگر از Cloudflare استفاده می‌کنید، در پنل CDN، لاگ‌های دقیق را می‌بینید. کدهای ۵۲۰ و ۵۲۱ در Cloudflare معمولاً به‌معنی قطع ارتباط بین Cloudflare و سرور اصلی است. کد ۵۲۲ به‌معنی timeout، و کد ۵۲۴ به‌معنی پاسخ دیرهنگام سرور اصلی است. این تفکیک، مسیر عیب‌یابی را سریع‌تر می‌کند.

تست با آی‌پی مستقیم

سریع‌ترین تست، دور زدن CDN است. با دستور curl -I --resolve yourdomain.com:443:server_ip https://yourdomain.com می‌توانید پاسخ مستقیم سرور اصلی را ببینید. اگر مستقیم پاسخ داد ولی از دامنه خطا آمد، ریشه در لایه‌ی CDN یا پراکسی معکوس است.

تنظیمات لودبالانسر

اگر سرور شما در یک cluster لودبالانسر است، خطای ۵۰۲ ممکن است از قطع شدن یکی از سرورهای پشتی بیاید. لودبالانسرها معمولاً health check دوره‌ای دارند؛ اگر یک سرور مرده ولی هنوز در cluster باشد، درخواست‌ها به آن می‌روند و خطای ۵۰۲ می‌گیرند. رفع این سناریو نیاز به بررسی health check و حذف سرور معیوب از cluster دارد.

منابع سرور: حافظه، CPU و پروسه‌ها

کمبود منابع، مستقیم‌ترین دلیل خطای ۵۰۲ در سرورهای بدون معماری پیچیده است. سه منبع کلیدی باید بررسی شوند:

حافظه (RAM)

پایش حافظه با free -h و vmstat 1 5 انجام می‌شود. اگر مقدار available به‌طور مداوم زیر ۱۰ درصد باشد، احتمال کشته شدن پروسه‌ها توسط کرنل بالاست. برای پیدا کردن پروسه‌های پرمصرف:

ps aux --sort=-%mem | head -15

مصرف CPU

مصرف بالای CPU به‌تنهایی باعث ۵۰۲ نمی‌شود، ولی اگر با مصرف بالای حافظه همراه باشد، احتمال کشته شدن پروسه‌ها را افزایش می‌دهد. پایش لحظه‌ای با top و سپس تحلیل ترند در بازه‌ی زمانی با ابزارهایی مثل htop یا glances انجام می‌شود. مسیر دقیق رفع این مشکل در رفع مصرف بالای CPU در وردپرس و رفع کندی شدید سایت وردپرسی آمده است.

تعداد پروسه‌ها (Process Limit)

در هاست‌های اشتراکی، محدودیت تعداد پروسه‌ها می‌تواند باعث ۵۰۲ شود. اگر تعداد پروسه‌های سایت شما به سقف برسد، درخواست‌های جدید رد می‌شوند. برای بررسی تعداد پروسه‌های فعلی:

ps -u username | wc -l

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

SSL، پروتکل و تنظیمات رمزنگاری

ناسازگاری SSL بین دو لایه، یکی از علت‌های کمتر شناخته‌شده‌ی خطای ۵۰۲ است. سه سناریوی رایج:

عدم اعتماد سرویس جلویی به گواهی پشتی

اگر لایه‌ی جلویی با HTTPS به لایه‌ی پشتی وصل شود ولی گواهی لایه‌ی پشتی self-signed یا منقضی باشد، ارتباط برقرار نمی‌شود. راه‌حل، نصب گواهی معتبر روی هر دو لایه یا غیرفعال کردن بررسی گواهی در لایه‌ی جلویی (فقط در محیط داخلی و امن).

ناسازگاری نسخه‌ی TLS

اگر لایه‌ی جلویی از TLS 1.3 استفاده کند ولی لایه‌ی پشتی فقط تا TLS 1.2 را پشتیبانی کند، ارتباط برقرار نمی‌شود. این سناریو در سرورهای قدیمی با پیکربندی‌های ناهمگون شایع است. بررسی:

openssl s_client -connect backend_ip:443 -tls1_3
openssl s_client -connect backend_ip:443 -tls1_2

گواهی منقضی روی لایه‌ی میانی

در معماری‌های چندلایه، گواهی روی یکی از لایه‌ها ممکن است به‌صورت خودکار تمدید نشده باشد و منقضی شود. پایش منظم انقضای گواهی‌ها، یکی از اقدامات پیشگیرانه‌ی مهم است. مسیر رفع خطاهای SSL در رفع خطای SSL در سرور آمده است.

بازگردانی سریع سرویس

بعد از پیدا کردن ریشه، نوبت به بازگردانی سرویس می‌رسد. ترتیب اولویت‌بندی من در پروژه‌های واقعی:

  1. بازگردانی سریع: اگر ریشه در سرویس از کار افتاده است، با ری‌استارت سریع سایت را برگردانید.
  2. افزایش موقت منابع: اگر ریشه در timeout است، موقتاً مقادیر timeout را افزایش دهید تا کاربران بتوانند سایت را ببینند.
  3. رفع ریشه‌ای: بعد از بازگردانی سرویس، تحلیل ریشه را تا انتها ادامه دهید تا مشکل بعداً برنگردد.
  4. مستندسازی: ریشه، روش تشخیص و راه‌حل نهایی را ثبت کنید. این یادداشت در بحران بعدی، ساعت‌ها زمان صرفه‌جویی می‌کند.
  5. پایش پس از بازگشت: ۴۸ ساعت اول را با پایش دقیق بگذرانید و ترند منابع را ببینید.

پایش مستمر و پیشگیری

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

سطح اول: پایش منابع سرور

ابزارهایی مثل htop یا glances را به‌صورت دوره‌ای اجرا کنید و ترند مصرف را ثبت کنید. این پایش باعث می‌شود قبل از رسیدن به سقف منابع، ارتقا دهید.

سطح دوم: هشدار روی خطاهای بحرانی

سیستم‌هایی مثل Logwatch یا fail2ban می‌توانند روی ظاهر شدن خطاهای بحرانی در لاگ‌ها هشدار بدهند. این کار اجازه می‌دهد قبل از این‌که کاربران خطا را ببینند، شما مطلع شوید.

سطح سوم: پایش خارجی آپ‌تایم

سرویس‌هایی مثل Uptime Robot هر چند دقیقه یک درخواست به سایت شما می‌فرستند و در صورت خطای ۵۰۲، هشدار می‌دهند. این سطح پایش از دید کاربر واقعی، بهترین شاخص سلامت سایت است.

سطح چهارم: پایش سرویس PHP-FPM

سیستم‌های پایش پیشرفته مثل Zabbix یا Prometheus می‌توانند وضعیت PHP-FPM را به‌صورت مستقیم پایش کنند و در صورت قطع شدن سرویس یا مصرف بیش از حد منابع، هشدار بدهند. این سطح پایش، مخصوص سرورهایی است که SLA بالا دارند.

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

خطای 502 یعنی سرور من هک شده است؟

نه لزوماً. خطای ۵۰۲ به‌خود‌تنهایی نشانه‌ی نفوذ نیست. گرچه بعضی حملات مثل DDoS می‌توانند منابع سرور را اشباع کنند و باعث ۵۰۲ شوند، در بیشتر موارد ریشه در پیکربندی سرویس یا مصرف منابع است، نه نفوذ. برای اطمینان، لاگ‌های امنیتی سرور را بررسی کنید. مباحث مرتبط با امنیت سرور در افزایش امنیت سرور پوشش داده شده است.

ری‌استارت PHP-FPM چرا خطا را موقتاً برطرف می‌کند؟

ری‌استارت PHP-FPM، پروسه‌های قدیمی را می‌کشد و پروسه‌های جدید با وضعیت پاک راه‌اندازی می‌کند. این کار موقتی است و ریشه را حل نمی‌کند. اگر ری‌استارت هر روز لازم باشد، یعنی ریشه در مصرف منابع یا پیکربندی نادرست است و باید رفع شود.

چطور بفهمم ۵۰۲ از CDN است یا از سرور اصلی؟

سریع‌ترین تست، دور زدن CDN است. با دستور curl -I --resolve yourdomain.com:443:server_ip https://yourdomain.com یا با تغییر موقت فایل hosts سیستم خود، سایت را مستقیم از سرور اصلی تست کنید. اگر مستقیم پاسخ داد، ریشه در لایه‌ی CDN است.

آیا ۵۰۲ می‌تواند ناشی از خطای افزونه باشد؟

بله، ولی این حالت کمتر شایع است. اگر افزونه‌ای منبع سرور را بیش از حد مصرف کند یا باعث کندی شدید شود، می‌تواند با timeout به ۵۰۲ منجر شود. نشانه‌ی این سناریو: ۵۰۲ فقط در صفحات خاص یا در ساعات خاص رخ می‌دهد. مسیر دقیق عیب‌یابی این سناریو در رفع خطای 500 Internal Server Error در وردپرس پوشش داده شده است.

چرا بعد از آپدیت PHP، سایت خطای ۵۰۲ می‌دهد؟

در آپدیت PHP، معمولاً نسخه‌ی سوکت PHP-FPM تغییر می‌کند (مثلاً از php7.4-fpm.sock به php8.2-fpm.sock). اگر پیکربندی Nginx یا Apache به‌روز نشود، سوکت قدیمی وجود ندارد و خطای ۵۰۲ رخ می‌دهد. راه‌حل، به‌روزرسانی مسیر سوکت در پیکربندی وب‌سرور است.

آیا تنظیم pm.max_children می‌تواند ۵۰۲ را برطرف کند؟

در بعضی موارد بله. اگر ریشه در اشباع پروسه‌های PHP-FPM باشد، افزایش این مقدار می‌تواند درخواست‌های بیشتری را همزمان پردازش کند. اما این افزایش باید متناسب با منابع سرور باشد؛ در غیر این صورت، مصرف حافظه بالا می‌رود و پروسه‌ها کشته می‌شوند که ریشه‌ی ۵۰۲ جدید می‌شود.

چطور می‌توانم بین ۵۰۲ و ۵۰۴ در لاگ تشخیص دهم؟

در لاگ Nginx، پیام upstream prematurely closed connection نشانه‌ی ۵۰۲ است (سرویس بسته شد)، ولی upstream timed out (110) نشانه‌ی ۵۰۴ است (سرویس دیر پاسخ داد). این تفکیک، مسیر عیب‌یابی را کاملاً متفاوت می‌کند.

چگونه از بروز ۵۰۲ در ساعات پیک جلوگیری کنیم؟

سه اقدام مؤثر: اول، افزایش pm.max_children متناسب با ترافیک پیک. دوم، بهینه‌سازی درخواست‌های سنگین (مثل کوئری‌های جستجو یا فیلترها) با کش مؤثر. سوم، پایش هفتگی منابع و ارتقا در زمان مناسب، نه در بحران.

آیا ۵۰۲ روی سئو تأثیر می‌گذارد؟

بله، اگر ۵۰۲ مدت‌زمان زیادی ادامه داشته باشد، ربات‌های گوگل صفحاتی که مرتب خطا می‌دهند را از فهرست خارج می‌کنند. راه‌حل: بعد از رفع، در Google Search Console درخواست ایندکس مجدد دهید و در هفته‌ی اول پایش کنید که ایندکس صفحات بازمی‌گردد.

چه زمانی نیاز به ارتقای سرور داریم نه تنظیم مجدد؟

اگر بعد از رفع پیکربندی، ۵۰۲ در ساعات پیک برگردد و ترند مصرف منابع نشان دهد که به سقف نزدیک هستید، ارتقای سرور اجتناب‌ناپذیر است. علائم کلیدی: مصرف مداوم حافظه بالای ۸۵ درصد، مصرف CPU بالای ۷۰ درصد در ساعات اوج، و تعداد پروسه‌های نزدیک به محدودیت.

نکته‌های میدانی که در مستندات رسمی پیدا نمی‌کنید

در پایان این مقاله، چند نکته‌ای را می‌گویم که در مستندات رسمی کم‌تر به آن‌ها اشاره می‌شود ولی در پروژه‌های واقعی بارها به کارم آمده:

نخست: قبل از هر تغییری در پیکربندی PHP-FPM یا Nginx، یک نسخه‌ی پشتیبان از فایل پیکربندی بگیرید. اگر تغییر باعث بدتر شدن وضعیت شد، می‌توانید در چند ثانیه به نسخه‌ی سالم برگردید. این عادت ساده، بحران‌های زیادی را در پروژه‌های من جلوگیری کرده است.

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

سوم: خطای ۵۰۲ همیشه نشانه‌ی ضعف نیست؛ گاهی نشانه‌ی رشد است. اگر سایت شما رشد سریع داشته و منابع سرور را به سقف رسانده، این خطا نشانه‌ی موفقیت است، به شرط آن‌که سریع واکنش نشان دهید و منابع را ارتقا دهید. نگهداری سایت در حالت پایدار، یکی از ارکان رشد پایدار کسب‌وکار است.

در تجربه‌ی چندساله‌ام روی سرورهای تولیدی و پروژه‌های وردپرسی، الگویی که بارها تکرار شده این است که خطای ۵۰۲ تقریباً همیشه به یک نقطه‌ی مشخص برمی‌گردد: قطع ارتباط بین دو لایه‌ی سرویس. تشخیص سریع این نقطه، از هر راه‌حل آماده مؤثرتر است. اگر لاگ‌ها را درست بخوانید و لایه‌ها را به ترتیب بررسی کنید، این خطا از یک بحران ترسناک به یک تمرین روتین تبدیل می‌شود.

اگر روی سرور خود با نوعی از خطای ۵۰۲ مواجه شده‌اید که در این مقاله پوشش داده نشده، یا اگر راه‌حل متفاوتی پیدا کرده‌اید که به کارتان آمده، برای من جالب است آن را بشنوم. به‌خصوص اگر بخشی از لاگ یا پیکربندی که ریشه‌ی واقعی را نشان داد، با خوانندگان دیگر به اشتراک بگذارید؛ این یادداشت‌های دقیق، برای مدیر سرور بعدی ساعت‌ها زمان صرفه‌جویی می‌کنند. 🔌