Loading...

الأساسيات · قراءة 8 دقائق

502 Bad Gateway: ماذا يعني وكيف تُصلحه

502 ليس خطأ زائرك ونادرًا ما يكون خطأ CDN. يعني أن الجهاز أمام موقعك طلب الصفحة من خادمك وحصل على شيء لا يمكنه استخدامه. هذا الدليل مكتوب من جهة الوسيط (proxy): ما الذي رأته الحافة فعليًا، وأيّ من الأسباب الأربعة كان السبب.

آخر تحديث

502 Bad Gateway: ماذا يعني وكيف تُصلحه

من الذي يقول فعليًا "bad gateway"

رمز الحالة يُولَّد من أي جهة تقف أمام تطبيقك، لا من التطبيق نفسه. الطلب يسافر زائر ← حافة CDN ← خادم أصلك ← (غالبًا) خادم تطبيقك، وأي محطة تعمل كوسيط نحو التالية يمكن أن تُنتج 502 عن المحطة التي بعدها. هذا مهم لأن الصفحة التي تنظر إليها مكتوبة من الوسيط: لو كان تطبيقك قد أجاب على الإطلاق، ولو بخطأ، لكنت تنظر إلى صفحة 500 الخاصة بك بدلًا من ذلك.

فـ 502 إذن بيان عن محادثة فشلت، والسؤال المفيد دائمًا هو نفسه: أي جهازين كانا يتحادثان، وماذا حدث بينهما؟

502 مقابل 504: الفرق الذي يتجاهله الجميع

هذان الرمزان يُستخدمان أحدهما مكان الآخر في تدوينات كثيرة، وينبغي ألا يكون الأمر كذلك.

504 Gateway Timeout تعني أن الوسيط اتصل بلا مشكلة ثم انتظر. أصلك قبل الطلب ولم ينه الإجابة أبدًا ضمن المهلة الزمنية. الأسباب المعتادة استعلام قاعدة بيانات بطيء، أو استدعاء API خارجي بلا مهلة زمنية خاصة به، أو تجمّع عمليات ممتلئ ويُصطف الطلب فيه.

502 Bad Gateway تعني أنه لم تكن هناك إجابة صالحة لينتظرها أصلًا. الاتصال رُفض، أو قُبل ثم أُسقط، أو أن البايتات التي عادت لم تكن استجابة HTTP صالحة.

إن كنت ترى 504، انظر إلى المدة التي يستغرقها تطبيقك. إن كنت ترى 502، انظر إلى ما إذا كان تطبيقك يجيب أصلًا.

السبب 1 — الأصل رفض الاتصال

الوسيط فتح اتصال TCP نحو أصلك وحصل على رفض فوري أو لا مسار إطلاقًا. لا شيء كان يستمع على ذلك المنفذ، أو أن جدار حماية أسقط الحزمة.

ما يُنتج ذلك عمليًا: خادم الويب أو الحاوية متوقف؛ أو أنه يستمع على 127.0.0.1 بدل الواجهة العامة؛ أو أن المنفذ في إعدادات أصلك لا يطابق المنفذ الذي تعمل عليه الخدمة؛ أو أن جدار حماية المضيف أو مجموعة أمان تحظر عناوين IP الخاصة بـ CDN.

كيف تتأكد. من خارج شبكتك الخاصة، اسأل الأصل مباشرةً وأرسل ترويسة Host التي يستخدمها موقعك — وإلا فأصل يخدم عدة مواقع سيجيب عن الموقع الخطأ أو يرفض:

curl -sI -H "Host: example.com" http://ORIGIN_IP/

إن فشل ذلك الأمر بالطريقة نفسها، فـ CDN يبلغ الحقيقة والإصلاح على الأصل. وإن نجح ذلك الأمر بينما ترى الحافة رفضًا، فالفرق يكاد يكون دائمًا قاعدة جدار حماية تسمح لك ولا تسمح للحافة.

السبب 2 — الأصل أغلق الاتصال مبكرًا

الاتصال قُبل، ثم مات قبل أن تعود استجابة كاملة. هذا أكثر أنواع 502 شيوعًا على حزم PHP وNode تحت الحمل.

