خطای 504 Gateway Timeout یعنی یک gateway در مهلت تعیینشده پاسخ upstream را کامل دریافت نکرده است. gateway میتواند CDN، load balancer، Nginx یا proxy داخل پلتفرم باشد. افزایش چند timeout ممکن است صفحه خطا را دیرتر نشان دهد، اما Query قفلشده، API بیرونی کند یا صف پر PHP-FPM را سریع نمیکند و حتی ظرفیت را بیشتر اشغال میکند.
پاسخ سریع: ابتدا مشخص کنید 504 را کدام لایه و پس از چند ثانیه تولید میکند. request کند را با timestamp یا request ID در access/error log دنبال کنید، زمان proxy و upstream را جدا ببینید و سپس PHP، دیتابیس، job یا API وابسته را بررسی کنید. timeout فقط وقتی تغییر کند که زمان سالم عملیات عمداً از سقف فعلی بیشتر است.
نشانههایی که مسیر تشخیص را کوتاه میکنند
- همه صفحات بعد از مدت تقریباً ثابت 504 میشوند
- فقط گزارش، import، جستوجو یا Checkout خطا دارد
- خطا فقط در ساعت اوج دیده میشود
- از origin پاسخ میگیرید ولی از CDN نه، یا برعکس
- درخواست پس از 504 همچنان روی backend ادامه دارد
- deploy یا تغییر دیتابیس پیش از شروع خطا انجام شده است
زمان ثابت اغلب به timeout یک لایه اشاره میکند. خطای مسیر خاص به منطق همان endpoint یا dependency آن نزدیکتر است. خطای اوج میتواند از queue، connection pool یا saturation باشد. اینها فرضیهاند؛ باید با لاگ و metric تأیید شوند.
کدام Gateway صفحه 504 را ساخته است؟
ظاهر error page، headerهای پاسخ، Ray/Request ID سرویس بالادست و logها را بررسی کنید. ممکن است Nginx هنوز منتظر باشد اما CDN زودتر timeout کند. یا load balancer سالم باشد و Nginx داخلی از اپلیکیشن پاسخ نگیرد. افزایش timeout در لایه اشتباه هیچ اثری ندارد.
یک Timeline واقعی بسازید
- زمان شروع request را با timezone ثبت کنید.
- مدت تا نمایش 504 را اندازه بگیرید.
- شناسه request را از edge تا برنامه دنبال کنید.
- زمان اتصال و زمان پاسخ upstream را جدا کنید.
- پایان یا ادامه پردازش backend بعد از قطع client را بررسی کنید.
اگر request در لایه برنامه ۹۰ ثانیه کار میکند اما proxy در ۶۰ ثانیه قطع میکند، سؤال بعدی این نیست که «کدام عدد را ۱۲۰ کنیم»؛ ابتدا باید روشن شود آیا عملیات تعاملی واقعاً باید ۹۰ ثانیه طول بکشد یا بهتر است به job پسزمینه تبدیل شود.
لاگ Nginx چه میگوید؟
پیام upstream timed out همراه context مشخص میکند timeout هنگام connect، ارسال request یا خواندن response رخ داده است. access log اگر request time و upstream response time/status داشته باشد، لایه کند را بهتر نشان میدهد. مقدار خالی یا چند upstream در log نیز باید درست تفسیر شود.
بررسی وضعیت منابع بدون ایجاد بار
uptime
free -h
df -h
df -i
ss -s
systemctl --failed
این snapshot فقط وضعیت همان لحظه است و جای metric تاریخی را نمیگیرد. load بالا همیشه CPU بالا نیست؛ task منتظر I/O نیز load را افزایش میدهد. RAM ظاهراً پر در لینوکس الزاماً بحران نیست؛ available، swap، OOM و رفتار processها را کنار هم ببینید.
صف PHP-FPM و Workerهای اشباع
اگر همه workerها مشغول requestهای کند باشند، درخواست تازه در صف میماند و پیش از شروع پردازش timeout میشود. تعداد worker را صرفاً زیاد نکنید. میانگین و بیشینه حافظه هر process، RAM قابل تخصیص، CPU و طول request را بسنجید. slow log کنترلشده میتواند stack مسیرهای طولانی را نشان دهد؛ داده حساس آن را مدیریت کنید.
Query کند یا قفل دیتابیس
گزارش سنگین، index نامناسب، lock یا connection pool پر میتواند request را متوقف کند. slow query log و وضعیت دیتابیس را در بازه رخداد بررسی کنید. فعالسازی logging پرحجم روی production نیازمند ظرفیت disk و مدت محدود است. Query مخرب یا عملیات حذف را برای «تست» اجرا نکنید و پیش از تغییر schema backup و rollback داشته باشید.
برای وردپرس، راهنمای پیدا کردن Slow Query کمک میکند زمان PHP از زمان SQL جدا شود. plugin profiler نیز باید کوتاهمدت و با سنجش overhead استفاده شود.
API و سرویس بیرونی
Checkout، پیامک، مالیات، حملونقل یا احراز هویت ممکن است منتظر API دیگری باشد. timeout اتصال، خواندن و retry باید محدود و قابل مشاهده باشد. retry بدون idempotency میتواند عملیات مالی را دو بار اجرا کند. circuit breaker، queue یا پاسخ async بسته به اهمیت عملیات مناسبتر از نگه داشتن worker وب است.
DNS و شبکه
resolve کند، packet loss، مسیر شبکه یا connection establishment نیز میتواند زمان را مصرف کند. تست باید از همان host/container و همان network انجام شود؛ نتیجه لپتاپ مدیر لزوماً نماینده مسیر production نیست. IPv4 و IPv6، proxy environment و DNS resolver فعال را جداگانه در نظر بگیرید.
کار طولانی را از HTTP تعاملی جدا کنید
export بزرگ، تولید فایل، sync یا پردازش تصویر بهتر است به job پسزمینه با status قابل پیگیری سپرده شود. پاسخ سریع یک job ID میدهد و worker جدا عملیات را با retry کنترلشده انجام میدهد. این تغییر معماری از timeout بلند و نگهداری connection برای چند دقیقه پایدارتر است.
Timeoutهای چند لایه
Browser/client، CDN، load balancer، Nginx، application server، PHP و database هرکدام timeout متفاوت دارند. سقفها باید بر اساس SLA endpoint و failure budget هماهنگ باشند. سقف داخلی معمولاً باید فرصت دهد خطای کنترلشده پیش از قطع لایه بیرونی ثبت شود، اما عدد دقیق را نمیتوان بدون معماری و workload تجویز کرد.
پس از قطع Gateway، پردازش Backend چه میشود؟
نمایش 504 الزاماً به معنی توقف کار در backend نیست. بسته به runtime و نحوه تشخیص قطع client، Query، job یا تماس با درگاه ممکن است ادامه پیدا کند. به همین دلیل کاربر نباید بدون بررسی نتیجه، عملیات مالی یا ثبت سفارش را پیدرپی تکرار کند. endpointهای تغییردهنده وضعیت باید شناسه یکتا و رفتار idempotent داشته باشند تا retry کنترلشده رکورد تکراری نسازد.
در incident بررسی کنید آیا requestهای timeoutشده هنوز process یا connection نگه داشتهاند. اگر بله، ورود retryهای جدید backlog را بزرگتر میکند. محدودسازی موقت ترافیک یا غیرفعال کردن یک قابلیت باید با ارزیابی اثر کسبوکار انجام شود؛ خاموش کردن کل سامانه یا kill جمعی processها میتواند تراکنش نیمهتمام و ناسازگاری داده ایجاد کند.
تفکیک Connect Time از Response Time
کندی برقراری اتصال معمولاً نگاه را به DNS، network، listener و pool اتصال میبرد؛ پاسخ دیرهنگام پس از اتصال، بیشتر به queue و اجرای برنامه یا dependency مربوط است. این دو را در metric و log جدا ثبت کنید. یک عدد «زمان کل» بهتنهایی نمیگوید زمان قبل از رسیدن به برنامه مصرف شده یا داخل منطق درخواست.
چه زمانی افزایش Timeout موجه است؟
وقتی عملیات سالم و محدود، عمداً طولانی است؛ منابع کافی دارد؛ progress یا رفتار قطع client معلوم است؛ و سقف فعلی پایینتر از زمان قابلقبول کسبوکار است. حتی در این حالت، فقط directive مربوط به مرحله واقعی timeout را تغییر دهید و بعد نرخ خطا، concurrency و memory را پایش کنید.
ترتیب رفع مشکل
- نمونه request، زمان و شناسه آن را ثبت کنید.
- لایه تولیدکننده 504 و سقف زمانی را بیابید.
- زمان upstream و queue را از log/metric جدا کنید.
- PHP، دیتابیس، API، DNS و منابع را طبق شواهد بررسی کنید.
- علت پردازش طولانی یا اشباع را رفع کنید.
- اگر زمان طولانی ذاتی است، معماری async یا timeout مستند طراحی کنید.
- در staging و سپس با rollout محدود آزمون کنید.
- مسیر اصلی کسبوکار و نرخ خطا را بعد از تغییر کنترل کنید.
خطاهای رایج هنگام رفع 504
- افزایش همزمان همه timeoutها بدون دانستن لایه کند
- restart پیش از نگهداری log و metric
- load test نامحدود روی production
- افزایش worker بدون بودجه حافظه
- نادیده گرفتن lock دیتابیس یا API بیرونی
- retry تراکنش غیر idempotent
- یکی دانستن 502 و 504
- قضاوت فقط با میانگین latency
مانیتورینگ پیشگیرانه
p50/p95/p99، نرخ 504، request و upstream time، queue، active worker، connection دیتابیس، dependency latency و saturation منابع را پایش کنید. alert باید پیش از فراگیر شدن timeout فعال شود. synthetic check فقط صفحه اصلی کافی نیست؛ یک endpoint dynamic کمخطر نیز لازم است.
چه زمانی کمک تخصصی لازم است؟
اگر 504 در Checkout، پنل یا API مهم تکرار میشود و منبع زمان میان چند لایه مبهم است، افزایش timeout ریسک backlog را بالا میبرد. در مدیریت ماهانه سرور میتوان trace زمانی Nginx، PHP-FPM، دیتابیس و dependencyها را کنار هم گذاشت و گلوگاه را هدفمند رفع کرد.
پرسشهای متداول
آیا 504 یعنی سرور ضعیف است؟
نه همیشه. Query قفلشده، API بیرونی، DNS، config timeout یا صف نیز میتواند علت باشد؛ منابع فقط یکی از فرضیهها هستند.
فرق 504 و 502 چیست؟
504 بیشتر به تمام شدن مهلت پاسخ اشاره دارد؛ 502 معمولاً شکست اتصال یا پاسخ نامعتبر upstream است. متن log مرجع دقیقتر است.
چرا فقط در ساعات شلوغ 504 داریم؟
احتمال saturation worker، connection یا dependency بیشتر است. metric ظرفیت و latency را با نرخ درخواست تطبیق دهید.
آیا بالا بردن proxy_read_timeout کافی است؟
فقط اگر همان مرحله timeout میشود و طولانی بودن عملیات پذیرفته و ظرفیت آن محاسبه شده باشد؛ در غیر این صورت علامت را دیرتر نمایش میدهد.