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

منذ عدة سنوات ، أمضيت بضعة أسابيع في دراسة سلوك الذاكرة على خوادم الألعاب الحية. كانت الخوادم تشغل Linux في مراكز البيانات البعيدة ، لذلك تم قضاء معظم الوقت في الحصول على الأذونات اللازمة حتى أتمكن من الاتصال بالخوادم ، بالإضافة إلى تعلم كيفية العمل بفعالية مع أدوات التشخيص perf وغيرها من أدوات تشخيص Linux. اكتشفت سلسلة من الأخطاء التي تسببت في زيادة استهلاك الذاكرة ثلاث مرات أكثر من اللازم وقمت بإصلاحها:
- لقد وجدت عدم تطابق في معرّف الخريطة ، مما تسبب في عدم استخدام كل لعبة للنسخة نفسها لحوالي 20 ميجابايت من البيانات ، ولكن لتحميل واحدة جديدة.
- لقد وجدت متغيرًا عامًا غير مستخدم (!) 50 ميجابايت (!!) ، والذي تم تعيينه على صفر memset (!!!) ، مما تسبب في استهلاك ذاكرة الوصول العشوائي الفعلية في كل عملية.
- أخطاء مختلفة أقل خطورة.
لكن قصتنا لن تكون عن ذلك.
بعد قضاء بعض الوقت في تعلم كيفية تصنيف خوادم اللعبة ، أدركت أنه يمكنني استكشاف هذا بشكل أعمق قليلاً. لذلك ، قمت بتشغيل perf على خوادم إحدى ألعابنا. كانت أول عملية خادم وصفتها ... غريبة. عند مشاهدة بيانات المعالج التي تم أخذ عينات منها "مباشرة" ، رأيت أن وظيفة واحدة كانت تستهلك 100٪ من وقت وحدة المعالجة المركزية. ومع ذلك ، تم تنفيذ أربعة عشر تعليمات فقط في هذه الوظيفة. لم يكن له أي معنى.
في البداية افترضت أنني كنت أستخدم الأداء بشكل غير صحيحأو إساءة تفسير البيانات. نظرت إلى بعض عمليات الخادم الأخرى ووجدت أن حوالي نصفها كانت في حالة غريبة. النصف الثاني كان لديه ملف تعريف CPU أكثر طبيعية.
تم تمرير الوظيفة التي تهمنا من خلال القائمة المرتبطة بعقد التنقل. سألت زملائي ووجدت مبرمجًا قال إن مشاكل دقة النقطة العائمة قد تتسبب في إنشاء قوائم تنقل ملتوية. لقد أرادوا دائمًا تحديد الحد الأقصى لعدد العقد التي يمكنهم المشي فيها ، لكنهم لم يتمكنوا من القيام بذلك.
لذلك تم حل اللغز؟ يتسبب عدم استقرار حسابات النقطة العائمة في حدوث حلقات في قوائم التنقل ، مما يجعل اللعبة تتجاوزها إلى ما لا نهاية - هذا كل شيء ، يتم شرح السلوك.
لكن ... مثل هذا التفسير يعني أنه عند حدوث ذلك ، تدخل عملية الخادم في حلقة لا نهائية ، وسيتعين على جميع اللاعبين قطع الاتصال بها ، وستستهلك عملية الخادم نواة المعالج بالكامل إلى ما لا نهاية. إذا كان الأمر كذلك ، ألن تنفد الموارد على خوادمنا في النهاية؟ ألم يلاحظ أحد هذا؟
لقد بحثت عن بيانات مراقبة الخادم ووجدت شيئًا مثل هذا:

خلال فترة المراقبة بأكملها (من عام إلى عامين) ، لاحظت تقلبات يومية وأسبوعية في حمل الخادم ، والتي تم فرضها بواسطة النمط الشهري. زاد مستوى استخدام المعالج تدريجياً ثم انخفض إلى الصفر. بعد السؤال أكثر من ذلك بقليل ، اكتشفت أنه تم إعادة تشغيل الخوادم مرة واحدة في الشهر. وأخيراً ظهر المنطق في كل هذا:
- , .
- , , .
- CPU , 50%.
- .
تم إصلاح الخطأ بإضافة بضعة أسطر من التعليمات البرمجية التي توقفت عن اجتياز القائمة بعد عشرين عقدة تنقل ، مما يوفر على الأرجح عدة ملايين من الدولارات في تكاليف الخادم والطاقة. لم أجد هذا الخطأ من خلال النظر في الرسوم البيانية للرصد ، ولكن أي شخص نظر إليها يمكنه فعل ذلك.
يعجبني حقيقة أن تواتر الخطأ يتطابق تمامًا مع زيادة تكلفة ذلك ؛ في الوقت نفسه ، لم يتسبب أبدًا في مشاكل خطيرة بدرجة كافية ليتم العثور عليها. هذا مشابه لعمل فيروس يتطور ليجعل الناس يعطسون لا يقتلهم.
تحميل بطيء

