خطای 504 Gateway Timeout از آن دسته خطاهایی است که در ظاهر شبیه ۵۰۲ به نظر می‌رسد، ولی پیام فنی‌اش دقیقاً همان چیزی را می‌گوید که در لاگ‌ها پنهان است: لایه‌ی جلویی پاسخ معتبر از لایه‌ی پشتی گرفته، ولی این پاسخ بیش از حد دیر رسیده. سال‌هاست روی سرورهای پرترافیک و پروژه‌های وردپرسی با این خطا مواجه می‌شوم و در تجربه‌ام، تفاوت بنیادی میان ۵۰۲ و ۵۰۴ در همین نکته‌ی ظریف نهفته است: یکی از نرسیدن پاسخ خبر می‌دهد، دیگری از دیر رسیدن پاسخ. مسیر عیب‌یابی هر یک، کاملاً متفاوت است.

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

معنای دقیق خطای ۵۰۴ در معماری سرور

کد وضعیت 504 در پروتکل HTTP (Hypertext Transfer Protocol) به این معناست که لایه‌ی جلویی سرور (معمولاً Nginx یا یک لودبالانسر)، درخواست را به سرویس پشتی فرستاده و منتظر پاسخ مانده، ولی در بازه‌ی زمانی مشخص‌شده پاسخی دریافت نکرده. نکته‌ی کلیدی اینجاست: برخلاف ۵۰۲ که در آن ارتباط اصلاً برقرار نمی‌شود، در ۵۰۴ ارتباط برقرار شده و سرویس پشتی در حال پردازش است، فقط کندتر از آن چیزی که مهلت (timeout) اجازه می‌دهد. توضیح تکمیلی این کد در ویکی‌پدیا موجود است، ولی جان ماجرا در همین تمایز است.

در پروژه‌های واقعی، خطای ۵۰۴ تقریباً همیشه یک پیام ثانویه است، نه ریشه. ریشه در جایی دیگر پنهان است: در یک کوئری کند، در یک سرویس بیرونی که پاسخ نمی‌دهد، در یک اسکریپت PHP که در حلقه‌ای بی‌پایان گیر افتاده، یا در یک افزونه‌ای که بی‌سروصدا تمام منابع را به خودش اختصاص داده. همین نکته باعث می‌شود خطای ۵۰۴ یکی از آن خطاهایی باشد که برای عیب‌یابی درست، باید اول مقصر کندی را پیدا کنید و سپس timeout را تنظیم کنید.

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

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

تفاوت ۵۰۴ با ۵۰۰ و ۵۰۲ و ۵۰۳

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

کدمعنالایه‌ی مقصرنشانه‌ی تشخیص در لاگ
500Internal Server Errorکد اپلیکیشن یا پیکربندیخطای کشنده در PHP
502Bad Gatewayسرویس پشتی پاسخ نمی‌دهدconnect() failed یا upstream prematurely closed
503Service Unavailableتصمیم آگاهانه‌ی سرورlimiting requests یا حالت نگهداری
504Gateway Timeoutپاسخ دیرهنگام سرویسupstream timed out while reading response

در تجربه‌ی چندساله‌ام، تشخیص این چهار کد بر اساس نشانه‌های لاگ، سریع‌ترین راه برای انتخاب مسیر درست است. اگر در لاگ Nginx پیام upstream timed out دیدید، ۹۹ درصد با خطای ۵۰۴ طرفید. مسیر کامل تشخیص ۵۰۲ در رفع خطای 502 Bad Gateway و مسیر تشخیص ۵۰۰ در رفع خطای 500 Internal Server Error در وردپرس با جزئیات باز شده است.

هفت علت ریشه‌ای خطای ۵۰۴

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

علت اول: کوئری کند دیتابیس

شایع‌ترین دلیل خطای ۵۰۴ در سایت‌های وردپرسی. اگر یک کوئری به دلیل نبود ایندکس مناسب، جدول‌های بزرگ، یا قفل (lock) طول بکشد، PHP-FPM منتظر پاسخ دیتابیس می‌ماند و در این فاصله، timeout لایه‌ی جلویی سر می‌رسد. مسیر دقیق این سناریو در رفع خطای اتصال به دیتابیس در وردپرس باز شده است.

