WIUNIX ACADEMY
عیبیابی خطاهای 502 و 504 در Nginx
وقتی برنامه مستقیم پاسخ میدهد اما پشت Nginx خطا میگیرید، اتصال، لاگ و زمان پاسخ را بررسی کنید تا محل واقعی خرابی مشخص شود.
محیطت را انتخاب کنآموزش متناسب با محیط تو
کجا اجرا میکنی؟
سیستمعامل و نسخه را انتخاب کن تا مراحل، دستورها و راهحلها برای همان محیط نمایش داده شوند.
آموزش متناسب با مقادیر تو
تنظیمات این آموزش
مقادیر نمونه را برای محیط خودت تنظیم کن؛ متن و دستورهای مرتبط با هم تغییر میکنند. رمز، کلید خصوصی و توکن وارد نکن. مقادیر فقط در همین زبانه نگهداری میشوند و به سرور یا لینک اشتراکگذاری فرستاده نمیشوند. پیش از اجرا، DNS، گواهیها و سیاست شبکهٔ واقعی را بررسی کن.
آیپی، دامنه یا پورت مثالها با محیط تو فرق دارد؟ دکمهٔ زیر را باز کن، مقادیر را تغییر بده و «اعمال در آموزش» را بزن؛ سپس دستورهای بهروزشده را کپی کن.
تنظیم مقادیر برای محیط من5 مقدار قابلتغییر
از اینجا شروع کن
در پایان چه چیزی خواهی داشت؟
تشخیص دهید خطا هنگام اتصال به برنامه رخ میدهد یا پس از برقراری اتصال؛ سپس نتیجهٔ مسیر عمومی و بکاند را با لاگ همان درخواست تطبیق دهید.
سیستمعاملها و نسخههای پوششدادهشده
مسیرهای این آموزش با مستندات رسمی ابزار و توزیع انتخابی بررسی شدهاند. فرمانهای آموزشی روی سرویس شما اجرا نشدهاند؛ نتیجهٔ محیط خودتان را در هر گام بررسی کنید.
قبل از شروع
- یک Nginx فعال روی میزبان لینوکس که درخواست HTTP را به بکاند مشخصی میفرستد؛ آدرس و پورت واقعی برنامه را میدانید.
- دسترسی مجاز به لاگ و وضعیت سرویس، ابزارهای معرفیشده برای سیستمعامل انتخابی، و یک مسیر GET بدون اثر جانبی برای بررسی در اختیار دارید.
- برای تغییر اختیاری تنظیم لاگ، نسخهٔ قبل و زمان مناسب reload را مشخص کردهاید؛ این آموزش نصب یا جابهجایی سرویس نیست.
از روی کد خطا نمیتوان علت را تعیین کرد
زیادکردن timeout معمولاً اولین کار درست نیست. خطای 502 یعنی پروکسی پاسخ قابل استفادهای از بکاند نگرفته؛ در 504 زمان انتظار پروکسی تمام شده است. هنوز باید معلوم شود اتصال برقرار نمیشود، برنامه در صف مانده یا پاسخ نامعتبر میفرستد.
یک درخواست مشخص و یک بازهٔ زمانی کوتاه انتخاب کنید. مثالهای این راهنما برای Nginx روی میزبان و بکاند HTTP با آدرس و پورت معلوماند. برای FastCGI، gRPC، سوکت یونیکس یا شبکهٔ داخلی کانتینر، بررسی اتصال باید متناسب با همان مسیر انجام شود.
قدم بعدی
پیش از شروع، ابزار و تفاوتهای توزیع را بررسی کنید
این گام روی همان میزبان آزمایش یا عیبیابی اجرا میشود. نام و نسخهٔ سیستمعامل و بستههای فهرستشده را با محیط انتخابی تطبیق دهید. اگر ابزاری نصب نیست، ابتدا از مخزن رسمی فعال و روند مجاز مدیریت بستهٔ خود آن را نصب کنید؛ این آموزش سرور موجود را دوباره نصب یا مخزنش را عوض نمیکند.
در Debian 13 و 12 نام بستهها در پنل آمده است. Debian 12 در دورهٔ LTS قرار دارد و پوشش پشتیبانی به معماری و بسته بستگی دارد؛ صرف نصببودن یک بسته تضمین پشتیبانی آن نیست.
Nginx باید از قبل نصب و سرویس موجود شناختهشده باشد. در بستههای متداول این خانواده، سرویس nginx و فایل اصلی nginx.conf زیر شاخهٔ /etc/nginx قرار دارند؛ محل include و لاگ را از پیکربندی مؤثر خودتان پیدا کنید، نه از نام توزیع. روی RPM چیدمان sites-enabled اوبونتو را فرض نکنید.
خروجی کامل پیکربندی ممکن است دادهٔ خصوصی داشته باشد؛ آن را عمومی نکنید. مسیر لاگ خطای فعال را در تنظیمات همین آموزش وارد کنید.
ترمینال میزبان مجاز معرفیشده در همین بخش
cat /etc/os-release
dpkg-query -W curl iproute2
command -v curl ss nginx
sudo nginx -t
sudo nginx -T 2>&1 | sed -n '1,100p'
systemctl show nginx.service -p FragmentPath -p DropInPaths -p ExecStartبسته و ابزار لازم شناسایی شده است؛ خطا یا نبود ابزار را پیش از ادامه رفع کنید.
قدم بعدی
زمان و نتیجهٔ مسیر عمومی را ثبت کنید
روی سرور Nginx، ساعت و نسخه را ثبت کنید و یک درخواست بدون کوکی، توکن یا پارامتر حساس به app.example.com بفرستید. اگر ریشهٔ سایت برای این کار مناسب نیست، نشانی یک مسیر سلامت تأییدشده را در پنل جایگزین کنید.
زمان اولین بایت در این درخواست شامل کارهای DNS، اتصال و TLS هم هست؛ آن را زمان اجرای خالص برنامه ندانید. کد پاسخ یا خطای curl را همراه زمان UTC نگه دارید تا بتوانید همان رخداد را در لاگ پیدا کنید.
ترمینال همان میزبان معرفیشده در توضیح گام
date -u +'%Y-%m-%dT%H:%M:%SZ'
nginx -v
curl --noproxy '*' --connect-timeout 3 --max-time 15 -sS -o /dev/null -w 'status=%{http_code} connect=%{time_connect} tls=%{time_appconnect} first_byte=%{time_starttransfer} total=%{time_total}\n' 'https://app.example.com/'نتیجهٔ همین درخواست و زمان آن ثبت شده است. قطع درخواست پس از ۱۵ ثانیه، مهلت ابزار بررسی است؛ بهتنهایی timeout خود Nginx را نشان نمیدهد.
قدم بعدی
کنترل امنیتی میزبان را جداگانه بررسی کنید
لاگ کرنل را در بازهٔ زمانی همان خطا بررسی کنید. روی میزبان دارای AppArmor، denial پروفایل فعال ممکن است مستقل از مجوز Unix یا شبکه باشد؛ پروفایل را صرفاً برای سبزشدن تست خاموش نکنید. این بررسی جای لاگ برنامه و بررسی سیاست واقعی میزبان را نمیگیرد.
ترمینال میزبان مجاز معرفیشده در همین بخش
sudo journalctl -k --since '-10 min' --no-pager -n 120علت احتمالی را به شواهد همان خطا و سیاست مشخص میزبان مرتبط کردهاید؛ هیچ سیاست امنیتی یا قاعدهٔ فایروالی را غیرفعال یا تغییر ندادهاید.
قدم بعدی
از سرور Nginx مستقیماً بکاند را بررسی کنید
از همان میزبان به 127.0.0.1 روی پورت 8000 درخواست بفرستید. نام دامنه را در هدر Host نگه دارید تا برنامهٔ درست انتخاب شود. اگر این مسیر هم مشکل دارد، پیش از تغییر پروکسی، خود برنامه و مسیر اتصال به آن را بررسی کنید.
این درخواست پورت خصوصی را عمومی نمیکند. نمونه برای بکاند HTTP است؛ اگر ارتباط Nginx با برنامه HTTPS است، باید نام و گواهی همان ارتباط را درست اعتبارسنجی کنید و این نمونه را عیناً اجرا نکنید.
ترمینال همان میزبان معرفیشده در توضیح گام
curl --noproxy '*' --connect-timeout 3 --max-time 15 -H 'Host: app.example.com' -sS -o /dev/null -w 'status=%{http_code} connect=%{time_connect} first_byte=%{time_starttransfer} total=%{time_total}\n' 'http://127.0.0.1:8000/'رد فوری اتصال، پایان مهلت اتصال و تأخیر اولین بایت را جدا ثبت کنید؛ هرکدام مسیر بررسی متفاوتی دارند.
قدم بعدی
مطمئن شوید برنامه در نشانی مورد انتظار گوش میدهد
این پنل روی میزبان بکاند اجرا میشود. شنوندهٔ پورت را با تنظیم واقعی Nginx و فرایند سرویس example-app.service تطبیق دهید. برنامهای که فقط داخل namespace دیگری گوش میدهد، الزاماً از میزبان قابل دسترس نیست.
وضعیت active به معنی آمادهبودن worker یا سالمبودن دیتابیس نیست. قبل از restartهای پیاپی، خطاهای اخیر برنامه را بخوانید. لاگ ممکن است اطلاعات خصوصی داشته باشد؛ آن را محلی بررسی و پیش از اشتراکگذاری پاکسازی کنید.
ترمینال همان میزبان معرفیشده در توضیح گام
sudo ss -lntp 'sport = :8000'
sudo systemctl status 'example-app.service' --no-pager
sudo journalctl -u 'example-app.service' --since '-10 min' --no-pager -n 100آدرس، پورت و فرایند درست مشخص شدهاند و خطای اخیر برنامه بررسی شده است؛ فعالبودن unit بهتنهایی نتیجهٔ بررسی نیست.