اسمي Danil Mukhametzyanov وأنا أعمل كمطور خلفية في Badoo منذ سبع سنوات. خلال هذا الوقت ، تمكنت من إنشاء وتغيير كمية كبيرة من التعليمات البرمجية. كبيرة لدرجة أن المدير جاء إلي ذات يوم وقال لي: "الحصة قد انتهت. لإضافة شيء ما ، تحتاج إلى إزالة شيء ما ".
حسنًا ، هذه مجرد مزحة - لم يقل ذلك. من المؤسف! على مدار فترة وجود الشركة بالكامل ، جمعت Badoo أكثر من 5.5 مليون سطر من رمز العمل المنطقي ، باستثناء الأسطر الفارغة وأقواس الإغلاق.
الكمية نفسها ليست مخيفة جدًا: إنه يكذب ولا يطلب الطعام. لكن منذ عامين أو ثلاثة أعوام ، بدأت ألاحظ أنني أقرأ أكثر فأكثر وأحاول اكتشاف رمز لا يعمل حقًا في بيئة الإنتاج. هذا ، في الواقع ، ميت.
لم ألاحظ هذا الاتجاه فقط من قبلي. أدرك Badoo أن مهندسينا الذين يتقاضون رواتب عالية يهدرون الوقت باستمرار على كود ميت
لقد قدمت هذا الحديث في Badoo PHP Meetup # 4
من أين يأتي الرمز الميت؟
بدأنا في البحث عن أسباب المشاكل قسمهم إلى فئتين:
- عملية - تلك التي تنشأ نتيجة التنمية ؛
- التاريخية - رمز الإرث.
بادئ ذي بدء ، قررنا تفكيك مصادر العملية من أجل منع ظهور مشاكل جديدة.
اختبار A / B
بدأت Badoo في استخدام اختبارات A / B بنشاط منذ أربع سنوات. الآن لدينا حوالي 200 اختبار قيد التشغيل باستمرار ، وجميع ميزات المنتج تمر عبر هذا الإجراء.
نتيجة لذلك ، تم تجميع حوالي 2000 اختبار مكتمل في أربع سنوات ، وهذا الرقم في تزايد مستمر. لقد أخافتنا من أن كل اختبار هو جزء من رمز ميت لم يعد يتم تنفيذه ولم يعد مطلوبًا على الإطلاق.
جاء حل المشكلة سريعًا: لقد بدأنا تلقائيًا في إنشاء تذكرة لاستغناء الرمز عند الانتهاء من اختبار A / B.
مثال على تذكرة
لكن العامل البشري بدأ بشكل دوري. مرارًا وتكرارًا ، وجدنا رمز الاختبار الذي استمر في العمل ، لكن لم يفكر أحد فيه وأكمل الاختبار.
ثم كان هناك إطار عمل صارم: يجب أن يكون لكل اختبار تاريخ انتهاء. إذا نسي المدير قراءة نتائج الاختبار ، فسيتوقف ويتوقف تلقائيًا. وكما ذكرت سابقًا ، تم إنشاء تذكرة تلقائيًا لقصها مع الحفاظ على الإصدار الأصلي لمنطق الميزة.
بمساعدة هذه الآلية البسيطة ، تخلصنا من طبقة كبيرة من العمل.
تنوع العملاء
يتم دعم العديد من العلامات التجارية في شركتنا ، ولكن الخادم واحد. يتم تمثيل كل علامة تجارية على ثلاث منصات: الويب و iOS و Android. في نظامي iOS و Android ، لدينا دورة تطوير أسبوعية: مرة في الأسبوع ، جنبًا إلى جنب مع التحديث ، نتلقى إصدارًا جديدًا من التطبيق على كل نظام أساسي.
من السهل تخمين أنه مع هذا النهج ، لدينا في غضون شهر ما يقرب من اثني عشر نسخة جديدة تحتاج إلى الدعم. يتم توزيع حركة مرور المستخدمين بينهم بشكل غير متساو: يتحول المستخدمون تدريجياً من إصدار إلى آخر. تحتوي بعض الإصدارات القديمة على حركة مرور ، ولكنها صغيرة جدًا بحيث يصعب الحفاظ عليها. إنه صعب وعديم الفائدة.
لذلك بدأنا في حساب عدد الإصدارات التي نريد دعمها. يوجد حدان للعميل: الحد المرن والحد الأقصى.
عندما يتم الوصول إلى الحد الأدنى (عندما يتم إطلاق ثلاثة أو أربعة إصدارات جديدة بالفعل ، ولا يزال التطبيق غير محدث) ، يرى المستخدم شاشة مع تحذير بأن نسخته قديمة. عندما يتم الوصول إلى الحد الأقصى (حوالي 10 إلى 20 نسخة "مفقودة" ، اعتمادًا على التطبيق والعلامة التجارية) ، نقوم ببساطة بإزالة خيار تخطي هذه الشاشة. يصبح محظورًا: لا يمكنك استخدام التطبيق معه.

