سيعرض Liveprof متى ولماذا تغير أداء تطبيق PHP الخاص بك



مرحبا يا هبر! اسمي Timur Shagiakhmetov ، أنا مطور PHP على Badoo .

يعد أداء التطبيق من أهم المعايير لجودة عمل المبرمج. في الأمور المتعلقة بتحسين تطبيقات PHP ، يكون المساعد هو المحلل.

لقد تحدثنا مؤخرًا عن الأدوات التي نستخدمها للتوصيف. واسمحوا لي أن أذكركم: أحد أدوات تحليل الأداء ، عندما لا يكون من الواضح أي أجزاء من الكود التي أثرت في زيادة وقت توليد الاستجابة ، هي XHProf . هذا امتداد لـ PHP الذي يسمح لك برمز الملف الشخصي على خادم قتالي ومن ثم تحسينه.

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

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

في هذه المقالة سأتحدث عن تفاصيل التطبيق وميزات استخدام هذه الأداة.

قليلا عن XHProf


أولاً ، بضع كلمات حول ميزات XHProf نفسها. هذا هو ملف التعريف ل PHP مكتوب في C امتدادا. تم تطويره على Facebook ونشره في المجال العام. لديها عدة شوكات ( uprofiler ، Tideways ) ، متوافقة تمامًا على مستوى تنسيق بيانات الإخراج.

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

نتيجة XHProf عبارة عن مجموعة من العناصر بالتنسيق التالي:

$data = [ 'parentMethodName==>childMethodName' => [ 'ct' => 1 'wt' => 8 'cpu' => 11 'mu' => 528 'pmu' => 0 ] ]; 

اين

parentMethodName و childMethodName هما childMethodName الأصل childMethodName ، على التوالي ؛
ct - عدد المكالمات في سياق الطلب ؛
wt - وقت تنفيذ الطلب (يتكون من الوقت الذي يقضيه المعالج ووقت انتظار الإدخال / الإخراج أو استجابة خدمة أخرى) ؛
cpu - الوقت الذي يقضيه المعالج في معالجة الطلب ؛
mu - التغيير في استهلاك الذاكرة بعد استدعاء الأسلوب ؛
pmu - التغيير في استهلاك الذاكرة الذروة بعد استدعاء الأسلوب.

بعض الخيارات الأخرى ممكنة أيضا.

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

على سبيل المثال

نتيجة فرز فقاعة
 <?php class ArrayGenerator { public function getRandomArray(int $count): array { $array = []; for ($i = 0; $i < $count; $i++) { $array[] = rand(0, 1000); } return $array; } } class BubbleSorter { public function sort(&$array): void { $len = count($array); for ($i = 0; $i < $len ; $i++) { for ($j = 0; $j < $len - $i - 1; $j++) { if ($array[$j] > $array[$j + 1]) { $this->swap($array[$j], $array[$j + 1]); } } } } private function swap(&$a, &$b): void { $tmp = $a; $a = $b; $b = $tmp; } public function isSorted(array $array): bool { $len = count($array); for ($i = 0; $i < $len - 1; $i++) { if ($array[$i] > $array[$i + 1]) { return false; } } return true; } } class ArrayPrinter { public function print(array $array, string $delimiter = ' '): void { echo implode($delimiter, $array) . PHP_EOL; } } xhprof_enable(); $n = 10; $arrayGenerator = new \ArrayGenerator(); $array = $arrayGenerator->getRandomArray($n); $sorter = new BubbleSorter(); if (!$sorter->isSorted($array)) { $sorter->sort($array); } $printer = new \ArrayPrinter(); $printer->print($array); $xhprof_data = xhprof_disable(); 




يمكنك الانتقال إلى داخل كل طريقة لمعرفة الطرق التي استهلكت عدد الموارد.

يمكنك أيضًا إلقاء نظرة على الرسم البياني للمكالمات من خلال إبراز الطرق الأكثر كثافة للموارد:



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

Liveprof: النتائج الإجمالية والحفاظ على التاريخ


كيفية الحصول على التنميط التاريخ؟

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

أداتنا لها مزايا و بعض القيود.