ترتبط إنتاجية مطور البرامج ارتباطًا وثيقًا بسرعة دورة التحرير / التجميع / الارتباط / التصحيح. بمعنى آخر ، يعتمد الأمر على المدة التي يستغرقها بعد إجراء تغيير على الملف المصدر لتشغيل الثنائي الجديد مع التغيير الذي تم إجراؤه. على مر السنين ، قمت بعمل رائع لتقليل أوقات الترجمة / الارتباط ، ولكن أوقات التحميل مهمة أيضًا. تقوم بعض الألعاب بقدر كبير من العمل في كل مرة تبدأ فيها. فأنا لا أطيق صبرًا ، ولذلك غالبًا ما يكون أول من يقضي ساعات أو أيامًا في تحميل اللعبة بشكل أسرع بضع ثوانٍ.
في هذه الحالة ، قمت بتشغيل ملف التعريف المفضل لدي ونظرت إلى الرسم البياني لاستخدام وحدة المعالجة المركزية أثناء مرحلة التحميل الأولية للعبة. بدت إحدى الخطوات أكثر واعدة: استغرق الأمر حوالي عشر ثوان لتهيئة بعض بيانات الإضاءة. كنت آمل أنه يمكن العثور على طريقة لتسريع هذه الحسابات من خلال توفير خمس ثوانٍ في مرحلة بدء التشغيل. قبل الغوص في الدراسة ، تشاورت مع أخصائي رسومات. قال:
"نحن لا نستخدم بيانات الإضاءة هذه في اللعبة. ما عليك سوى إزالة هذا التحدي ".
اوه رائع. لقد كان سهلا.
من خلال قضاء نصف ساعة في التنميط وتغيير سطر واحد ، تمكنت من تقليل وقت تحميل القائمة الرئيسية إلى النصف ، ولم يتطلب الأمر أي جهد غير عادي.
الرحيل المبكر
نظرًا للعدد التعسفي للوسيطات في التنسيق ، من
printfالسهل جدًا الحصول على خطأ عدم تطابق النوع. في الممارسة العملية ، يمكن أن تختلف النتائج بشكل كبير:
- printf ("0x٪ 08lx" ، p) ؛ // اطبع المؤشر كـ int - اقتطاع أو أسوأ على 64 بت
- printf ("٪ d ،٪ f" ، f ، i) ؛ // قد يؤدي تغيير أماكن التعويم و int - إلى هراء ، أو قد يعمل (!)
- printf ("٪ s٪ d"، i، s) ؛ // تغيير ترتيب السلسلة و int - سيؤدي على الأرجح إلى تعطل
المعيار يقول أن مثل هذا النوع من عدم التطابق هو سلوك غير محدد ، وبعض المترجمين ينشئون كودًا يتعطل عمدًا مع أي من حالات عدم التطابق هذه ، ومع ذلك ، فإن القائمة أعلاه تسرد النتائج الأكثر احتمالية (ملاحظة: السؤال عن سبب إنتاج الفقرة الثانية للنتائج المرجوة هو أمر جيد لغز المعرفة ABI ).
من السهل جدًا ارتكاب مثل هذه الأخطاء ، لذا فإن جميع المترجمين المعاصرين لديهم القدرة على تحذير المطورين من حدوث عدم تطابق. يحتوي كل من gcc و clang على تعليقات توضيحية للوظيفة بنمط printf ، ويمكنهما التحذير من حالات عدم التطابق (ومع ذلك ، للأسف ، لا تعمل التعليقات التوضيحية مع وظائف نمط wprintf). يحتوي VC ++ على تعليقات توضيحية (للأسف أخرى) يمكن استخدامها / تحليلها للتحذير من حالات عدم التطابق ، ولكن إذا لم تستخدم / تحلل ، فسيتم تحذيرك فقط من وظائف نمط CRT printf / wprintf ، وليس وظائفك المخصصة ...
قامت الشركة التي عملت بها بوضع تعليقات توضيحية على وظائفها بأسلوب printf بحيث يصدر مجلس التعاون الخليجي / clang التحذيرات ، لكنه قرر لاحقًا تجاهل التحذيرات. هذا قرار غريب ، لأن مثل هذه التحذيرات هي مؤشرات دقيقة تمامًا للأخطاء - نسبة الإشارة إلى الضوضاء لا نهائية.
قررت البدء في تنظيف هذه الأخطاء باستخدام VC ++ و / تحليل التعليقات التوضيحية للعثور على جميع الأخطاء بالضبط. لقد عملت من خلال معظم الأخطاء وقمت بإجراء تغيير كبير واحد في انتظار التحقق من الكود قبل إرساله.