شاشة للحد الصعب
في هذه الحالة ، من غير المجدي الاستمرار في معالجة الطلبات الواردة من العميل - لن يرى أي شيء سوى شاشة.
ولكن هنا ، كما في حالة اختبارات A / B ، نشأ فارق بسيط. مطورو العملاء هم أشخاص أيضًا. يستخدمون تقنيات جديدة وشرائح من أنظمة التشغيل - وبعد فترة لم يعد إصدار التطبيق مدعومًا في الإصدار التالي من نظام التشغيل. ومع ذلك ، لا يزال الخادم يعاني لأنه يجب أن يستمر في معالجة هذه الطلبات.
توصلنا إلى حل منفصل للحالة عند انتهاء دعم Windows Phone. أعددنا شاشة تخبر المستخدم: "نحن نحبك كثيراً! انت رائع جدا! لكن هل يمكنك البدء في استخدام منصة أخرى؟ ستتوفر لك وظائف رائعة جديدة ، ولكن هنا لا يمكننا فعل أي شيء ". كقاعدة عامة ، نقدم منصة ويب كمنصة بديلة ، وهي متاحة دائمًا.
باستخدام هذه الآلية البسيطة ، قمنا بتحديد عدد إصدارات العميل التي يدعمها الخادم: حوالي 100 إصدار مختلف من جميع العلامات التجارية ، من جميع الأنظمة الأساسية.
أعلام الميزة
ومع ذلك ، من خلال تعطيل دعم الأنظمة الأساسية القديمة ، لم نفهم تمامًا ما إذا كان من الممكن قطع الكود الذي كانوا يستخدمونه تمامًا. أم أن الأنظمة الأساسية المتبقية لإصدارات نظام التشغيل الأقدم تستمر في استخدام نفس الوظيفة؟
تكمن المشكلة في أن واجهة برمجة التطبيقات (API) الخاصة بنا لم يتم إنشاؤها على الجزء الذي تم إصداره ، ولكن على استخدام علامات الميزات. كيف توصلنا إلى هذا ، يمكنك معرفة ذلك من هذا التقرير .
كان لدينا نوعان من أعلام الميزات. سأخبرك عنهم بأمثلة.
ميزات ثانوية
يقول العميل للخادم ، "مرحبًا ، هذا أنا. أنا أؤيد منشورات الصور ". ينظر الخادم إليه ويرد: "رائع ، دعم! الآن أعرف ذلك وسأرسل لك رسائل مصورة ". الميزة الأساسية هنا هي أن الخادم لا يمكنه التأثير على العميل بأي شكل من الأشكال - فهو ببساطة يقبل الرسائل منه ويضطر إلى الاستماع إليه.
نسمي هذه الأعلام ميزات ثانوية. في الوقت الحالي لدينا أكثر من 600 منهم ،
ما هو عيب استخدام هذه الأعلام؟ بشكل دوري ، هناك وظائف ثقيلة لا يمكن تغطيتها من جانب العميل فقط - فأنت تريد التحكم فيها من جانب الخادم أيضًا. لهذا ، قدمنا أنواعًا أخرى من الأعلام.
ميزات التطبيق
نفس العميل ونفس الخادم. يقول العميل: "الخادم ، لقد تعلمت دعم بث الفيديو. قم بتشغيله؟ " يرد الخادم ، "شكرًا ، سأضع ذلك في الاعتبار". ويضيف: "عظيم. دعونا نظهر لمستخدمنا المحبوب هذه الوظيفة ، سيكون سعيدًا ". أو: "حسنًا ، لكننا لن ندرجها بعد."
نسمي هذه الميزات ميزات التطبيق. إنها أثقل ، لذلك لدينا عدد أقل منها ، لكنها كافية: أكثر من 300.
لذلك ، يقوم المستخدمون بالتبديل من إصدار واحد من العميل إلى آخر. بدأ دعم نوع من العلم من قبل جميع الإصدارات النشطة من التطبيقات. أو ، على العكس من ذلك ، غير مدعوم. ليس من الواضح تمامًا كيفية التحكم في هذا: 100 إصدار للعميل ، 900 علامة! للتعامل مع هذا ، قمنا ببناء لوحة القيادة.
مربع أحمر عليه يعني أن جميع إصدارات هذا النظام الأساسي لا تدعم هذه الميزة ؛ أخضر - تدعم جميع إصدارات هذا النظام الأساسي هذه العلامة. إذا كان بالإمكان إيقاف تشغيل العلم وتشغيله ، فسيومض بشكل دوري. يمكننا أن نرى ما يحدث في أي إصدار.
شاشة لوحة المعلومات
مباشرة في هذه الواجهة ، بدأنا في إنشاء مهام لاستبعاد الوظائف. تجدر الإشارة إلى أنه لا يلزم ملء جميع الخلايا الحمراء أو الخضراء في كل صف. هناك أعلام تعمل على منصة واحدة فقط. هناك أعلام تم ملؤها لعلامة تجارية واحدة فقط.
أتمتة العملية ليست مريحة للغاية ، ولكنها ، من حيث المبدأ ، ليست ضرورية - ما عليك سوى تعيين مهمة وإلقاء نظرة دورية على لوحة القيادة. في التكرار الأول ، تمكنا من قطع أكثر من 200 علم. هذا ما يقرب من ربع الأعلام التي استخدمناها!
هذا هو المكان الذي انتهت فيه مصادر العملية. لقد ظهرت نتيجة لتدفق التطوير لدينا ، وقمنا بدمج العمل معهم بنجاح في هذه العملية.
ماذا تفعل بالكود القديم
لقد أوقفنا ظهور مشاكل جديدة في مصادر العملية. وواجهنا سؤالا صعبا: ماذا نفعل بالكود القديم الذي تراكم على مر السنين؟ لقد تعاملنا مع الحل من وجهة نظر هندسية ، أي أننا قررنا أتمتة كل شيء. لكن لم يكن من الواضح كيفية العثور على الكود الذي لم يتم استخدامه. اختبأ في عالمه الصغير المريح: لم يتم استدعاؤه بأي شكل من الأشكال ، ولا يدع أي شخص يعرف عن نفسه.
كان علي أن أذهب من الجانب الآخر: أخذ كل الكود الذي لدينا ، وجمع المعلومات حول القطع التي تم تنفيذها بالضبط ، ثم قم بالعكس.
ثم قمنا بتجميعها وتنفيذها بأدنى مستوى - على الملفات. بهذه الطريقة يمكننا بسهولة الحصول على قائمة بالملفات من المستودع عن طريق تشغيل أمر UNIX المناسب.
بقي لجمع قائمة من الملفات التي يتم استخدامها في الإنتاج. الأمر بسيط للغاية: لكل طلب عند الإغلاق ، اتصل بوظيفة PHP المقابلة. التحسين الوحيد الذي قمنا به هنا هو بدء طلب OPCache بدلاً من طلب كل طلب. خلاف ذلك ، ستكون كمية البيانات كبيرة جدًا.
نتيجة لذلك ، اكتشفنا العديد من القطع الأثرية المثيرة للاهتمام. ولكن بتحليل أعمق ، أدركنا أننا نفتقد الطرق غير المستخدمة: كان الاختلاف في عددها من ثلاث إلى سبع مرات.
اتضح أنه يمكن تحميل الملف وتنفيذه وترجمته من أجل ثابت واحد فقط أو طريقتين. كل شيء بقي عديم الفائدة في هذا البحر الذي لا قاع له.
تجميع قائمة الأساليب
ومع ذلك ، فقد اتضح بسرعة كافية لجمع قائمة كاملة من الأساليب. لقد أخذنا للتو المحلل اللغوي لنيكيتا بوبوف وقمنا بإطعامه مستودعنا وحصلنا على كل ما لدينا في الكود.
يبقى السؤال: كيف نجمع ما يتم تشغيله في الإنتاج؟ نحن مهتمون بالإنتاج ، لأن الاختبارات يمكن أن تغطي ما لا نحتاجه على الإطلاق. دون التفكير مرتين ، أخذنا XHProf. لقد تم تنفيذه بالفعل في الإنتاج لجزء من الاستعلامات ، وبالتالي كان لدينا عينات ملفات شخصية مخزنة في قواعد البيانات. كان يكفي مجرد الذهاب إلى قواعد البيانات هذه ، وتحليل اللقطات التي تم إنشاؤها - والحصول على قائمة بالملفات.
عيوب XHProf
كررنا هذه العملية على مجموعة أخرى حيث لم يبدأ XHProf ، ولكن كانت هناك حاجة ماسة إليه. هذه مجموعة لتشغيل البرامج النصية في الخلفية والمعالجة غير المتزامنة ، وهو أمر مهم للحمل العالي ، فهي تدير الكثير من المنطق.
ثم تأكدنا من أن XHProf غير مريح لنا.
- يتطلب تغيير كود PHP. تحتاج إلى إدخال رمز بدء التتبع ، وإنهاء التتبع ، والحصول على البيانات المجمعة ، وكتابتها في ملف. بعد كل شيء ، هذا ملف تعريف ، ولدينا إنتاج ، أي ، هناك الكثير من الطلبات ، تحتاج إلى التفكير في أخذ العينات أيضًا. في حالتنا ، تفاقم هذا بسبب وجود عدد كبير من التجمعات ذات نقاط الدخول المختلفة.
- . . , OPCache. : XHProf, . , core- .
- . . XHProf . ( XHProf): CPU, , . , , . - XHProf aggregator ( XHProf Live Profiler, open-source) , , , . , : «, , », CPU , , Live Profiler . , , .
- XHProf. , . . , . : , ( , youROCK، هذا ليس مطلوبًا من قبل lsd ، ولكن كان من الأنسب الاحتفاظ بغلاف واحد فوقه). تصحيح XHProf ليس ما أردنا القيام به ، لأنه أداة تعريف كبيرة إلى حد ما (ماذا لو كسرنا شيئًا عن غير قصد؟).
كانت هناك فكرة أخرى - لاستبعاد مساحات أسماء معينة ، على سبيل المثال ، مساحات أسماء البائعين من الملحن ، والتي يتم تنفيذها في الإنتاج ، لأنها عديمة الفائدة: لن نقوم بإعادة تشكيل حزم البائعين ونقطع كودًا إضافيًا منها.
متطلبات الحل
اجتمعنا مرة أخرى ونظرنا في الحلول الموجودة. وصاغوا القائمة النهائية للمتطلبات.
أولاً: الحد الأدنى من النفقات العامة. بالنسبة لنا ، كان XHProf هو الشريط: ليس أكثر مما يتطلبه.
ثانيًا ، لم نرغب في تغيير كود PHP.
ثالثًا ، أردنا أن يعمل الحل في كل مكان - سواء في FPM أو في CLI.
رابعًا ، أردنا التعامل مع الشوكات. يتم استخدامها بنشاط في CLI ، على الخوادم السحابية. لم أرغب في عمل منطق محدد لهم داخل PHP.
خامساً: أخذ العينات من الصندوق. في الواقع ، هذا يأتي من شرط عدم تغيير كود PHP. سأوضح أدناه سبب حاجتنا لأخذ العينات.
السادس والأخير:القدرة على القوة من التعليمات البرمجية. نحن نحب ذلك عندما يعمل كل شيء تلقائيًا ، ولكن في بعض الأحيان يكون من الأنسب البدء والتعديل والنظر يدويًا. لقد احتجنا إلى القدرة على تمكين وتعطيل كل شيء مباشرةً من الكود ، وليس بقرار عشوائي من الآلية الأكثر عمومية لوحدة PHP ، والتي تحدد احتمالية التضمين من خلال الإعدادات.
كيف يعمل funcmap
نتيجة لذلك ، لدينا حل نسميه funcmap.
Funcmap هو في الأساس امتداد PHP. في مصطلحات PHP ، هذه وحدة PHP. لفهم كيفية عملها ، دعنا نلقي نظرة على كيفية عمل عملية PHP ووحدة PHP.
لذلك ، تبدأ العملية. يتيح PHP الاشتراك في الخطافات عند بناء وحدة. تبدأ العملية ، يتم تشغيل خطاف GINIT (التهيئة العامة) ، حيث يمكنك تهيئة المعلمات العامة. ثم يتم تهيئة الوحدة النمطية. يمكن إنشاء الثوابت وتخصيصها هناك ، ولكن فقط لوحدة معينة ، وليس لطلب ، وإلا فإنك ستطلق النار على قدمك.
ثم يأتي طلب المستخدم ، يتم استدعاء خطاف RINIT (طلب التهيئة). عند اكتمال الطلب ، يحدث إيقاف تشغيله ، وفي النهاية - إيقاف تشغيل الوحدة: MSHUTDOWN و GSHUTDOWN. كل شيء منطقي.
إذا كنا نتحدث عن FPM ، فإن كل طلب مستخدم يأتي إلى عامل موجود بالفعل. في الأساس ، تعمل RINIT و RSHUTDOWN في دائرة حتى تقرر FPM أن العامل قد عفا عليه الزمن ، وقد حان الوقت لإطلاق النار عليه وإنشاء واحد جديد. إذا كنا نتحدث عن CLI ، فهي مجرد عملية خطية. سيتم استدعاء كل شيء مرة واحدة.