ما يمكن للمجمع القيام به:


  1. التنميط التلقائي لكل طلب نث.
  2. التجميع اليومي للملفات الشخصية المجمعة.
  3. القدرة على رؤية الرسوم البيانية للتغييرات في كل معلمة تقاس من قبل منشئ ملفات التعريف. على سبيل المثال ، وزن ، وحدة المعالجة المركزية ، مو ، PMU المذكورة أعلاه.
  4. شاهد التغيير في أداء أي طريقة لفترة زمنية معينة.
  5. الرسم البياني للهب على أساس أحدث البيانات المجمعة.
  6. ابحث عن استعلامات تستدعي طريقة محددة

القيود:


  1. نظرًا لأن الأداة لدينا هي أداة مجمعة ، فمن المستحيل معرفة أداء استعلام واحد (على سبيل المثال ، الأبطأ) - نحصل على متوسط ​​النتائج في اليوم الأخير. ولكن هذا يكفي لتقييم ديناميات الأداء الكلي. إذا انخفض أي طلب في سرعة التنفيذ ، فسيتم تغيير متوسط ​​القيمة والنسبة المئوية 95 والحد الأقصى لوقت التنفيذ.
  2. لا يمكنك استعادة مكدس الاستدعاءات الكامل بشكل لا لبس فيه ، لأن XHProf تقوم بإرجاع أزواج الوالدين والطفل الفريدة فقط مع مجموع قيم الموارد المستهلكة.
  3. طلب خطأ وقت التشغيل المتعلق بـ XHProf. الفرق ليس كبيرًا ، ولكن يجب أن يؤخذ في الاعتبار عند قياس وقت تنفيذ الاستعلام.

كيفية استخدام التعريف


  1. أولاً ، يحتاج المُنشئ إلى أن يكون متصلاً بالموقع أو البرنامج النصي. الطريقة الأكثر ملاءمة لاستخدام الأداة هي تشغيل أداة التعريف تلقائيًا :

     php composer.phar require badoo/liveprof # Run a script to configure database LIVE_PROFILER_CONNECTION_URL=mysql://db_user:db_password@db_mysql:3306/Profiler?charset=utf8 php vendor/badoo/liveprof/bin/install.php 

    وهو يدعم إصدارات PHP بدءًا من 5.4 ، واستخدامه محفوف بحد أدنى من الحمل ، والذي يسمح لك باستخدامه في بيئة قتالية. تكتشف الأداة تلقائيًا امتداد أداة التعريف المستخدمة: XHProf أو uprofiler أو Tideways . عند بدء التشغيل ، تحتاج إلى تحديد معلمات للاتصال بقاعدة البيانات وإعدادات ملفات التعريف.

    مثال للاستخدام في التعليمات البرمجية مع الإعدادات الافتراضية:

     <?php include 'vendor/autoload.php'; \Badoo\LiveProfiler\LiveProfiler::getInstance()->start(); // Code is here 

    يتم حفظ نتائج ملفات التعريف في قاعدة البيانات. مرة واحدة في اليوم ، تتم عملية التجميع. للقيام بذلك ، حدد جميع السجلات لطلب محدد يوميًا وحساب الدوال المجمّعة لكل معلمة. يمكن توسيع وظائف التجميع أو إعادة تعريفها.

    التالية متاحة الآن:

    • على الأقل في اليوم ؛
    • الحد الأقصى في اليوم الواحد ؛
    • المتوسط ​​اليومي
    • 95 في المئة من اليوم.

  2. يستخدم عميل الويب aggregator لتكوين التجميع وعرض النتائج. أسهل طريقة لتثبيته في حاوية عامل ميناء:

     git clone https://github.com/badoo/liveprof-ui.git cd liveprof-ui docker-compose up web 
  3. قبل البدء الأول ، تحتاج إلى تكوين معلمات اتصال قاعدة البيانات ، وقائمة الحقول والوظائف الإجمالية المستخدمة في ملف التكوين src / config / services.yaml. ثم قم بتنفيذ نص التثبيت:

     docker-compose exec web bash install.sh 
  4. من الضروري التسجيل تلقائيًا في تشغيل البرامج النصية لتجميع البيانات القديمة وتنظيفها في التيجان:

     # script aggregates all profiles for previous day, add it if you don't use a queue for aggregation jobs (parameter aggregator.use_jobs_in_aggregation=false) 0 2 * * * docker-compose -f %PATH_TO_PROJECT%/docker-compose.yml run --rm --entrypoint '/usr/local/bin/php /app/bin/cli.php cron:aggregate-all-profiles' web # script removes old aggregated data, by default > 200 days 0 1 * * * docker-compose -f %PATH_TO_PROJECT%/docker-compose.yml run --rm --entrypoint '/usr/local/bin/php /app/bin/cli.php cron:remove-old-profiles' web 200 

  5. لملء بيانات الاختبار ، يمكنك تشغيل البرنامج النصي:

     docker-compose exec web php /app/bin/cli.php example:a-week-degradation 