علت دوم: محدودیت max_execution_time در PHP

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

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

مقدار proxy_read_timeout در Nginx یا مقدار مشابه در Apache، حداکثر زمان انتظار برای پاسخ سرویس پشتی را مشخص می‌کند. مقدار پیش‌فرض معمولاً ۶۰ ثانیه است و برای سایت‌های معمولی کافی است. ولی اگر کد سایت به‌طور منظم به سرویس بیرونی وصل شود (مثل درگاه پرداخت یا API تحلیل)، این مقدار می‌تواند گلوگاه شود.

علت چهارم: سرویس بیرونی کند

اگر کد PHP به سرویس بیرونی درخواست بزند و آن سرویس پاسخ ندهد یا کند پاسخ بدهد، کل زمان پردازش بالا می‌رود و ۵۰۴ رخ می‌دهد. این سناریو در فروشگاه‌هایی که به درگاه پرداخت یا سرویس‌های احراز هویت متصل هستند شایع‌تر است. مباحث مرتبط با اتصال درگاه پرداخت در رفع خطای درگاه پرداخت ووکامرس پوشش داده شده است.

علت پنجم: مصرف بالای حافظه و swap

اگر سرور شما حافظه‌ی کافی نداشته باشد و از swap روی دیسک استفاده کند، سرعت پردازش به‌شدت افت می‌کند. این کندی می‌تواند به ۵۰۴ منجر شود، به‌خصوص اگر کوئری سنگین دیتابیس هم در جریان باشد. راه‌حل سریع این سناریو در راه‌حل خطای Memory Limit در PHP آمده است.

علت ششم: عملیات پس‌زمینه سنگین

cron jobهای سنگین مثل بکاپ‌گیری، بهینه‌سازی دیتابیس یا اسکن امنیتی می‌توانند منابع سرور را اشغال کنند و زمان پاسخ درخواست‌های کاربران را به‌شدت افزایش دهند. اگر خطای ۵۰۴ در ساعات مشخصی از شبانه‌روز رخ می‌دهد، احتمالاً با یک cron job در آن زمان طرفید. مسیر تشخیص این سناریو در عیب‌یابی مشکلات cron در وردپرس باز شده است.

علت هفتم: کندی زیرساخت شبکه یا CDN

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

پروتکل واکنش سریع در بحران

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

  1. تعیین دامنه‌ی خطا: سریع تست کنید که آیا خطا در همه‌ی صفحات است یا فقط بعضی. اگر همه‌ی سایت ۵۰۴ می‌دهد، احتمالاً ریشه در منابع سرور یا سرویس دیتابیس است. اگر فقط بعضی صفحات، به سراغ افزونه یا کد مرتبط بروید.
  2. ری‌استارت سرویس‌ها: با sudo systemctl restart php8.2-fpm nginx سرویس‌ها را ری‌استارت کنید. اگر ریشه در قفل شدن یک پروسه بود، این حرکت سایت را برمی‌گرداند.
  3. افزایش موقت timeout: اگر ریشه در کندی است، موقتاً proxy_read_timeout و fastcgi_read_timeout را به ۳۰۰ ثانیه افزایش دهید تا کاربران بتوانند از سایت استفاده کنند.
  4. بررسی منابع سرور: با free -h و top ببینید آیا حافظه یا CPU به سقف رسیده. اگر بله، ریشه در منابع است نه پیکربندی.
  5. پایش کوئری‌های کند: اگر دیتابیس MySQL است، با فعال‌سازی slow_query_log، کوئری‌های کند را شناسایی کنید.

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

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

در خطای ۵۰۴، سه لاگ کلید هستند و ترتیب خواندنشان اهمیت دارد. اول لاگ Nginx، سپس لاگ PHP-FPM و در نهایت لاگ دیتابیس. مسیر دقیق‌تر خواندن این لاگ‌ها در بررسی خطاهای سرور در لاگ‌ها با جزئیات باز شده است.

