خطأ HTTP 503. الخدمة غير متوفرة: حالة في دعم الاستضافة

العمل في استضافة الدعم هو في الأساس نفس النوع ، ومعظم الطلبات المقدمة من العملاء يتم حلها وفقًا لنظام مخطط جيدًا ، ولكن في بعض الأحيان لا يزال عليك مواجهة مشاكل غير تافهة. ثم تتمثل المهمة الرئيسية للمهندس في العثور على المسار - المسار الصحيح الوحيد الذي سيؤدي إلى حله. في هذه المقالة ، أود أن أتحدث عن كيف واجهنا الخطأ العائم "خطأ HTTP 503. الخدمة غير متاحة" في الاستضافة المشتركة الخاصة بنا ، وكيف حاولنا الإمساك بها وتشخيصها وحصلنا على نهاية غير متوقعة.



بداية



توفر الاستضافة للمستخدمين حزمة Linux + Apache + Mysql + PHP نموذجية وغلافًا إداريًا. في حالتنا ، هذا هو ISP Manager 5 Business استنادًا إلى Centos 7 مع التحويل إلى CloudLinux. من الجانب الإداري ، يوفر CloudLinux أدوات لإدارة الحدود ، بالإضافة إلى محدد PHP مع أوضاع تشغيل مختلفة (CGI و FastCGI و LSAPI).



هذه المرة اتصل بنا عميل لحل المشكلة التالية. بدأ موقعه على محرك ووردبريس بشكل دوري بإعطاء 503 أخطاء ، أبلغنا عنها.



تشير رموز الاستجابة التي تبدأ بـ 50x إلى مشكلات جانب الخادم. يمكن أن تكون هذه مشاكل في كل من الموقع نفسه وخادم الويب الذي يخدمهما.



الحالات النموذجية التي نتلقى فيها الأخطاء التالية:



  • 500 خطأ داخلي في الخادم - غالبًا ما يكون مرتبطًا إما بأخطاء بناء الجملة في رمز الموقع ، أو مع مكتبات مفقودة / إصدار PHP غير مدعوم. قد تكون هناك أيضًا مشكلات في الاتصال بقاعدة بيانات الموقع أو أذونات غير صحيحة للملفات / الدلائل
  • 502 Bad Gateway - على سبيل المثال ، إذا كان Nginx يشير إلى منفذ خادم الويب Apache الخاطئ ، أو توقفت عملية Apache عن العمل لسبب ما
  • 504 Gateway Timeout - لم يتم استلام رد Apache خلال الوقت المحدد في تكوين خادم الويب
  • تم الوصول إلى حد الموارد 508 - تم تجاوز حد الموارد المخصصة للمستخدم


تحتوي هذه القائمة على بعض الحالات الأكثر شيوعًا فقط. وتجدر الإشارة أيضًا إلى أنه عندما يتم تجاوز الحدود ، يمكن للمستخدم تلقي أخطاء 500 و 503.



عند تشخيص هذه الأخطاء ، فإن الخطوة الأولى هي التحقق من سجلات خادم الويب. عادة ما يكون هذا كافيًا لتحديد الجاني وإصلاح المشكلة.



فيما يتعلق بالخطأ 503 في حالتنا ، رأينا إدخالًا في السجلات:

[lsapi: error] [pid 49817] [العميل xxxx: 6801] [host XXX.XX] خطأ في إرسال الطلب (GET /index.php HTTP / 1.0) ؛ uri (/index.php) طول المحتوى (0): ReceiveAckHdr: لا يوجد شيء للقراءة من الواجهة الخلفية (معرف LVE 8514) ، راجع docs.cloudlinux.com/mod_lsapi_troubleshooting.html
بناءً على هذا السجل فقط ، لم يكن من الممكن تحديد المشكلة.



التشخيص الأساسي



في البداية ، قمنا بفحص إحصائيات المستخدم التي تجاوزت الحدود. تم تسجيل تجاوزات طفيفة في الأيام السابقة ، ولكن الأخطاء في السجلات كانت جديدة ، علاوة على ذلك ، ظهرت في السجل على فترات من دقيقة إلى عدة دقائق.



درسنا أيضًا توصيات CloudLinux باستخدام الرابط المقدم في سجلات الأخطاء.

لم يؤدي تغيير أي معلمات إلى أي نتائج.



استخدم الموقع قاعدة بيانات على خادم Mysql 5.7 يعمل على نفس الخادم في حاوية Docker. احتوت سجلات الحاوية على رسائل:



[Note] Aborted connection 555 to db: 'dbname' user: 'username' host: 'x.x.x.x' (Got an error reading communication packets)


