Profiluri neprofitabile php. Profilarea și depanarea aplicațiilor PHP folosind xhprof și FirePHP. Optimizarea codului pe baza datelor de profilare

O extensie pentru PHP numită Xdebug este disponibilă pentru a ajuta la profilarea aplicațiilor PHP, precum și la depanarea în timp de execuție. La rularea profilelor, rezultatul este scris într-un fișier într-un format binar numit „cachegrind”. Pe fiecare platformă sunt disponibile aplicații pentru a analiza aceste fișiere. Nu sunt necesare modificări ale codului aplicației pentru a efectua această profilare.

Pentru a activa profilarea, instalați extensia și ajustați setările php.ini. Unele distribuții Linux vin cu pachete standard (de exemplu, pachetul php-xdebug al Ubuntu). În exemplul nostru vom rula profilul opțional pe baza unui parametru de solicitare. Acest lucru ne permite să păstrăm setările statice și să pornim profiler-ul numai după cum este necesar.

# php.ini settings # Setați la 1 pentru a-l activa pentru fiecare solicitare xdebug.profiler_enable = 0 # Să folosim un parametru GET/POST pentru a porni profilerul xdebug.profiler_enable_trigger = 1 # Valoarea GET/POST pe care o vom transmite ; gol pentru orice valoare xdebug.profiler_enable_trigger_value = "" # Ieșiți fișierele cachegrind în /tmp, astfel încât sistemul nostru să le curețe mai târziu xdebug.profiler_output_dir = "/tmp" xdebug.profiler_output_name = "cachegrind.out.%p"

Apoi utilizați un client web pentru a face o solicitare către adresa URL a aplicației dvs. pe care doriți să o profilați, de ex.

Http://example.com/article/1?XDEBUG_PROFILE=1

Pe măsură ce pagina se procesează, va scrie într-un fișier cu un nume similar cu

/tmp/cachegrind.out.12345

În mod implicit, numărul din numele fișierului este id-ul procesului care l-a scris. Acesta este configurabil cu setarea xdebug.profiler_output_name.

Rețineți că va scrie un fișier pentru fiecare cerere / proces PHP care este executat. Deci, de exemplu, dacă doriți să analizați o postare de formular, va fi scris un profil pentru solicitarea GET pentru a afișa formularul HTML. Parametrul XDEBUG_PROFILE va trebui să fie trecut în cererea POST ulterioară pentru a analiza a doua cerere care procesează formularul. Prin urmare, la profilare, uneori este mai ușor să rulați curl pentru a POST direct un formular.

Analizând ieșirea

Odată scris, memoria cache a profilului poate fi citită de o aplicație precum sau Webgrind. PHPStorm, un IDE PHP popular, poate afișa și aceste date de profilare.

KCachegrind, de exemplu, va afișa informații, inclusiv:

  • Funcții executate
  • Timpul apelului, atât propriu-zis, cât și inclusiv apelurile de funcții ulterioare
  • De câte ori este apelată fiecare funcție
  • Apelați grafice
  • Legături către codul sursă

Ce anume sa cauti

În mod evident, reglarea performanței este foarte specifică cazurilor de utilizare ale fiecărei aplicații. În general, este bine să căutați:

  • Apeluri repetate la aceeași funcție pe care nu v-ați aștepta să o vedeți. Pentru funcțiile care procesează și interogează date, acestea ar putea fi oportunități principale pentru ca aplicația dvs.
  • Funcții de funcționare lentă. Unde își petrece aplicația cea mai mare parte a timpului? cel mai bun profit în reglarea performanței este concentrarea pe acele părți ale aplicației care consumă cel mai mult timp.

Notă: Xdebug, și în special caracteristicile sale de profilare, consumă foarte mult resurse și încetinesc execuția PHP. Este recomandat să nu rulați acestea într-un mediu de server de producție.

Folosind sisteme de profilare, puteți colecta informații despre care funcții din codul PHP consumă mai mult timp CPU și RAM, adică identificați locurile cele mai lente și mai solicitante de memorie dintr-un program PHP.

xhprof

XHProf - profiler PHP dezvoltat de Facebook.

Instalare:

Aptitude install php-pear pecl install xhprof-0.9.4 echo "extension=xhprof.so" > /etc/php5/mods-available/xhprof.ini ln -s /etc/php5/mods-available/xhprof.ini /etc /php5/conf.d/xhprof.ini apachectl restart

Fișierele necesare pentru lucru se află în director /usr/share/php. Cu toate acestea, nu totul, ci numai cu cod PHP. Pentru afișarea normală a rapoartelor, sunt necesare jquery și css. Acestea pot fi obținute din depozitul github:

Clona Git https://github.com/facebook/xhprof.git

După aceasta, adăugați linia la codul de script PHP în locul unde ar trebui să înceapă colectarea datelor:

Xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY);

Parametrii pentru colectarea datelor sunt indicați în paranteze. În acest caz, datele vor fi colectate privind încărcarea procesorului și utilizarea RAM. Este posibilă încă o opțiune XHPROF_FLAGS_NO_BUILTINS atunci când sunt utilizate, datele privind funcțiile încorporate nu sunt colectate.

$xhprof_data = xhprof_disable(); include_once "xhprof_lib/utils/xhprof_lib.php"; include_once "xhprof_lib/utils/xhprof_runs.php"; $xhprof_runs = nou XHProfRuns_Default(); $run_id = $xhprof_runs->save_run($xhprof_data, "xhprof_test"); echo „Raport: http://domain.tld/xhprof_html/index.php?run=$run_id&source=xhprof_test”; ecou „\n”;

În linie $run_id Ghilimelele indică numele profilului, care poate fi setat în mod arbitrar.

Rezultatul procesat arată astfel:

Dacă specificați parametrul XHPROF_FLAGS_NO_BUILTINS, este clar că numărul de apeluri de funcții este redus semnificativ:

Tabelul oferă următoarele informații:

Apeluri- numărul de apeluri de funcții,
Timp de perete- timpul total de funcționare al funcției, inclusiv timpul petrecut în așteptarea unui răspuns din partea resurselor externe,
CPU- cât timp a fost alocat procesării funcțiilor,
MemUse- câtă memorie RAM a fost folosită,
PeakMemUse- consum maxim de memorie.

Modificatorii sunt:

Incl- inclusiv - luând în considerare apelurile către alte funcții din această funcție,
Excl.- exclusiv - excluzând apelurile de funcții.

În plus, deasupra tabelului există informații despre timpul total de procesare, memoria utilizată și numărul de apeluri de funcții.

De asemenea XHProf vă permite să construiți rapoarte diferențiale între două rulări, care sunt indicate prin culori roșie și verde. Cu aceste rapoarte, puteți obține o imagine clară a îmbunătățirilor după fiecare modificare a codului.

Pentru a obține un astfel de raport, trebuie să utilizați un link ca acesta:

http://domain.tld/xhprof_html/index.php?run1=run_id1&run2=run_id2&source=xhprof_test

Unde run_id1Și run_id2- identificatori de lansare.

Daca instalezi Graphviz:

Aptitude instalează graphviz

Există, de asemenea, interfețe web terță parte pentru php profiler xhprof care utilizează baze de date:

xDebug

xDebug- Depanator de cod PHP cu capacitate de profilare, scris de Derick Rethans.

Instalare:

Yum, instalează php5-xdebug

Apoi edităm configurația:

Nano /etc/php5/mods-available/xdebug.ini

adăugându-i liniile:

Xdebug.profiler_enable = 1 xdebug.profiler_aggregate = Pe xdebug.profiler_output_dir = /tmp

Aici activăm profilerul PHP și specificăm directorul în care să stocăm profilurile. Profilurile sunt create cu nume precum cachegrind.out.*

Există un client web webgrind: https://github.com/jokkedk/webgrind. Nu funcționează foarte repede, dar vă permite să vizualizați rapid profile mici. De fapt, acesta este codul PHP care trebuie clonat din github:

Clona Git https://github.com/jokkedk/webgrind.git

va fi creat un director webgrind, pe care trebuie să îl copiați în directorul oricărui site web și să îl accesați din browser. Apoi, pentru a face plotarea în fișierul de configurare să funcționeze în Debian config.php trebuie să corectați calea către fișierul executabil graphviz. Ar trebui să arate așa:

Static $dotExecutable = "/usr/bin/dot";

În plus, puteți regla fusul orar:

Static $defaultTimezone = "Europa/Moscova";

În antet, puteți selecta un profil și puteți bifa caseta pentru a lua în considerare funcțiile încorporate. Tabelul în sine arată funcțiile, numărul de apeluri, timpul de funcționare al funcției în sine și timpul inclusiv așteptarea. Pentru a aprofunda funcțiile, faceți clic pe săgeata triunghiulară. În cazul meu, cu profiluri destul de mari (de la câțiva megaocteți), așteptarea rezultatului a fost inutil de mare. Probabil că este mai bine să folosiți programe locale de vizualizare pentru profiluri destul de mari.

Graficul ar putea arăta astfel:

Rețineți că webgrind nu trebuie utilizat pe serverele de producție, deoarece nu este furnizată nicio autorizare, dar există acces la codul fișierului php. Dacă este necesar, utilizați cel puțin autorizația de bază Apache.

Există și programe pentru analiza profilurilor pentru Linux:

Despre profilare

Datele de profil vă pot ajuta să vă îmbunătățiți aplicația, adică să atingeți anumite obiective, de exemplu, reducerea consumului de memorie, reducerea timpului de generare a paginii și așa mai departe.

Informațiile din profil sunt punctul de plecare pentru optimizare: arată cât timp durează generarea rezultatului, câtă memorie este folosită și câte apeluri de funcții sunt efectuate. Cu date mai detaliate, puteți îmbunătăți aceste valori.

De exemplu, dacă utilizați un cadru, atunci utilizarea unor funcții ale cadrului poate duce la apeluri la mai multe funcții de bază. Dacă citiți unele date de mai multe ori, ar putea merita să stocați rezultatul într-o variabilă.

De asemenea, profilerul vă poate ajuta să înțelegeți unde să utilizați memorarea în cache a codului PHP, de exemplu, folosind APCu sau memcached.

În primul rând, merită să optimizați funcțiile care necesită cel mai mult timp de execuție. Odată ce totul este optimizat și se pare că nu mai este nimic de îmbunătățit, merită să sortați funcțiile după numărul de apeluri și să lucrați la reducerea acestuia. Chiar dacă PHP este rapid, merită să ne gândim dacă funcțiile trebuie apelate atât de des?

Dacă întâmpinați următoarele situații, ar trebui să luați în considerare stocarea în cache:

  • Funcțiile imuabile sunt numite în interiorul unei bucle,
  • Unele conținut sunt generate de două ori,
  • Conținutul care nu se modifică este generat de fiecare dată,
  • Conținutul este generat chiar dacă nu este utilizat.

Nu ar trebui să păstrați totul în cache, deoarece memoria este, de asemenea, o resursă valoroasă. Memorați în cache datele pe care le accesați în mod constant. De asemenea, stocarea în cache nu are sens dacă stocarea în cache risipește mai multe resurse decât economisește.

Pe lângă stocarea în cache în cod, nu uitați de memorarea în cache folosind serverul web (), precum și pe partea clientului. Dacă utilizați anteturile potrivite, multe solicitări pot fi rezolvate înainte ca acestea să ajungă chiar pe server.

FirePHP este o extensie pentru firebug, care, împreună cu clasa sa mică php, vă permite să difuzați date din php, de exemplu, tot felul de var_dump și alte informații de depanare, către consola firebug. Principalul avantaj al acestei extensii este că toate informațiile de depanare sunt difuzate prin anteturi și nu împrăștie paginile și nu rupe în niciun fel logica aplicației.Site oficial: http://firephp.org/.

Ideea principală.

Algoritmul general de profilare este următorul:
  1. La începutul paginii, activăm profilarea folosind xhprof_enable()
  2. La sfârșitul paginii, dezactivați profilarea folosind xhprof_disable() și salvați datele colectate folosind save_run()
  3. Apoi, folosind clasa firephp php, transmitem un link către datele de profilare către partea client
  4. În consola firebug deschidem informațiile de care avem nevoie
  5. ne bucuram :)