لاگ Nginx

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

  • upstream timed out (110: Connection timed out) while reading response header from upstream: سرویس پشتی پاسخ دیر داده یا اصلاً پاسخ نداده.
  • upstream timed out (110: Connection timed out) while reading response header from upstream, client: ...: به‌همراه نام سرویس مقصر، مثل php-fpm.
  • upstream prematurely closed connection while reading response header from upstream: معمولاً به‌معنی ۵۰۲ است، نه ۵۰۴.
  • a client request body is buffered to a temporary file: نشان می‌دهد حجم بدنه‌ی درخواست بالا رفته و ممکن است پردازش کند شود.

لاگ PHP-FPM

مسیر لاگ PHP-FPM معمولاً /var/log/php8.2-fpm.log است. اگر خطای ۵۰۴ ناشی از timeout در این سرویس باشد، پیام‌هایی مثل WARNING: [pool www] child ... seems to be busy یا execution timed out (set to ... sec دیده می‌شود.

لاگ کندی دیتابیس

اگر MySQL یا MariaDB دارید، فعال‌سازی slow_query_log سریع‌ترین راه پیدا کردن کوئری‌های کند است. برای فعال‌سازی:

SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 2;
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';

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

PHP-FPM و محدودیت زمان اجرا

PHP-FPM سرویسی است که کد PHP وردپرس را اجرا می‌کند. اگر تنظیمات این سرویس متناسب با بار سایت نباشد، می‌تواند منبع خطای ۵۰۴ شود. سه تنظیم کلیدی:

max_execution_time در PHP

حداکثر زمان اجرای یک اسکریپت را تعیین می‌کند. مقدار پیش‌فرض معمولاً ۳۰ ثانیه است، ولی برای عملیات سنگین مثل بکاپ‌گیری، به ۳۰۰ ثانیه یا بیشتر نیاز است. برای تنظیم در php.ini یا .user.ini:

max_execution_time = 300
max_input_time = 300
memory_limit = 256M

request_terminate_timeout در PHP-FPM

این مقدار، سقف نهایی زمان اجرای یک درخواست است. اگر max_execution_time در PHP روی ۳۰۰ باشد ولی request_terminate_timeout در PHP-FPM روی ۶۰ باشد، سرویس پاسخ را پیش از کامل شدن متوقف می‌کند. این مقدار باید همیشه بزرگ‌تر از max_execution_time باشد:

request_terminate_timeout = 320

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

اگر تعداد درخواست‌های همزمان از تعداد پروسه‌های موجود بیشتر شود، درخواست‌ها در صف می‌مانند و زمان انتظار هر درخواست بالا می‌رود که می‌تواند به timeout و ۵۰۴ منجر شود. مقدار پیشنهادی برای سرور با ۴ گیگابایت RAM، بین ۲۰ تا ۴۰ پروسه است:

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

نکته‌ی مهم: در پروژه‌های واقعی بارها دیده‌ام که خطای ۵۰۴ در ساعات پیک رخ می‌دهد و در ساعات خلوت ناپدید می‌شود. این الگو تقریباً همیشه به اشباع پروسه‌های PHP-FPM یا کوئری‌های کند در لحظه‌ی ترافیک بالا مربوط است. راه‌حل ریشه‌ای در این شرایط، هم افزایش منابع و هم بهینه‌سازی کوئری‌هاست. مباحث مرتبط با عملکرد سرور در بهبود عملکرد سرور باز شده است.

تنظیمات timeout در Nginx و Apache

لایه‌ی جلویی وب‌سرور، اولین نقطه‌ای است که timeout اعمال می‌شود. سه تنظیم کلیدی در Nginx:

proxy_read_timeout

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

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;
}

proxy_connect_timeout

حداکثر زمان انتظار برای برقراری اتصال به سرویس پشتی. مقدار پیش‌فرض ۶۰ ثانیه است و معمولاً نیازی به تغییر ندارد، مگر در شبکه‌های کند داخلی.

