سایت بالا نمیآید و مرورگر یک صفحه سفید با عدد 503 نشان میدهد. اولین کاری که اکثر مدیران سایت میکنند ریاستارت سرویس وب است. این کار در نیمی از موارد مشکل را بدتر میکند، چون 503 دو معنی کاملاً متفاوت دارد و تا وقتی ندانید کدامیک را میبینید، هر اقدامی شلیک در تاریکی است.
خطای 503 عمدی است یا ناخواسته؟
یک نگاه به هدر پاسخ این را روشن میکند. اگر سرور خودش تصمیم گرفته باشد سرویس را موقتاً قطع کند، هدر Retry-After را میفرستد:
HTTP/1.1 503 Service Unavailable
Retry-After: 3600
Cache-Control: no-store
وجود Retry-After یعنی کسی این 503 را از قبل طراحی کرده. این حالت در حالت تعمیر و نگهداری، در حالت maintenance mode وردپرس، یا وقتی Nginx بهعنوان reverse proxy پشت یک upstream خاموش قرار دارد رخ میدهد. اگر این هدر نبود و در عوض در پاسخ Server: nginx با بدنه پیشفرض دیدید، احتمالاً upstream واقعاً مرده است.
تفاوت عملی این دو در لاگ است. 503 عمدی معمولاً در access.log با کد 503 و بدون هیچ ردی در error.log ثبت میشود. 503 ناخواسته همیشه یک خط متناظر در error.log دارد:
connect() failed (111: Connection refused) while connecting to upstream
یا نسخه PHP-FPM آن:
connect() to unix:/run/php/php8.2-fpm.sock failed (2: No such file or directory)
این خط دوم را زیاد میبینم. یعنی سوکت PHP-FPM وجود ندارد؛ یا سرویس بالا نیامده، یا نسخه PHP عوض شده و مسیر سوکت در کانفیگ Nginx بهروز نشده.
چرا گوگل ۵۰۳ درست را جریمه نمیکند
کراولر گوگل بین 503 و 500 فرق میگذارد و این فرق برای رتبه سایت حیاتی است. 503 یک کد موقت است. گوگل صبر میکند، دوباره سر میزند و صفحه را از ایندکس حذف نمیکند. اما 500 یا 404 در طول چند هفته میتواند صفحه را از نتایج جستجو بردارد.
شرطش این است که 503 واقعاً موقت باشد. اگر سایت شما سه هفته پشت سر هم 503 برگرداند، گوگل آن را مثل خرابی دائمی میبیند و ترافیک ارگانیک میریزد. تجربه شخصی من: سایتهایی که بعد از مهاجرت سرور یک هفته در حالت maintenance ماندند، افت ۳۰ تا ۴۰ درصدی ترافیک را دو تا سه هفته بعد حس کردند.
یک نکته فنی که کمتر گفته میشود: در حالت maintenance، هدر Retry-After را حتماً ست کنید. مقدار منطقی بین 3600 و 86400 ثانیه است. اگر این هدر نباشد، کراولر با فاصلههای کوتاه و پشتسرهم تلاش میکند و بار اضافه روی همان سروری میافتد که در حال تعمیر است.
تشخیص سریع در سه دقیقه
قبل از هر تغییری، این ترتیب را برو:
- با
curl -I https://example.comهدرها را ببینید. کد 503 باRetry-Afterیعنی عمدی. - در سرور
systemctl status nginx php8.2-fpmرا بزنید. اگر یکی از سرویسهاfailedبود، مشکل همان است. - با
tail -f /var/log/nginx/error.logهمزمان با یک درخواست، خط خطا را بخوانید. - با
ss -lntp | grep :80ببینید کسی روی پورت 80 گوش میدهد یا نه.
اگر سرویسها سالم بودند و باز هم 503 میگیرید، احتمالاً محدودیت منابع است. وقتی PHP-FPM به سقف pm.max_children برسد، درخواستهای جدید در صف میمانند و بعد از timeout با 503 برمیگردند. این حالت را در /var/log/php8.2-fpm.log با پیام زیر میشناسید:
WARNING: [pool www] server reached pm.max_children setting (10), consider raising it
افزایش این عدد راهحل نیست، فقط علائم را جابهجا میکند. هر پروسه PHP-FPM حدود ۳۰ تا ۸۰ مگابایت RAM میگیرد. اگر روی یک سرور ۲ گیگابایتی عدد را از ۱۰ به ۴۰ ببرید، بهجای 503 خطای OOM Killer و ریاستارت شدن MySQL را میگیرید. اول مصرف واقعی حافظه را با free -m بسنجید، بعد تصمیم بگیرید.
اینجا اشتباه میکنند
رایجترین اشتباهی که دیدهام: مدیر سایت 503 را با ریاستارت Nginx حل میکند، سایت دو دقیقه بالا میآید و بعد دوباره میافتد. علتش این است که مشکل در لایه دیگری بوده. اگر پایگاه داده در حال اجرای یک کوئری سنگین باشد یا دیسک به سقف IOPS رسیده باشد، ریاستارت وبسرور فقط صف درخواستها را خالی میکند.
نشانهاش این است: بعد از هر ریاستارت، سایت دقیقاً چند دقیقه کار میکند و بعد همان 503 برمیگردد. در این حالت بهجای وبسرور، سراغ SHOW FULL PROCESSLIST; در MySQL و iostat -x 1 بروید. اگر %util دیسک بالای ۹۰ درصد بود، گلوگاه I/O است نه وبسرور.
اشتباه دوم: گذاشتن صفحه 503 روی یک فایل استاتیک بدون کد وضعیت درست. بعضیها صفحه maintenance را با کد 200 برمیگردانند. این بدترین کار ممکن برای سئو است، چون گوگل محتوای «سایت در دست تعمیر است» را بهعنوان محتوای واقعی صفحه ایندکس میکند.
۵۰۳ عمدی را درست پیاده کنید
در Nginx، سادهترین راه استفاده از فایل استاتیک با کد صحیح است:
location / {
if (-f /var/www/maintenance.flag) {
return 503;
}
}
error_page 503 /maintenance.html;
location = /maintenance.html {
internal;
}
با این تنظیم، کافی است فایل maintenance.flag را بسازید یا پاک کنید؛ نیازی به reload نیست. برای اینکه گوگل هم بفهمد موقتی است، در بلاک error_page هدر Retry-After را اضافه کنید.
اگر سایت روی وردپرس است، افزونههای maintenance mode همین کار را میکنند، ولی بعضیشان کد 200 برمیگردانند. قبل از فعال کردن، با curl -I چک کنید که واقعاً 503 میگیرید.
کِی سراغ ارتقای زیرساخت برویم
اگر بعد از تنظیم درست pm.max_children، بهینهسازی کوئریها و فعال کردن کش، باز هم در ساعات اوج ترافیک 503 میگیرید، مشکل ظرفیت است نه تنظیمات. در این نقطه دو مسیر دارید: جدا کردن پایگاه داده روی سرور دیگر، یا مهاجرت به یک سرور اختصاصی با منابع اختصاصی.
انتخاب من در بیشتر موارد مسیر اول است، چون ارزانتر و سریعتر جواب میدهد. اما اگر ترافیک شما بهطور مداوم از ظرفیت یک سرور عبور کرده و I/O دیسک گلوگاه اصلی است، جدا کردن دیتابیس فقط پیچیدگی اضافه میکند و باید سراغ سختافزار قویتر بروید. برای سایتهای کوچک و متوسط که مشکلشان تنظیمات PHP-FPM و کش است، یک هاست لینوکس با منابع کافی و امکان تنظیم دقیق PHP-FPM کفایت میکند.
قبل از هر مهاجرت، وضعیت فعلی را مستند کنید. با ابزارهای رایگان وبمستر میتوانید زمان پاسخ سرور و وضعیت DNS را بسنجید و بعد از مهاجرت مقایسه کنید. اگر شک دارید مشکل از DNS است یا سرور، بررسی DNS و شبکه سریعترین راه تفکیک این دو است.
یک نکته درباره کش: اگر سایت شما پشت CDN است، 503 از مبدأ ممکن است در لبه کش شود و بعد از رفع مشکل هم چند دقیقه ادامه پیدا کند. در این حالت باید cache را purge کنید. راهنمای کش مرورگر و هدرهای Cache-Control توضیح میدهد چطور هدرها را طوری تنظیم کنید که پاسخهای خطا کش نشوند.
پرسشهای پرتکرار
آیا خطای 503 برای سئو خطرناک است؟
خطای 503 بهخودیخود برای سئو خطرناک نیست، چون یک کد وضعیت موقت است و گوگل صفحه را از ایندکس حذف نمیکند. خطر وقتی شروع میشود که 503 طولانی شود. اگر بیش از دو تا سه هفته ادامه پیدا کند، گوگل آن را مثل خرابی دائمی میبیند و رتبه سایت افت میکند.
برای اینکه خیالتان راحت باشد، همیشه هدر Retry-After را در پاسخ 503 بفرستید و مطمئن شوید صفحه maintenance با کد 200 برگردانده نمیشود.
چطور بفهمم 503 از سرور خودم است یا از CDN؟
با curl -I --resolve example.com:443:IP-سرور-اصلی https://example.com مستقیم به مبدأ درخواست بزنید. اگر پاسخ 200 بود ولی از طریق دامنه 503 میگیرید، مشکل در لایه CDN است.
در این حالت هدر Server و CF-Ray یا مشابه آن را در پاسخ ببینید. اگر نام ارائهدهنده CDN را نشان میدهد، باید در پنل CDN دنبال خطا بگردید نه در سرور خودتان.
آیا ریاستارت Nginx خطای 503 را حل میکند؟
فقط اگر علت واقعی، گیر کردن پروسههای Nginx یا پر شدن صف درخواستها باشد. در بیشتر موارد 503 از PHP-FPM، پایگاه داده یا I/O دیسک میآید و ریاستارت Nginx فقط چند دقیقه مهلت میدهد.
قبل از ریاستارت، همیشه error.log را بخوانید. اگر خطای connect() failed دیدید، مشکل upstream است نه خود Nginx.
تفاوت 503 با 502 چیست؟
502 یعنی سرور بهعنوان gateway پاسخ نامعتبر از upstream گرفته، ولی 503 یعنی سرویس الان در دسترس نیست. در عمل هر دو معمولاً از یک ریشه میآیند: upstream خاموش یا overload شده.
تفکیکشان از روی لاگ مهم است. 502 بیشتر وقتی رخ میدهد که پروسه upstream وسط پاسخ دادن بمیرد؛ 503 وقتی که اصلاً نتواند وصل شود یا خودش اعلام کند در دسترس نیست.
دفعه بعد که 503 دیدید، قبل از هر دستوری، با curl -I بپرسید عمدی است یا نه. جواب این یک سؤال، مسیر عیبیابی را نصف میکند.
دیدگاهها ۰
هنوز دیدگاهی ثبت نشده؛ اولین نفر باشید!