ما يُنتج ذلك: تجمّع PHP-FPM بكل عماله مشغولون، فتُقبَل الاتصالات الجديدة في قائمة انتظار النواة (kernel backlog) ثم تُسقَط؛ أو عامل بلغ حد الذاكرة الخاص به فقُتل في منتصف الاستجابة؛ أو عملية تطبيق انهارت عند ذلك الطلب تحديدًا؛ أو عدم تطابق في keepalive حيث يُغلق الأصل الاتصالات الخاملة أبكر مما يتوقع الوسيط لإعادة استخدامها.

كيف تتأكد. انظر إلى سجل أخطاء الأصل نفسه في لحظة 502 — هذه هي الحالة الوحيدة التي يملك فيها الأصل قصة واضحة يرويها. سطر Premature end of script headers، أو سطر segfault، أو تحذير PHP-FPM بـ server reached pm.max_children يسمّي السبب مباشرةً. إن كانت حالات 502 تتجمّع عند ذروات الزيارات لا أن تظهر عشوائيًا، فأنت أمام استنفاد تجمّع لا عطل برمجي.

السبب 3 — فشلت مصافحة TLS مع الأصل

إن كان الوسيط يتحدث إلى أصلك عبر HTTPS، فقد تفشل المصافحة لأسباب لا علاقة لها بالشهادة التي يراها زوارك. الحافة تحمل الشهادة العامة؛ والاتصال خلفها محادثة منفصلة بشهادتها الخاصة.

ما يُنتج ذلك: شهادة الأصل انتهت ولم يلاحظ أحد لأن الشهادة العامة تُجدَّد تلقائيًا؛ أو أن الأصل يخدم عدة أسماء ويحتاج SNI لاختيار الاسم الصحيح؛ أو أن الأصل يقبل فقط إصدارات TLS أو مجموعات تشفير لا يقدّمها الوسيط؛ أو أن الشهادة تغطي www.example.com بينما يتصل الوسيط طالبًا example.com.

كيف تتأكد.

openssl s_client -connect ORIGIN_IP:443 -servername example.com </dev/null | head -20

اقرأ السلسلة والتواريخ. على cdn.com.tr ترسل الحافة SNI إلى الأصل، فشهادة صالحة لاسم المضيف الذي أعددته ستتفاوض بنجاح؛ أما شهادة صالحة فقط للمضيف الافتراضي (vhost) فلن تفعل.

السبب 4 — الاستجابة لم تكن HTTP صالحًا

أندر، ومُرضٍ حين تجده. الأصل أجاب، لكن ما عاد تعذّر تحليله: سطر ترويسة أطول من مخزن الوسيط المؤقت، أو سطر ناتج شارد طُبع قبل الترويسات (تحذير PHP، أو علامة ترتيب البايت في ملف include)، أو استجابة تدّعي Content-Length لا يطابق الجسم، أو تفريغ عطل نصي بسيط يُقدَّم على المنفذ 443.

كيف تتأكد. اجلب الأصل مباشرةً وانظر إلى البايتات الخام بدل صفحة مُصيَّرة:

curl -sv -H "Host: example.com" http://ORIGIN_IP/ -o /dev/null

إن لم يكن السطر الأول العائد HTTP/1.1 ...، فقد وجدته. الإصلاح في تطبيقك أو في تخزينه المؤقت للمخرجات (output buffering)، وكان الوسيط محقًا في رفضه.

ما تفعله حين يكون هناك CDN أمامك

الـ CDN يغيّر التشخيص بطريقتين مفيدتين.

الصفحات المخزَّنة مؤقتًا تستمر بالعمل. زائر يطلب شيئًا موجودًا أصلًا في تخزين الحافة المؤقت يحصل عليه حتى والأصل معطّل، فـ 502 جزئي — بعض الصفحات معطوبة وأخرى سليمة — يعني عادةً أن الأصل يعمل لكنه يفشل على المسارات غير المخزَّنة مؤقتًا، وهي عادةً المسارات الديناميكية.