كان هناك انقطاع في الطاقة في مركز البيانات في نهاية هذا الأسبوع وتعطلت جميع خوادمنا (ربما بسبب أخطاء في تكوين الطاقة). هرع موظفو الطوارئ لاستعادة وإصلاح كل شيء قبل خسارة الكثير من الأموال.
الجانب المضحك من أخطاء printf هو أنها تسيء التصرف بنسبة 100٪ من الوقت. أي ، إذا كانوا سيعرضون بيانات غير صحيحة أو يتسببون في تعطل البرنامج ، فإن هذا يحدث في كل مرة. لذلك ، يمكنهم البقاء في البرنامج فقط إذا كانوا في رمز تسجيل لا يُقرأ أبدًا ، أو في رمز معالجة الأخطاء الذي نادرًا ما يتم تنفيذه.
اتضح أن حدث "إعادة التشغيل المتزامن لجميع الخوادم" تسبب في تحرك الشفرة على طول المسارات التي لا يتم تنفيذها عادةً. بدأ بدء الخوادم بالبحث عن خوادم أخرى ، ولم يتمكن من العثور عليها ، وعرض شيئًا مثل هذه الرسالة:
fprintf (السجل ، "لا يمكن العثور على الخادم٪ s. رمز الخطأ٪ d. \ n" ، خطأ ، اسم الخادم) ؛
وجه الفتاة. اكتب عدم تطابق لعدد عشوائي من الوسائط. والمغادرة.
يواجه المستجيبون للطوارئ مشكلة إضافية. كانت الخوادم بحاجة إلى إعادة التشغيل ، ولكن لا يمكن القيام بذلك قبل فحص تفريغ الأعطال ، واكتشاف خطأ ، ولم يتم إعادة بناء ثنائيات الخادم ، وتم إصدار بنية جديدة. لقد كانت عملية سريعة إلى حد ما - على ما يبدو ، ليس أكثر من بضع ساعات ، ولكن كان من الممكن تجنبها.
اعتقدت أن هذه القصة توضح تمامًا سبب قضاء الوقت في استكشاف أسباب هذه التحذيرات - لماذا نتجاهل التحذيرات التي تخبرنا أن الشفرة ستتعطل بالتأكيد أو تتصرف بشكل سيء عند تنفيذها؟ ومع ذلك ، لم يزعج أحد أن إلغاء هذه الفئة من التحذيرات يمكن أن يوفر علينا عدة ساعات من التوقف. في الواقع ، لا يبدو أن ثقافة الشركة مهتمة بأي من هذه الإصلاحات. لكن هذا الخطأ الأخير جعلني أدرك أن الوقت قد حان للانتقال إلى شركة أخرى.
ما الدروس التي يمكن تعلمها من هذا؟
إذا كان جميع المعنيين يعملون بجد على ميزات المنتج وإصلاح الأخطاء المعروفة ، فمن المحتمل أن تكون هناك أخطاء بسيطة جدًا معروضة على الشاشة العامة. اقض بعض الوقت في دراسة السجلات ، وتنظيف تحذيرات المترجم (على الرغم من أنه في الواقع ، إذا كانت لديك تحذيرات المترجم ، فمن المحتمل أن يكون من المفيد إعادة التفكير في القرارات التي اتخذتها في حياتك) ، قم بتشغيل المحلل لبضع دقائق. تحصل على نقاط إضافية إذا قمت بإضافة نظام التسجيل الخاص بك ، أو قمت بتمكين التحذيرات الجديدة ، أو استخدام أداة تعريف لا يستخدمها أحد سواك.
إذا كنت تقوم بإصلاحات ممتازة تعمل على تحسين استخدام أو استقرار الذاكرة / وحدة المعالجة المركزية ، ولا أحد يهتم بها ، فابحث عن شركة تقدرها.
مناقشة Hacker News هنا ، مناقشة Reddit هنا ، مناقشة Twitter هنا .
إعلان
سيسمح لك الخادم الموثوق به للإيجار والاختيار الصحيح لخطة التعريفة بأن تكون أقل تشتتًا بسبب إشعارات المراقبة غير السارة - كل شيء سيعمل بسلاسة وبوقت تشغيل مرتفع للغاية!