كيف يعمل funcmap
خارج هذه المجموعة ، كنا مهتمين بخطافين . الأول هو RINIT . بدأنا في تعيين علم جمع البيانات: هذا نوع من العشوائية تم استدعاؤه لأخذ عينات من البيانات. إذا نجح الأمر ، فقد قمنا بمعالجة هذا الطلب: قمنا بجمع إحصائيات لاستدعاءات الوظائف والطرق الخاصة به. إذا لم يفلح ، فلن تتم معالجة الطلب. الشيء
التالي هو إنشاء جدول تجزئة إذا لم يكن موجودًا. يتم توفير جدول التجزئة داخليًا بواسطة PHP نفسها. ليست هناك حاجة لاختراع أي شيء هنا - فقط خذها واستخدمها.
بعد ذلك ، نقوم بتهيئة المؤقت. سأتحدث عنه أدناه ، في الوقت الحالي ، فقط تذكر أنه مهم ومطلوب.
الخطاف الثاني هو MSHUTDOWN... أريد أن أشير إلى أنه MSHUTDOWN ، وليس RSHUTDOWN. لم نرغب في إيجاد شيء لكل طلب - كنا مهتمين بالعامل بأكمله. في MSHUTDOWN ، نأخذ جدول التجزئة الخاص بنا ، ونتفوق عليه ونكتب ملفًا (ما الذي يمكن أن يكون أكثر موثوقية وملاءمة وتنوعًا من الملف القديم الجيد؟).
يتم ملء جدول التجزئة بكل بساطة بواسطة نفس خطاف PHP zend_execute_ex ، والذي يتم استدعاؤه في كل مرة يتم فيها استدعاء وظيفة محددة بواسطة المستخدم. يحتوي السجل على معلمات إضافية يمكنك من خلالها فهم نوع الوظيفة واسمها وفئتها. نحن نقبله ، ونقرأ الاسم ، ونكتبه في جدول التجزئة ، ثم نسميه الخطاف الافتراضي.
هذا الخطاف لا يكتب وظائف مضمنة. إذا كنت تريد تجاوز الوظائف المضمنة ، فهناك وظيفة منفصلة لذلك تسمى zend_execute_internal.
ترتيب
كيف يمكنني تكوين هذا بدون تغيير كود PHP؟ الإعدادات بسيطة للغاية:
- ممكّن: سواء تم تمكينه أم لا.
- الملف الذي نكتب إليه. يوجد عنصر نائب pid لاستبعاد شرط السباق عندما تكتب عمليات PHP مختلفة إلى نفس الملف في نفس الوقت.
- أساس الاحتمال: علم الاحتمال الخاص بنا. إذا قمت بتعيينه على 0 ، فلن تتم كتابة أي طلب ؛ إذا كانت 100 - عندها سيتم تسجيل جميع الطلبات وإدراجها في الإحصائيات.
- flush_interval. هذا هو معدل تكرار تفريغ جميع البيانات في ملف. نريد أن يتم تنفيذ جمع البيانات في CLI ، ولكن هناك نصوص يمكن تنفيذها لفترة طويلة ، مما يستهلك الذاكرة إذا كنت تستخدم قدرًا كبيرًا من الوظائف.
بالإضافة إلى ذلك ، إذا كان لدينا مجموعة غير محملة بشكل كبير ، فإن FPM تدرك أن العامل مستعد لمعالجة المزيد ، ولا يقتل العملية - فهو يعيش ويأكل جزءًا من الذاكرة. بعد فترة زمنية معينة ، نقوم بغسل كل شيء على القرص ، وإعادة تعيين جدول التجزئة والبدء في ملئه من جديد. ومع ذلك ، إذا لم يتم الوصول إلى المهلة بعد ، فسيتم تشغيل خطاف MSHUTDOWN ، حيث نكتب كل شيء في النهاية.
آخر شيء أردناه هو القدرة على استدعاء funcmap من كود PHP. يوفر الامتداد المقابل الطريقة الوحيدة التي تسمح لك بتمكين أو تعطيل جمع الإحصائيات بغض النظر عن كيفية عمل الاحتمال.
النفقات العامة
تساءلنا كيف يؤثر كل هذا على خوادمنا. لقد أنشأنا رسمًا بيانيًا يوضح عدد الطلبات القادمة إلى آلة قتالية حقيقية لواحدة من أكثر مجموعات PHP تحميلًا.
يمكن أن يكون هناك العديد من هذه الأجهزة ، لذا يوضح الرسم البياني عدد الطلبات ، وليس وحدة المعالجة المركزية. يدرك الموازن أن الآلة بدأت في استهلاك موارد أكثر من المعتاد وتحاول موازنة الطلبات بحيث يتم تحميل الآلات بالتساوي. كان هذا كافيًا لفهم كيف كان الخادم مهينًا.
قمنا بتشغيل امتدادنا بالتتابع عند 25٪ و 50٪ و 100٪ وشاهدنا الصورة التالية:
الخط المنقط هو عدد الطلبات التي نتوقعها. الخط الرئيسي هو عدد الطلبات الواردة. لقد لاحظنا انخفاضًا بنسبة 6٪ و 12٪ و 23٪ تقريبًا: بدأ هذا الخادم في معالجة ما يقرب من ربع الطلبات الواردة أقل.
يثبت هذا الرسم البياني أولاً وقبل كل شيء أن أخذ العينات مهم بالنسبة لنا: لا يمكننا إنفاق 20٪ من موارد الخادم على جمع الإحصائيات.
نتيجة خاطئة
أخذ العينات له تأثير جانبي: بعض الأساليب غير مدرجة في الإحصائيات ، ولكنها في الواقع مستخدمة. حاولنا محاربة هذا بعدة طرق:
- . -, . , , , , .
- . , : , , .
لقد جربنا حلين لمعالجة الأخطاء. الأول هو تمكين جمع الإحصائيات بالقوة بدءًا من لحظة إنشاء الخطأ: اجمع سجل الأخطاء وحللها. ولكن هناك مأزق هنا: عندما يسقط المورد ، يزداد عدد الأخطاء على الفور. تبدأ في معالجتها ، وهناك العديد من العمال - وتبدأ الكتلة في الموت ببطء. لذلك ، فإن القيام بذلك ليس صحيحًا تمامًا.
كيف تفعل ذلك بشكل مختلف؟ قرأنا ، وباستخدام المحلل اللغوي لنيكيتا بوبوف ، درسنا المخاطر ، مع الإشارة إلى الطرق التي يتم استدعاؤها هناك. وبالتالي ، فقد أزلنا العبء على الخادم وقللنا عدد الإيجابيات الخاطئة.
ولكن لا تزال هناك طرق نادرًا ما يتم استدعاؤها والتي لم يكن من الواضح ما إذا كانت مطلوبة أم لا. لقد أضفنا مساعدًا يساعد في تحديد حقيقة استخدام مثل هذه الأساليب: إذا أظهر أخذ العينات بالفعل أن الطريقة نادراً ما يتم الاتصال بها ، فيمكنك تشغيل المعالجة بنسبة 100٪ وعدم التفكير فيما يحدث. سيتم تسجيل أي تنفيذ لهذه الطريقة. ستعرف عنها.
إذا كنت تعرف على وجه اليقين أن الطريقة يتم استخدامها ، فقد تكون مبالغة. ربما تكون هذه وظيفة ضرورية ولكنها نادرة. تخيل أن لديك خيار "الشكوى" ، والذي نادرًا ما يتم استخدامه ، ولكنه مهم - لا يمكنك استبعاده. في مثل هذه الحالات ، تعلمنا كيفية تسمية هذه الأساليب يدويًا.
لقد أنشأنا واجهة توضح الأساليب المستخدمة (وهي على خلفية بيضاء) والتي من المحتمل ألا تكون مستخدمة (فهي على خلفية حمراء). هنا يمكنك أيضًا تحديد الطرق الضرورية.
شاشة الواجهة
الواجهة رائعة ، لكن دعنا نعود إلى البداية ، وهي المشكلة التي كنا نحلها. يتألف من حقيقة أن مهندسينا يقرؤون التعليمات البرمجية الميتة. أين يقرؤونه؟ في IDE. تخيل كيف سيكون الأمر عندما تجعل معجبًا بمهنتك يترك عالم IDE لنوع من واجهة الويب ويفعل شيئًا هناك! قررنا أننا بحاجة إلى مقابلة زملائنا في منتصف الطريق.
لقد أنشأنا ملحقًا لـ PhpStorm يقوم بتحميل قاعدة البيانات الكاملة للطرق غير المستخدمة ويعرض ما إذا كانت هذه الطريقة مستخدمة أم لا. علاوة على ذلك ، في الواجهة ، يمكنك تمييز الطريقة على أنها مستخدمة. سيذهب كل هذا إلى الخادم وسيصبح متاحًا لبقية المساهمين في قاعدة التعليمات البرمجية.
هذا يختتم الجزء الرئيسي من عملنا مع Legacy. بدأنا نلاحظ بشكل أسرع أننا لا ننفذ ، للرد بشكل أسرع وعدم إضاعة الوقت في البحث عن التعليمات البرمجية غير المستخدمة يدويًا.
ملحق funcmap متاح على GitHub . سنكون سعداء إذا كان مفيدًا لشخص ما.
البدائل
من الخارج ، قد يبدو أننا في Badoo لا نعرف ماذا نفعل بأنفسنا. لماذا لا تلقي نظرة على ما هو موجود في السوق؟
هذا سؤال عادل. نظرنا - ولم يكن هناك شيء في السوق في تلك اللحظة. فقط عندما بدأنا في تنفيذ حلنا بفاعلية اكتشفنا أنه في نفس الوقت ، قام رجل يدعى جو واتكينز ، يعيش في ضبابية بريطانيا العظمى ، بتنفيذ فكرة مماثلة وإنشاء امتداد Tombs.
لم ندرسها بعناية شديدة ، لأن لدينا بالفعل حل خاص بنا ، لكننا مع ذلك وجدنا عدة مشاكل:
- عدم أخذ العينات. أعلاه ، شرحت سبب حاجتنا إليه.
- . , APCu ( ), .
- CLI. , , CLI-, .
- . Tombs, , , , , , . funcmap («» , ): , . Tombs , , FPM CLI. - , .
أولاً ، فكر مسبقًا في كيفية إزالة الوظائف التي يتم تنفيذها لفترة قصيرة من الوقت ، خاصةً إذا كان التطوير نشطًا للغاية. في حالتنا ، كانت هذه اختبارات أ / ب. إذا كنت لا تفكر في الأمر مسبقًا ، فسيتعين عليك تنظيف الأنقاض.
ثانيًا: تعرف على عملائك بالنظر. لا يهم إذا كانت داخلية أو خارجية - يجب أن تعرفها. في مرحلة ما ، عليك أن تقول لهم: "عزيزي ، توقف! لا".
ثالثًا: تنظيف API الخاص بك. هذا يؤدي إلى تبسيط النظام بأكمله.
ورابعًا: يمكنك أتمتة كل شيء ، حتى البحث عن الكود الميت. الذي فعلناه.