proxy_send_timeout

حداکثر زمان انتظار برای ارسال درخواست به سرویس پشتی. این مقدار در سایت‌هایی که درخواست‌های POST با بدنه‌ی بزرگ ارسال می‌کنند (مثل فرم‌های آپلود) اهمیت دارد.

تنظیمات معادل در Apache

در Apache با ماژول mod_proxy، تنظیمات مشابه با نام‌های ProxyTimeout و ProxyPass انجام می‌شود. مقدار استاندارد برای اکثر سایت‌ها بین ۱۲۰ تا ۳۰۰ ثانیه است.

محدودیت‌های PHP و اپلیکیشن

فراتر از تنظیمات سرور، خود کد PHP هم می‌تواند منبع کندی باشد. سه الگوی رایج در کدهای وردپرسی که به ۵۰۴ منجر می‌شوند:

حلقه‌های بی‌پایان یا سنگین

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

درخواست‌های همگام به سرویس‌های بیرونی

اگر کد PHP در حلقه، به سرویس بیرونی درخواست بزند و منتظر پاسخ بماند، کل زمان پردازش به‌شدت افزایش می‌یابد. راه‌حل: استفاده از درخواست‌های ناهمگام یا کش کردن پاسخ‌ها.

افزونه‌های پرمصرف

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

نکته‌ی عملی: برای پیدا کردن افزونه‌ی پرمصرف، می‌توانید از افزونه‌ی Query Monitor استفاده کنید. این افزونه، تعداد کوئری‌ها، زمان اجرای هر کوئری و منبع آن‌ها را نشان می‌دهد. اگر تعداد کوئری‌ها در یک صفحه بیش از ۱۰۰ بود یا زمان اجرا بیش از ۲ ثانیه، ریشه‌ی کندی در همان صفحه است.

دیتابیس و کوئری‌های کند

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

نبود ایندکس مناسب

اگر جدول‌های ووکامرس مثل wp_postmeta یا wp_options ایندکس مناسب نداشته باشند، کوئری‌های جستجو یا فیلتر به‌شدت کند می‌شوند. برای بررسی، از دستور EXPLAIN در MySQL استفاده کنید:

EXPLAIN SELECT * FROM wp_postmeta WHERE meta_key = '_price' AND meta_value < 100000;

اگر در خروجی، ستون type روی ALL بود، یعنی کوئری جدول را کامل اسکن می‌کند. با ایندکس‌گذاری روی ستون‌های meta_key و meta_value، سرعت کوئری به‌شدت بالا می‌رود.

قفل شدن جدول‌ها (Table Locking)

اگر یک تراکنش طولانی در جریان باشد، جدول‌های درگیر قفل می‌شوند و کوئری‌های دیگر در انتظار می‌مانند. این سناریو در فروشگاه‌هایی که همزمان چند کاربر در حال تسویه‌حساب هستند شایع است. بررسی:

SHOW PROCESSLIST;
SHOW ENGINE INNODB STATUS;

حجم بالای جدول‌ها

اگر جدول‌های وردپرس به‌دلیل انباشت رکوردهای قدیمی سنگین شده باشند، حتی کوئری‌های ساده هم کند می‌شوند. برای بررسی حجم جدول‌ها:

SELECT table_name, table_rows, data_length, index_length
FROM information_schema.tables
WHERE table_schema = 'your_database_name'
ORDER BY data_length DESC
LIMIT 20;

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

سرویس‌های بیرونی و درگاه پرداخت

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

سه اقدام پیشگیرانه:

  1. تنظیم timeout در درخواست‌های بیرونی: با curl_setopt($ch, CURLOPT_TIMEOUT, 10); مطمئن شوید که درخواست به سرویس بیرونی بیش از ۱۰ ثانیه منتظر نمی‌ماند.
  2. استفاده از درخواست‌های ناهمگام: اگر نتیجه‌ی درخواست فوراً لازم نیست، آن را در پس‌زمینه اجرا کنید.
  3. کش کردن پاسخ‌ها: اگر داده‌ی سرویس بیرونی تغییر مکرر ندارد، آن را کش کنید و از کش بخوانید.