De asemenea, aș dori să spun că, desigur, adăugarea manuală a acestor funcții la scripturile dvs. PHP este grozavă. Dar vreau ca aceste informații să fie mereu la îndemână în timpul dezvoltării și să nu ajungă pe serverele de producție. Rezolvăm această problemă după cum urmează:

În proiectele noastre, în aproape toate scripturile, un fișier de lucru cu un încărcător de clasă, funcții de conectare și alte lucruri necesare este conectat la început. Prin urmare, am inclus includerea profilării în acest fișier. Și pentru a putea activa/dezactiva modul de depanare după bunul plac, am adăugat o verificare pentru constanta de configurare, plus că am împachetat aceste verificări în niște meta-etichete care sunt eliminate automat când proiectul este construit. Același lucru este valabil și pentru dezactivarea profilării și scrierea informațiilor în anteturi folosind firephp - aceste sarcini sunt rezolvate de o funcție, care este numită la sfârșitul fiecărui script PHP și este, de asemenea, înfășurată în meta-etichete. Arata cam asa:

// Următoarele constante sunt scrise în fișierul de configurare a aplicației

/** Modul de funcționare al mediului * */
define("APPLICATION_ENV" , "dev" ); // dev - depanare | pro - producție
/** Calea către profiler */
define("XHPROF_ROOT" , __DIR__ . „/ExtProcs/debug/xhprof-0.9.2”);

/***************************************************************************************
* În continuare, în fișierul care este încărcat la începutul fiecărui script, lansăm profilarea
* DEV_START și DEV_END sunt metaetichetele noastre, totul dintre ele este decupat în timpul asamblarii
***************************************************************************************/

//-- DEV_START
//-- în modul de depanare conectăm bibliotecile de depanare

// Încărcați firephp
require_once(__DIR__ . „/includes/ExtProcs/debug/firephp/FirePHP.class.php”);
//-- încărcați profilerul
„/xhprof_lib/utils/xhprof_lib.php”);
require_once(XHPROF_ROOT. „/xhprof_lib/utils/xhprof_runs.php”);
// Inițializați profilarea cu steagurile necesare. Descrierea detaliată a steagurilor
// poate fi găsit la php.net/manual/ru/xhprof.constants.php
xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY);
}
//-- DEV_END

// Ei bine, această funcție este apelată la sfârșitul fiecărui script
// Apelul său este, de asemenea, împachetat în DEV_START și DEV_END

/**
* Creați un link către rezultatul profilării și afișați-l în consolă
*/
funcția dev_boot_Down() (
dacă (APPLICATION_ENV === „dev” ) (
// Inițializați instanța firephp
$firephp = FirePHP::getInstance(true);
// Dezactivează profilarea și salvează datele
$xhprof_data = xhprof_disable();
$xhprof_runs = nou XHProfRuns_Default();
$run_id = $xhprof_runs->save_run($xhprof_data, "xhprof_testing" );
// Creați un link către datele de profilare și scrieți-l în consolă
$link = "http://" . $_SERVER[„HTTP_HOST”] . „/includes/ExtProcs/debug/xhprof-0.9.2/xhprof_html/index.php?run=($run_id)&source=xhprof_testing\n”;
$firephp->info($link, „date de profilare”);
}
}


* Acest cod sursă a fost evidențiat cu Sursa de evidențiere a codului.

Nu voi intra în detalii despre instalarea acestor extensii, deoarece totul este simplu aici. Voi spune doar câteva aspecte ale configurației. xhproof are o singură variabilă de configurare - xhprof.output_dir, care indică folderul în care vor fi salvate datele de profilare. Prin urmare, asigurați-vă că utilizatorul sub care sunt executate scripturile PHP are drepturi de scriere în directorul specificat. Deci, scrie ceva de genul acesta în php.ini-ul tău:


extensie=xhprof.so
xhprof.output_dir="/var/tmp/xhprof"

De asemenea, este o idee bună să instalați ceva precum dot sau Graphviz pentru a desena grafice de apel. Am Graphviz pe MacOS X.

După ce am finalizat procedurile descrise mai sus, am putut să deschidem și să ne uităm la profilarea oricăruia dintre scripturile noastre direct în browser în orice moment.