تكسب نقطة رصد ثانية. الحافة ترى أصلك من الخارج باستمرار. إن أبلغت الحافة عن 502 ووصل متصفحك أنت إلى الأصل، فالفرق بين هذين الطلبين هو العلة: جدار حماية يسمح لعنوان IP الخاص بك، أو سجل DNS يشير إلى مكان آخر بالنسبة لك، أو شهادة تطابق فقط الاسم الذي تصادف أنك تستخدمه.

على cdn.com.tr، تتيح لك قواعد التوصيل الإبقاء على مدة صلاحية (TTL) أطول للتخزين المؤقت على المسارات التي تتحمّل ذلك، وهذا ما يحوّل حادثة في الأصل إلى موقع متدهور الأداء بدل موقع ميت تمامًا. يستحق ذلك الإعداد قبل أن تحتاجه، لا أثناءه.

الـ 502 الذي لا علاقة له بأصلك إطلاقًا

حالة واحدة تستحق التسمية لأنها تُهدر ساعات. إن كان DNS الخاص بك يشير إلى حافة CDN لكن اسم المضيف لم يُعدّ على تلك الحافة بعد، فلن تحصل على 502 — ستحصل على 503 بصفحة تقول إنه لا توجد خدمة مُعدَّة لهذا النطاق. هذه هي الحافة تخبرك أنها لا تعرف أي أصل تسأله إطلاقًا.

يرى الناس صفحة خطأ فور تغيير DNS، فيفترضون أن الأصل معطّل، ويبدؤون بإعادة تشغيل خدمات لم تكن معنية بالأمر أصلًا. تحقق من رمز الحالة أولًا: 502 تعني أن الحافة حاولت الوصول إلى أصلك وفشلت؛ أما 503 من هذا النوع فتعني أن الحافة لم يكن لديها أصل تجرّبه أصلًا.

الأسئلة الشائعة حول 502 Bad Gateway

هل 502 خطئي أم خطأ CDN؟

عادةً لا هذا ولا ذاك — إنه خطأ الأصل. الـ CDN يبلّغ عن العطل الذي واجهه؛ لا يخترعه. الاستثناء الذي يستحق التحقق منه هو الاتصال: إن كان جدار حماية الأصل يحظر عناوين IP الخاصة بالحافة، فالأصل سليم بالنسبة لك وغير قابل للوصول بالنسبة لـ CDN، والإصلاح قاعدة سماح لا أي شيء في التطبيق.

لماذا أحصل على 502 أحيانًا فقط؟

حالات 502 المتقطعة تعني تقريبًا دائمًا مشكلة سعة لا إعداد. تجمّع عمليات ممتلئ خلال الذروات، أو عامل تجري إعادة تدويره، أو أصل يغلق اتصالات keepalive أبكر مما يتوقع الوسيط — كلها تُنتج أخطاء تأتي وتذهب بينما ينجح اختبار بسيط من حاسوبك المحمول في كل مرة.

هل يساعد التحديث (refresh)؟

يخبرك بشيء ما. إن نجح التحديث، فالعطل متقطع وأنت أمام مسألة سعة أو عامل معين. وإن فشل كل تحديث بالطريقة نفسها، فهي مسألة إعداد — اتصال مرفوض، أو منفذ خاطئ، أو شهادة أصل منتهية — والتحديث لن يغيّر ذلك.

كيف أميّز 502 عن 504 دون رمز الحالة؟

بمدة انتظارك. 504 تجعلك تنتظر حتى انتهاء المهلة الزمنية، عادةً عشرات الثواني، لأن الوسيط ينتظر إجابة فعليًا. أما 502 فتصل عادةً بسرعة، لأن الاتصال المرفوض أو المعطوب يفشل سريعًا.

هل يمكنني أن أعرض لزوّاري شيئًا أفضل من صفحة الخطأ الافتراضية؟

نعم، وينبغي أن تفعل. يقدّم CDN محتوى مخزَّنًا مؤقتًا وإن كان قديمًا، أو صفحة خطأ بهوية علامتك التجارية بدل الافتراضية الخاصة بالوسيط، فيتحول الانقطاع إلى تجربة أسوأ من المعتاد قليلًا لا إلى تجربة معطوبة. أعدّها قبل وقوع أي حادثة، لأن أثناءها لن يكون لديك الانتباه الكافي لتخصيصه لذلك.