کش و CDN به‌عنوان سپر دفاعی

کش و CDN، مؤثرترین ابزار برای کاهش بار سرور و جلوگیری از ۵۰۴ هستند. مکانیزم کار این ابزارها، ذخیره‌ی نسخه‌ی آماده‌ی پاسخ‌ها و ارسال آن‌ها به کاربران بعدی است، بدون این‌که درخواست به سرویس پشتی برسد.

انتخاب افزونه‌ی کش مناسب، بسته به هاست و نوع سایت متفاوت است. مباحث دقیق این حوزه در بهترین افزونه‌های کش وردپرس و نقش CDN در سرعت سایت باز شده است. دو نکته‌ی کلیدی:

  1. صفحات پویا را مستثنی کنید: سبد خرید، تسویه‌حساب و صفحات کاربری را از کش مستثنی کنید تا سشن کاربران از بین نرود.
  2. CDN را فعال کنید: حتی نسخه‌ی رایگان Cloudflare می‌تواند بخش بزرگی از بار استاتیک را از سرور شما بگیرد و زمان پاسخ را کاهش دهد.

نکته‌ی میدانی: در یکی از پروژه‌های فروشگاهی که با آن مواجه شدم، خطای ۵۰۴ در ساعات اوج کمپین رخ می‌داد. با فعال‌سازی CDN و کش هوشمند، زمان پاسخ سرور از ۴ ثانیه به کمتر از ۱ ثانیه کاهش یافت و خطای ۵۰۴ کاملاً ناپدید شد. این تجربه نشان می‌دهد که در بسیاری از موارد، بهینه‌سازی لایه‌ی کش از افزایش منابع سرور مؤثرتر است.

بازگردانی سرویس و اولویت‌بندی

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

  1. افزایش موقت timeout: سریع‌ترین راه برگرداندن سایت، افزایش موقت مقادیر timeout در Nginx و PHP است.
  2. ری‌استارت سرویس‌ها: اگر ریشه در قفل شدن پروسه‌ها بود، ری‌استارت PHP-FPM و Nginx سایت را برمی‌گرداند.
  3. فعال‌سازی کش و CDN: اگر ریشه در بار سرور است، فعال‌سازی کش و CDN، بار را به‌طور محسوس کاهش می‌دهد.
  4. رفع ریشه‌ای: بعد از بازگردانی، کوئری‌های کند و افزونه‌های پرمصرف را شناسایی و اصلاح کنید.
  5. مستندسازی: ریشه، روش تشخیص و راه‌حل نهایی را ثبت کنید. این یادداشت در بحران بعدی، ساعت‌ها زمان صرفه‌جویی می‌کند.

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

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

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

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

سطح دوم: پایش زمان پاسخ دیتابیس

فعال بودن slow_query_log در MySQL و بازبینی هفتگی آن، سریع‌ترین راه پیدا کردن کوئری‌های کند است. اگر کوئری جدیدی در لیست ظاهر شد، بلافاصله بررسی کنید.

سطح سوم: پایش زمان پاسخ کاربر

ابزارهایی مثل Google Analytics یا New Relic می‌توانند زمان پاسخ هر صفحه را نشان دهند. اگر ترند زمان پاسخ در حال افزایش است، قبل از این‌که به ۵۰۴ منجر شود، اقدام کنید.

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

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

سطح پنجم: پایش لاگ‌ها و هشدار خودکار

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

پرسش‌های پرتکرار درباره خطای ۵۰۴

تفاوت اصلی ۵۰۴ و ۵۰۲ در چیست؟