من بين هذه الرسائل كانت هناك رسائل حول انقطاع الاتصال بالموقع قيد التحقيق. وقد أعطى هذا الافتراض أن الاتصال بنظام DBMS لا يتم بشكل صحيح. للتحقق من ذلك ، قمنا بنشر نسخة من الموقع على نطاق تجريبي ، وقمنا بتحويل قاعدة بيانات الموقع إلى إصدار Centos 7 الأصلي من 5.5.65-MariaDB DBMS. في موقع الاختبار ، تم تنفيذ عدة مئات من الطلبات باستخدام أداة curl. لا يمكن تكرار الخطأ. لكن هذه النتيجة كانت أولية ، وبعد تحويل قاعدة البيانات في موقع الإنتاج ، ظلت المشكلة قائمة.



وبالتالي ، تم القضاء على مشكلة الاتصال غير الصحيح بنظام DBMS.



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



نتيجة لذلك ، توصلنا إلى استنتاج مفاده أن المشكلة تكمن في استضافتنا.



بعد تحليل سجلات المواقع الأخرى ، تبين أن المشكلة لوحظت في العديد منها. حوالي 100 جهاز كمبيوتر شخصى. في وقت التحقق:



/var/www/httpd-logs# grep -Rl "ReceiveAckHdr: nothing to read from backend" ./ | wc -l
99


أثناء الاختبار ، وجدنا أن CMS Wordpress النظيفة والمثبتة حديثًا يعطي أيضًا خطأ 503 بشكل دوري.



قبل شهرين تقريبًا ، قمنا بعمل تحديث الخادم ، على وجه الخصوص ، قمنا بتغيير وضع Apache للعمل من Worker إلى Prefork ، حتى نتمكن من استخدام PHP في LSAPI بدلاً من CGI البطيء. كان هناك افتراض بأن هذا يمكن أن يؤثر ، أو أن بعض إعدادات Apache الإضافية مطلوبة ، لكننا لم نتمكن من إعادة وضع العامل مرة أخرى. أثناء تغيير وضع تشغيل Apache ، يتم تغيير جميع تكوينات الموقع ، والعملية ليست سريعة ولا يمكن أن يسير كل شيء بسلاسة.



كما أن تصحيح إعدادات Apache لم يعط النتيجة المرجوة.



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



في هذه المرحلة ، قمنا بجمع المعلومات المتاحة ونتائج العمل المنجز. تم الاتصال بهم لدعم CloudLinux.



التشخيص التفصيلي



لعدة أيام ، بحث موظفو دعم CloudLinux في المشكلة. بشكل أساسي ، كانت التوصيات تتعلق بحدود المستخدم المحددة. فحصنا أيضا هذا السؤال. مع تعطيل الحدود (خيار CageFS للمستخدم) ومع تمكين الحدود في وضع PHP كوحدة Apache ، لم تتم ملاحظة المشكلة. وبناءً على ذلك ، فقد اقترح أن CloudLinux يؤثر بطريقة ما. ونتيجة لذلك ، بحلول نهاية الأسبوع ، تم تصعيد الطلب إلى المستوى الثالث من الدعم ، ولكن لم يكن هناك حل حتى الآن.



على طول الطريق ، درسنا وثائق Apache في وضعي CGI و LSAPI ، وقمنا بإعداد مثيل Apache ثانٍ على خادم الاستضافة على منفذ مختلف مع موقع اختبار ، وأزالنا تأثير Nginx عن طريق إرسال الطلبات مباشرة إلى Apache وتلقي نفس رموز الخطأ.



ساعدت وثائق LSAPI على الانطلاق ، بمجرد تشخيص أخطاء 503:

www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki : php: 503-الأخطاء

في قسم استكشاف الأخطاء وإصلاحها المتقدم ، يُقترح تتبع العمليات الموجودة في النظام:



while true; do if mypid=`ps aux | grep $USERNAME | grep lsphp | grep $SCRIPTNAME | grep -v grep | awk '{print $2; }' | tail -1`; then strace -tt -T -f -p $mypid; fi ; done


تم تنقيح الأمر لتسجيل جميع العمليات في الملفات مع معرفاتها.



عند النظر إلى ملفات التتبع ، نرى بعض الأسطر نفسها:



cat trace.* | tail
...
47307 21:33:04.137893 --- SIGHUP {si_signo=SIGHUP, si_code=SI_USER, si_pid=42053, si_uid=0} ---
47307 21:33:04.140728 +++ killed by SIGHUP +++
...


إذا نظرنا إلى وصف بنية الإشارات المرسلة بواسطة العمليات ، فسوف نرى ذلك



pid_t    si_pid;       /* Sending process ID */


يشير إلى معرف العملية التي أرسلت الإشارة.



في وقت دراسة الآثار ، لم تعد العملية مع PID 42053 في النظام ، وبالتالي ، في عملية التقاط الآثار ، قررنا مراقبة العمليات التي أرسلت إشارة SIGHUP أيضًا.

تحت المفسد ، تم وصف الإجراءات التي جعلت من الممكن تحديد نوع العملية ، وكذلك الحصول على أثرها ومعلومات إضافية حول العمليات التي ترسل إشارة SIGHUP إليها.