وصف واجهة


تتوفر واجهة الويب على: 127.0.0.1:8000.

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



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



تسمح لك الصفحة التي تحتوي على قائمة كاملة من الطرق التي تم استدعاؤها بالعثور بسرعة على طريقة الاهتمام والاطلاع على الرسوم البيانية بالانتقال إلى صفحة الرسوم البيانية:


تتيح لك الصفحة التي تحتوي على الرسم البياني للهب للاستعلام التجميعي الأخير تحديد الأجزاء الأثقل بصريًا.

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


صفحة تحتوي على قائمة بالطرق التي أصبحت أبطأ خلال الفترة الزمنية المحددة.

أيضًا ، لكل طريقة ، يمكنك معرفة أي من المكالمات الفرعية أثرت على الأداء أكثر من غيرها. على سبيل المثال ، في لقطة الشاشة أدناه ، يمكنك أن ترى أن طريقة ServiceApi::getAvailableServices() بدأت في تشغيل 116 مللي ثانية بشكل أبطأ. السبب في ذلك هو إضافة استدعاء إلى ServiceApi::getGifts() (التغيير بمقدار 56 مللي ثانية) وزيادة في عدد المكالمات إلى أسلوب ServiceApi::getConfigForList() من 1 إلى 5 (50 مللي ثانية أخرى):



إذا لم يكن معروفًا مسبقًا أي استعلام تم تغيير الأداء بشكل ملحوظ ، فإن صفحة تحتوي على قائمة بالطرق التي أصبحت أبطأ دون الرجوع إلى استعلام محدد ستساعد:


صفحة تبحث عن الاستعلامات التي تستدعي طريقة معينة.

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



ميزات التخصيص


الأداة لديها فرص وافرة للتخصيص:

  • يمكنك إضافة الوظائف التجميعية الخاصة بك والتي تقوم بحساب قيمة معينة بناءً على صفيف قيم المعلمات التي تم تمريرها
  • يمكنك تغيير قاعدة البيانات لتخزين ملفات التعريف والنتائج المجمعة (يتم الآن دعم SQLite و MySQL و PostgreSQL ، لكن يمكنك استخدام الآخرين من القائمة المتاحة لـ Doctrine DBAL ) ؛
  • يمكنك تجاوز كل من مدير اتصال قاعدة البيانات وتنفيذ أساليبك للحصول على البيانات ؛
  • يمكنك استخدام واجهة الويب كمشروع مستقل وداخل أي إطار (على سبيل المثال ، لوحة تحكم الموقع). مثال:

     public function profileListAction() {      <i>//Some custom logic before</i>   $this->checkPermissions();   $App = new \Badoo\LiveProfilerUI\LiveProfilerUI();   $Page = $App->getPage('profile_method_list_page');   return $Page->setData($data)->render(); } 

الخاتمة


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

وهي متوفرة على GitHub: github.com/badoo/liveprof ، واجهة الويب هي github.com/badoo/liveprof-ui .

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

أرسل إلينا تعليقات وأسئلة حول الاستخدام في Telegram والبق وطلبات السحب - مباشرةً إلى GitHub . نحن نرحب بالتعليقات والاقتراحات!

شكر خاص لجريجوري على الفكرة والتنفيذ الأول.

Source: https://habr.com/ru/post/ar436364/


All Articles