در ۵۰۲، لایه‌ی جلویی اصلاً نتوانسته با سرویس پشتی ارتباط برقرار کند (سرویس مرده یا سوکت اشتباه). در ۵۰۴، ارتباط برقرار شده ولی پاسخ دیر رسیده (سرویس کند یا timeout کوتاه). راه‌حل ۵۰۲ معمولاً ری‌استارت سرویس یا اصلاح پیکربندی سوکت است، ولی راه‌حل ۵۰۴ اغلب افزایش timeout یا بهینه‌سازی کوئری‌هاست.

آیا افزایش timeout همیشه راه‌حل ۵۰۴ است؟

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

خطای ۵۰۴ روی سئو چه تأثیری دارد؟

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

چطور بفهمم خطای ۵۰۴ ناشی از دیتابیس است یا سرویس بیرونی؟

سه نشانه: اول، اگر خطا فقط در صفحاتی رخ می‌دهد که کوئری سنگین دارند (مثل آرشیو یا جستجو)، ریشه در دیتابیس است. دوم، اگر خطا در همه‌ی صفحات رخ می‌دهد، احتمالاً ریشه در منابع سرور یا یک افزونه‌ی سراسری است. سوم، اگر خطا فقط در صفحاتی رخ می‌دهد که به سرویس بیرونی وصل می‌شوند (مثل تسویه‌حساب)، ریشه در سرویس بیرونی است.

مقدار مناسب max_execution_time چقدر است؟

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

آیا خطای ۵۰۴ می‌تواند ناشی از حمله باشد؟

بله. حملات Slowloris یا DDoS می‌توانند با اشغال منابع، زمان پاسخ را بالا ببرند و خطای ۵۰۴ را فعال کنند. نشانه‌ی این سناریو: افزایش ناگهانی در تعداد درخواست‌های همزمان و بالا رفتن زمان پاسخ همه‌ی درخواست‌ها. راه‌حل: محدودسازی نرخ درخواست در Nginx و استفاده از CDN با DDoS Protection.

چطور کوئری‌های کند را پیدا کنم؟

سه روش: اول، فعال‌سازی slow_query_log در MySQL. دوم، استفاده از افزونه‌ی Query Monitor در وردپرس که تعداد و زمان کوئری‌ها را نشان می‌دهد. سوم، بررسی SHOW PROCESSLIST در لحظه‌ی بحران برای دیدن کوئری‌های در حال اجرا.

آیا CDN می‌تواند خطای ۵۰۴ را برطرف کند؟

بله، در بسیاری از موارد. CDN بخش بزرگی از بار استاتیک (تصاویر، CSS، JS) را از سرور شما می‌گیرد و به لبه‌های شبکه منتقل می‌کند. این کاهش بار، زمان پاسخ داینامیک را پایین می‌آورد و در نتیجه ۵۰۴ کمتر رخ می‌دهد. برای سایت‌های پربازدید، CDN می‌تواند تا ۵۰ درصد کاهش بار سرور ایجاد کند.

چرا خطای ۵۰۴ بعد از آپدیت افزونه ظاهر می‌شود؟

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

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

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

نکته‌های میدانی از مدیریت بحران ۵۰۴

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

نخست: خطای ۵۰۴ نشانه‌ی این است که سرور شما هنوز زنده است، فقط کند. این تفاوت را در ذهنتان حفظ کنید؛ وقتی سرور کاملاً مرده باشد، کاربر ۵۰۲ می‌بیند، نه ۵۰۴. پس ۵۰۴ همیشه یک فرصت است برای پیدا کردن ریشه‌ی کندی و بهینه‌سازی، نه نشانه‌ی شکست کامل.

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

سوم: پیشگیری از ۵۰۴ ارزان‌تر از رفع آن است. سرمایه‌گذاری در کش، CDN و بهینه‌سازی کوئری‌ها، هزینه‌ی ماهانه‌ای دارد ولی از دست دادن مشتری در بحران، هزینه‌ای نجومی دارد. تجربه‌ی من نشان داده که سایت‌هایی که در زمان آرام روی زیرساخت سرمایه‌گذاری می‌کنند، در زمان بحران تقریباً هیچ‌وقت ۵۰۴ نمی‌بینند.

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

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