تقنية التتبع
وحدة التحكم 1.



tail -f /var/www/httpd-logs/sitename.error.log


وحدة التحكم 2.



while true; do if mypid=`ps aux | grep $USERNAME | grep lsphp | grep "sitename" | grep -v grep | awk '{print $2; }' | tail -1`; then strace -tt -T -f -p $mypid -o /tmp/strace/trace.$mypid; fi ; done


وحدة التحكم 3.



while true; do if mypid=`cat /tmp/strace/trace.* | grep si_pid | cut -d '{' -f 2 | cut -d'=' -f 4 | cut -d',' -f 1`; then ps -aux | grep $mypid; fi; done;


4.



seq 1 10000 | xargs -i sh -c "curl -I http://sitename/"


1 , 4 503, 4.



ونتيجة لذلك ، حصلنا على اسم العملية ، /opt/alt/python37/bin/python3.7 -sbb /usr/sbin/cagefsctl --rebuild-alt-php-ini



وتم تنفيذ هذه العملية في النظام مرة واحدة في الدقيقة.



نقوم بتتبع العديد من عمليات cagefsctl لتتبع واحدة على الأقل من البداية إلى النهاية:



for i in `seq 1 100`; do strace -p $(ps ax | grep cagefsctl | grep rebuild-alt-php-ini | grep -v grep | awk '{print $1}') -o /tmp/strace/cagefsctl.trace.$(date +%s); done;


بعد ذلك ، ندرس ما فعله ، على سبيل المثال:



cat /tmp/strace/cagefsctl.trace.1593197892 | grep SIGHUP


تم الحصول على معرفات العملية أيضًا التي تم إنهاؤها بإشارة SIGHUP. العمليات المنتهية هي عمليات PHP قيد التشغيل حاليًا.



تم نقل البيانات المستلمة إلى دعم CloudLinux لتوضيح شرعية هذه العملية وما إذا كان يجب أن تعمل بهذه التكرار.



في وقت لاحق ، تلقينا إجابة مفادها أن عمل الفريق /usr/sbin/cagefsctl --rebuild-alt-php-iniيتم تنفيذه بشكل صحيح ، التحذير الوحيد هو أن الفريق يتم تنفيذه كثيرًا. يُطلب عادةً عندما يتغير تحديث النظام أو إعدادات PHP.



المفتاح الوحيد المتبقي في هذه الحالة هو التحقق من أصل عملية cagefsctl.



لم تكن النتيجة طويلة ، وما فاجأنا - كانت العملية الأم لـ cagefsctl هي عملية ispmgrnode. كان الأمر غريبًا بعض الشيء ، لأنه تم تعيين مستوى تسجيل الدخول لمدير خدمة الإنترنت إلى الحد الأقصى ولم يتم مشاهدة استدعاء cagefsctl في ispmgr.log.



الآن كانت هناك بيانات كافية للاتصال بدعم نظام ISP أيضًا.



النتيجة



تم تشغيل المشكلة بعد إجراء تحديث ISP Manager. بشكل عام ، يعد تحديث ISP Manager حالة طبيعية ، ولكنه أدى إلى بدء عملية المزامنة ، التي انتهت بخطأ وتم إعادة تشغيلها كل دقيقة. استدعت عملية المزامنة عملية cagefsctl ، والتي بدورها أنهت عمليات PHP.



كان سبب تعليق عملية المزامنة هو العمل الذي تم على الاستضافة لترقية المعدات. قبل حدوث المشكلة ببضعة أشهر ، تم تثبيت محرك أقراص PCI-e NVMe في الخادم ، وتم إنشاء قسم XFS وتركيبه في الدليل / var. كما تم نقل ملفات المستخدمين إليها ، ولكن لم يتم تحديث الحصص النسبية للقرص. لم تكن خيارات التحميل كافية ، بل كان مطلوبًا أيضًا تغيير نوع نظام الملفات في معلمات ISP Manager ، منذ ذلك الحين تستدعي أوامر لتحديث الحصص النسبية للقرص. بالنسبة إلى Ext4 و XFS ، تختلف هذه الأوامر.



وهكذا ، أصبحت المشكلة نفسها بعد عدة أشهر من العمل.



الاستنتاجات



نحن أنفسنا خلقنا المشكلة ، لكنها لم تكن واضحة حتى اللحظة الأخيرة. بالنسبة للمستقبل ، سنحاول مراعاة أكبر عدد ممكن من الفروق الدقيقة. بمساعدة المزيد من الزملاء المدربين من CloudLinux ودعم نظام ISP ، تم حل المشكلة. الآن استضافتنا مستقرة. وقد اكتسبنا خبرة ستكون مفيدة لنا في العمل المستقبلي.



ملاحظة: آمل أن تكون مهتمًا بقراءة المقالة ، وسوف يساعد ذلك شخصًا على حل مشكلة مماثلة بسرعة.



All Articles