Instalarea xhprof pentru php:

Sudo apt-get install php5-xhprof

Reporniți Apache:

Reporniți serviciul Sudo apache2

Print phpinfo(); și verificați dacă modulul este conectat sau nu?

Verificăm /etc/php5/apache2/conf.d pentru a vedea dacă acolo apare un link către configurația xhprof.ini.

Dacă nu, atunci creați singur legătura și reporniți Apache.

Sudo ln -s /etc/php5/mods-available/xhprof.ini /etc/php5/apache2/conf.d/20-xhprof.ini sudo service apache2 restart

Verificăm conexiunea xhprof, verificăm dacă 20-xhprof.ini este conectat:

Captura de ecran arată versiunea 0.9.2, deși în timpul instalării a fost afișată versiunea 0.9.4, dar aceasta nu este o piedică pentru noi.

Acum ne putem profila codul.

  1. La începutul paginii, activați profilarea folosind xhprof_enable();
  2. La sfârșitul paginii, dezactivați profilarea folosind xhprof_disable() și salvați datele colectate folosind save_run();
  3. În continuare analizăm.

Funcţie xhprof_enable() ia steaguri drept argumente:

XHPROF_FLAGS_CPU pentru înregistrarea statisticilor procesorului,

XHPROF_FLAGS_MEMORY - pentru memorie,

XHPROF_FLAGS_NO_BUILTINS - pentru a ignora funcțiile încorporate.

Pentru a salva și a informa în continuare, trebuie să instalăm un instrument de analiză a profilului.

Descărcați arhiva cu instrumentul de analiză de pe pagina xhprof:, luați versiunea 0.9.4.

Pe server sau pe computerul local, creați un folder accesibil prin localhost sau un domeniu separat în care dezarhivăm arhiva descărcată:

Acum putem salva profilul.

https://xn--d1acnqm.xn--j1amh/altadmin/posts/edit/188

Codul de urmărire arată cam așa:

// Inițializați profilerul - vom număra atât timpul procesorului, cât și consumul de memorie xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY);
// Cod profilat # Opriți profilerul $xhprof_data = xhprof_disable(); # Salvați raportul și generați un link pentru a-l vizualiza include_once „/var/www/html/xhprof-0.9.4/xhprof_lib/utils/xhprof_lib.php”; include_once „/var/www/html/xhprof-0.9.4/xhprof_lib/utils/xhprof_runs.php”; $xhprof_runs = nou XHProfRuns_Default(); $run_id = $xhprof_runs->save_run($xhprof_data, "xhprof_test"); echo „Raport: http://localhost/xhprof-0.9.4/xhprof_html/index.php?run=$run_id&source=xhprof_test”; ecou „\n”;

/var/www/html/xhprof-0.9.4 - calea către folderul în care am dezarhivat bibliotecile de care avem nevoie.

Raport: http://localhost/xhprof-0.9.4/xhprof_html/index.php?run=57c32f3095d21&source=xhprof_test

Așa arată o analiză de profil. Acest tabel afișează toate apelurile de funcții care sunt profilate.

Putem sorta funcțiile făcând clic pe titlurile tabelului.

Când vedem că o funcție este executată fie de mai multe ori, fie pentru o perioadă foarte lungă de timp, putem face clic pe această funcție și se va deschide un tabel similar, dar cu apeluri interne în interiorul funcției în cauză și a mediului părinte în care a fost apelată funcția.

Indicatori:
Total Inc. Wall Time (timpul petrecut pentru executarea funcțiilor, ținând cont de așteptarea răspunsurilor de la socket-uri, sistemul de fișiere și alte resurse)
Total Inc. CPU (timpul petrecut executând funcții)
Total Inc. MemUse (utilizarea memoriei)
Total Inc. PeakMemUse (utilizare maximă a memoriei)
Numărul de apeluri de funcție

Există și opțiunea de afișare grafică a raportului. Dar pentru a face acest lucru, trebuie să vă asigurați că aveți instalată biblioteca graphviz:

Apt-get install graphviz

Apoi, în profilul dvs., trebuie să faceți clic pentru a afișa și voila:

Acum puteți analiza și îmbunătăți codul.