FPM folosește sintaxa php.ini pentru fișierul său de configurare - php-fpm.conf și fișierele de configurare a grupului.

Lista directivelor globale php-fpm.conf

pid şir

Calea către fișierul PID. Valoare implicită: niciuna.

Jurnal_eroare şir

Calea către fișierul jurnal de erori. Valoare implicită: #INSTALL_PREFIX#/log/php-fpm.log. Dacă este setat la „syslog”, jurnalul este trimis la syslogd în loc să fie scris într-un fișier local.

Log_level şir

Nivel de jurnal de erori. Valori posibile: alertă, eroare, avertizare, notificare, depanare. Valoare implicită: notificare.

Log_limit întreg

Limită de jurnal pentru liniile înregistrate, care permite înregistrarea mesajelor mai lungi de 1024 de caractere fără împachetare. Valoare implicită: 1024. Disponibil începând cu PHP 7.3.0.

Log_buffering boolean

Înregistrare experimentală fără tamponare suplimentară. Valoare implicită: da. Disponibil începând cu PHP 7.3.0.

Syslog.facilitate şir

folosit pentru a specifica ce tip de program înregistrează mesajul. Valoare implicită: daemon.

Syslog.ident şir

Pregătit pentru fiecare mesaj. Dacă aveți mai multe instanțe FPM care rulează pe același server, puteți modifica valoarea implicită care trebuie să se potrivească nevoilor comune. Valoarea implicită: php-fpm.

Prag_de_repornire de urgență int

Dacă acest număr de procese copil iese cu SIGSEGV sau SIGBUS în intervalul de timp stabilit de emergency_restart_interval, apoi FPM va reporni. O valoare de 0 înseamnă „Oprit”. Valoare implicită: 0 (Oprit).

Emergency_restart_interval amestecat

Intervalul de timp folosit de emergency_restart_interval pentru a determina când va fi inițiată o repornire grațioasă. Acest lucru poate fi util pentru a evita corupțiile accidentale în memoria partajată a unui accelerator. Unități disponibile: s(secunde), m(minute), h(al nostru) sau d(ays). Unitate implicită: secunde. Valoare implicită: 0 (Oprit).

Process_control_timeout amestecat

Limită de timp pentru ca procesele copil să aștepte o reacție la semnalele de la master. Unități disponibile: s(secunde), m(minute), h(al nostru) sau d(ays) Unitate implicită: secunde. Valoare implicită: 0.

Proces.max int

Numărul maxim de procese pe care FPM le va bifurca. Acesta a fost proiectat pentru a controla numărul global de procese atunci când se utilizează PM dinamic într-o mulțime de pool-uri. Folosiți-l cu precauție. Valoare implicită: 0.

Proces.prioritate int

Specificați prioritatea nice(2) de aplicat procesului principal (doar dacă este setată). Valoarea poate varia de la -19 (prioritate cea mai mare) la 20 (prioritate inferioară). Valoare implicită: nesetat.

Daemonize boolean

Trimiteți FPM în fundal. Setați la „nu” pentru a menține FPM în prim-plan pentru depanare. Valoare implicită: da.

Rlimit_files int

Setați descriptorul de fișier deschis rlimit pentru procesul principal. Valoare implicită: Setați descriptorul de fișier deschis rlimit pentru procesul principal.

Rlimit_core int

Setați dimensiunea maximă a miezului rlimit pentru procesul principal. Valoare implicită: 0.

Evenimente.mecanism şir

Specificați mecanismul de eveniment pe care îl va folosi FPM. Sunt disponibile următoarele: select, pool, epoll, kqueue (*BSD), port (Solaris). Valoare implicită: nesetat (detecție automată).

Systemd_interval int

Când FPM este construit cu integrarea systemd, specificați intervalul, în secunde, dintre notificarea raportului de sănătate către systemd. Setați la 0 pentru a dezactiva. Valoare implicită: 10.

Lista directivelor pool-ului

Cu FPM puteți rula mai multe grupuri de procese cu setări diferite. Acestea sunt setări care pot fi modificate pentru fiecare grup.

Asculta şir

Adresa la care să acceptați solicitările FastCGI. Sintaxele valide sunt: ​​„ip.add.re.ss:port”, „port”, „/path/to/unix/socket”. Această opțiune este obligatorie pentru fiecare piscină.

Ascultă.întârziere int

Setați listen(2) backlog. O valoare de „-1” înseamnă nelimitat. Valoare implicită: -1.

Ascultați.clienți_permisi şir

Lista adreselor IPv4 ale clienților FastCGI cărora li se permite să se conecteze. Echivalent cu variabila de mediu FCGI_WEB_SERVER_ADDRS din PHP FastCGI original (5.2.2+). Are sens doar cu o priză de ascultare tcp. Fiecare adresă trebuie despărțită prin virgulă. Dacă această valoare este lăsată necompletată, conexiunile vor fi acceptate de la orice adresă IP. Valoare implicită: oricare. Adresele IPv6 sunt permise începând cu PHP 5.5.20 și 5.6.4.

Ascultă.proprietar şir

Setați permisiunile pentru socket Unix, dacă este folosit unul. În Linux, permisiunile de citire/scriere trebuie setate pentru a permite conexiuni de la un server web. Multe sisteme derivate din BSD permit conexiuni indiferent de permisiuni. Valori implicite: utilizatorul și grupul sunt setate ca utilizator care rulează, modul este setat la 0660.

Ascultă.grup şir

Vedea ascultă.proprietar.

Ascultă.modul şir

Vedea ascultă.proprietar.

Ascultă.acl_users şir

Când listele de control al accesului POSIX sunt acceptate, le puteți seta folosind această opțiune. Când este setat ascultă.proprietarși asculta.grup sunt ignorate. Valoarea este o listă de nume de utilizator, separată prin virgulă. Din PHP 5.6.5.

Ascultă.acl_groups şir

Vedea ascultă.acl_users. Valoarea este o listă de nume de grup, separată prin virgulă. Din PHP 5.6.5.

Utilizator şir

Utilizator Unix al proceselor FPM. Această opțiune este obligatorie.

grup şir

Grupul Unix de procese FPM. Dacă nu este setat, este utilizat grupul de utilizator implicit.

P.m şir

Alegeți modul în care managerul de proces va controla numărul de procese copii. Valori posibile: static, la cerere, dinamic. Această opțiune este obligatorie.

static- numărul de procese copil este fix ( pm.max_copii).

la cerere- procesele apar la cerere (când sunt solicitate, spre deosebire de dinamic, unde pm.start_servers sunt pornite când serviciul este pornit.

dinamic- numărul de procese copil este setat dinamic pe baza următoarelor directive: pm.max_copii, pm.start_servers, pm.min_spare_servers, pm.max_spare_servers.

Pm.max_copii int

Numărul de procese copil care urmează să fie create când p.m este setat sa staticși numărul maxim de procese copil care urmează să fie create când p.m este setat sa dinamic. Această opțiune este obligatorie.

Această opțiune stabilește limita numărului de solicitări simultane care vor fi servite. Echivalent cu directiva ApacheMaxClients cu mpm_prefork și cu variabila de mediu PHP_FCGI_CHILDREN din PHP FastCGI original.

Pm.start_servers int

Numărul de procese copil create la pornire. Folosit numai când p.m este setat sa dinamic. Valoare implicită: min_spare_servers + (max_spare_servers - min_spare_servers) / 2.

Pm.min_servere_de rezervă int

Numărul minim dorit de procese de server inactiv. Folosit numai când p.m este setat sa dinamic

Pm.max_spare_servers int

Numărul maxim dorit de procese de server inactiv. Folosit numai când p.m este setat sa dinamic. De asemenea, obligatoriu în acest caz.

Pm.process_idle_timeout amestecat

Numărul de secunde după care un proces inactiv va fi oprit. Folosit numai când p.m este setat sa la cerere. Unități disponibile: s(secunde) (implicit), m(inute), h(al nostru) sau d(ays). Valoare implicită: 10s.

Pm.max_requests int

Numărul de solicitări pe care trebuie să le execute fiecare proces copil înainte de reapariție. Acest lucru poate fi util pentru a rezolva scurgerile de memorie din bibliotecile terță parte. Pentru procesarea cererilor fără sfârșit, specificați „0”. Echivalent cu PHP_FCGI_MAX_REQUESTS . Valoare implicită: 0.

Pm.status_path şir

URI pentru a vizualiza pagina de stare FPM. Dacă această valoare nu este setată, niciun URI nu va fi recunoscut ca pagină de stare. Valoare implicită: niciuna.

Ping.cale şir

URI-ul ping pentru a apela pagina de monitorizare a FPM. Dacă această valoare nu este setată, niciun URI nu va fi recunoscut ca pagină ping. Acest lucru ar putea fi folosit pentru a testa din exterior că FPM este viu și răspunde. Vă rugăm să rețineți că valoarea trebuie să înceapă cu o bară oblică (/).

Ping.răspuns şir

Această directivă poate fi utilizată pentru a personaliza răspunsul la o solicitare ping. Răspunsul este formatat ca text/plat cu un cod de răspuns de 200. Valoare implicită: pong.

Proces.prioritate int

Specificați prioritatea nice(2) de aplicat procesului de lucru (doar dacă este setată). Valoarea poate varia de la -19 (prioritate cea mai mare) la 20 (prioritate inferioară). Valoare implicită: nesetat.

Proces.dumpable boolean

Setați indicatorul de descărcare a procesului (PR_SET_DUMPABLE prctl) chiar dacă utilizatorul procesului sau grupul este diferit de utilizatorul procesului principal. Permite crearea unui dump de bază de proces și urmărirea procesului pentru utilizatorul pool-ului. Valoare implicită: nr. Din PHP 7.0.29, 7.1.17 și 7.2.5.

Prefix şir

Specificați prefixul pentru evaluarea căii

Request_terminate_timeout amestecat

Timeout pentru deservirea unei singure cereri după care procesul de lucru va fi oprit. Această opțiune ar trebui utilizată atunci când opțiunea ini „max_execution_time” nu oprește execuția scriptului dintr-un motiv oarecare. O valoare de „0” înseamnă „Oprit”. Unități disponibile: s(secunde) (implicit), m(inute), h(al nostru) sau d(ays). Valoare implicită: 0.

request_slowlog_timeout amestecat

Timpul expirat pentru servirea unei singure solicitări, după care un backtrace PHP va fi descărcat în fișierul „slowlog”. O valoare de „0” înseamnă „Oprit”. Unități disponibile: s(secunde)(implicit), m(inute), h(al nostru) sau d(ays). Valoare implicită: 0.

Slowlog şir

Fișierul jurnal pentru cereri lente. Valoare implicită: #INSTALL_PREFIX#/log/php-fpm.log.slow.

Rlimit_files int

Setați descriptorul de fișier deschis rlimit pentru procesele copil din acest pool. Valoare implicită: valoare definită de sistem.

Rlimit_core int

Setați dimensiunea maximă a nucleului rlimit pentru procesele copil din acest pool. Valori posibile: „nelimitat” sau un număr întreg mai mare sau egal cu 0. Valoare implicită: valoare definită de sistem.

Chroot şir

Chroot la acest director la început. Această valoare trebuie definită ca o cale absolută. Când această valoare nu este setată, chroot nu este utilizat.

Chdir şir

Chdir în acest director la început. Această valoare trebuie să fie o cale absolută. Valoarea implicită: directorul curent sau / atunci când este vorba despre chroot.

Catch_workers_output boolean

Redirecționează lucrătorul stdout și stderr în jurnalul principal de erori. Dacă nu sunt setate, stdout și stderr vor fi redirecționate către /dev/null conform specificațiilor FastCGI. Valoare implicită: nr.

Decorate_workers_output boolean

Activați decorarea de ieșire pentru ieșirea lucrătorilor când catch_workers_output este activat. Valoare implicită: da. Disponibil începând cu PHP 7.3.0.

Clear_env boolean

Mediu clar în lucrătorii FPM. Împiedică variabilele de mediu arbitrare să ajungă la procesele de lucru FPM prin ștergerea mediului din lucrători înainte ca valorile de mediu specificate în această configurație de pool să fie adăugate. Din PHP 5.4.27, 5.5.11 și 5.6.0. Valoare implicită: Da.

Security.limit_extensions şir

Limitează extensiile scriptului principal pe care FPM le va permite analizarea. Acest lucru poate preveni greșelile de configurare pe partea serverului web. Ar trebui să limitați FPM doar la extensiile .php pentru a preveni utilizatorii rău intenționați să folosească alte extensii pentru a executa codul php. Valoare implicită: .php .phar

Acces.log şir

Fișierul jurnal de acces. Valoare implicită: nesetat

Acces.format şir

Formatul jurnalului de acces. Valoare implicită: „%R - %u %t \"%m %r\" %s"

Este posibil să treceți variabile de mediu suplimentare și să actualizați setările PHP ale unui anumit pool. Pentru a face acest lucru, trebuie să adăugați următoarele opțiuni la fișierul de configurare a pool-ului.

Exemplul #1 Transmiterea variabilelor de mediu și a setărilor PHP la un pool

env = $HOSTNAME env = /usr/local/bin:/usr/bin:/bin env = /tmp env = /tmp env = /tmp php_admin_value = /usr/sbin/sendmail -t -i -f [email protected] php_flag = dezactivat php_admin_value = /var/log/fpm-php.www.log php_admin_flag = activat php_admin_value = 32M

Setările PHP trecute cu php_value sau php_flag vor suprascrie valoarea lor anterioară. Vă rugăm să rețineți că definirea disable_functions sau disable_classes nu va suprascrie valorile php.ini definite anterior, ci va adăuga noua valoare.

Setări definite cu php_admin_valueși php_admin_flag nu poate fi anulat cu ini_set().

Începând cu 5.3.3, setările PHP pot fi setate și pe serverul web.

Exemplul #2 setați setările PHP în nginx.conf

setați $php_value "pcre.backtrack_limit=424242"; set $php_value "$php_value \n pcre.recursion_limit=99999"; fastcgi_param PHP_VALUE $php_value; fastcgi_param PHP_ADMIN_VALUE "open_basedir=/var/www/htdocs";!}

Prudență

Deoarece aceste setări sunt transmise la php-fpm ca antete fastcgi, php-fpm nu ar trebui să fie legat de o adresă accesibilă la nivel mondial. În caz contrar, oricine ar putea modifica opțiunile de configurare PHP. Vezi si

O rachetă Soyuz livrată cu trenul la rampa de lansare. Fotografie din domeniul public NASA.

Virtuțile PHP

PHP are câteva caracteristici foarte profunde și cu siguranță adevărate.

Primul, stat. Fiecare cerere web începe cu o tablă complet goală. Spațiul de nume și variabilele globale sunt neinițializate, cu excepția unor variabile, funcții și clase globale standard care oferă funcționalitate primitivă și suport de viață. Pornind fiecare cerere dintr-o stare cunoscută, obținem un fel de izolare de posibile erori; Dacă cererea t întâmpină o problemă de software și eșuează, eroarea nu are niciun efect asupra execuției cererii ulterioare t+1. În realitate, desigur, starea aplicației se află în alte locuri în afară de heap-ul programului și este foarte posibil să se corupte complet baza de date, memcache-ul sau sistemul de fișiere. Dar PHP împărtășește această slăbiciune cu fiecare cadru imaginabil care permite persistența cu stare. În același timp, partajarea grămezilor de software între solicitări reduce costul majorității erorilor software.

Al doilea, paralelism. O cerere individuală rulează într-un fir PHP. La prima vedere, aceasta pare o restricție stupidă. Dar, deoarece aplicația noastră rulează în contextul unui server web, avem o sursă naturală de concurență: cererile web. Prin simpla trimitere a cererilor asincrone către noi înșine, putem realiza cu ușurință paralelismul cu stări izolate și apeluri de copiere-restaurare. În practică, aceasta este mai sigură și mai tolerantă la erori decât abordarea de blocare și stare partajată utilizată în alte limbaje de uz general.

În concluzie, faptul că programele PHP funcționează la nivel de solicitare înseamnă că fluxul de lucru al programatorului este rapid și eficient, și rămâne rapid după modificarea aplicației. O mulțime de limbaje de productivitate pretind că fac acest lucru, dar dacă nu își șterg starea la fiecare solicitare și firul evenimentului principal împărtășește starea la nivel de program între cereri, aproape întotdeauna durează ceva timp pentru a rula. Pentru un server de aplicații Python tipic, o buclă tipică de depanare ar arăta ceva de genul „gândește, editează, repornește serverul, trimite niște solicitări de testare.” Chiar dacă „repornirea serverului” durează doar câteva secunde din numărul total de ore, durează o mare parte din 15-30 de secunde din creierul nostru uman despre nevoia de a păstra cea mai inutilă parte a stării actuale în capul nostru.

Susțin că stilul de dezvoltare PHP „gândește, editează, reîncărcă” îi face pe dezvoltatori mai productivi.În ciclurile lungi și complexe de dezvoltare a proiectelor, acest lucru oferă câștiguri și mai mari.

Cazul împotriva PHP

Dacă toate acestea sunt adevărate, de ce este el atât de urât? Când lăsați deoparte toată hiperbola colorată, principalele plângeri cu privire la un cluster PHP se rezumă la următoarele probleme:


Ca să nu sune ca un apolog PHP nereflexiv: toate acestea sunt probleme serioase care fac mai probabil să introducă defecte. Sunt erori neforțate. Nu există un compromis inerent între părțile bune ale PHP și aceste probleme. Ar trebui să fie posibil să se creeze PHP care să rezolve aceste deficiențe, păstrând în același timp toate aspectele bune.

HHVM și Hack

Acest succesor al sistemului PHP se numește Hack

Hack este ceea ce oamenii numesc un limbaj de programare „sistem de tip incremental” pentru PHP. „Sistem de tip” înseamnă că permite programatorului să facă invarianți verificabili automat cu privire la datele care circulă prin cod: o funcție dată ia un șir sau un număr și returnează o foaie Fribbles, ca în Java sau C++ sau Haskell sau orice alta static. limba tastată, oricare o alegeți. „Gradual” înseamnă că unele părți ale bazei de cod pot fi tastate static, în timp ce alte părți pot fi încă în PHP dezordonat, dinamic. Abilitatea de a combina aceste abordări permite migrarea în timp a bazelor de cod mari.

În loc să vărsați o tonă de cerneală aici descriind sistemul de tip Hack și cum funcționează, doar jucați-vă cu el. Voi fi aici când te întorci.

Este un sistem îngrijit și este destul de ambițios în ceea ce vă permite să exprimați. Și a avea capacitatea de a migra treptat un proiect la Hack atunci când acesta crește mai mult decât te așteptai inițial este un beneficiu unic al ecosistemului PHP. Verificările tip hack păstrează un flux de lucru în stil „gândiți, editați, reîncărcați pagina”, deoarece rulează în fundal, actualizând treptat modelul de bază de cod atunci când vede modificări ale sistemului de fișiere. Proiectul Hack oferă integrări cu toate editorii și IDE-urile populare, astfel încât să puteți vedea feedback-ul despre erorile de tip de îndată ce terminați de tastat, la fel ca în demonstrația web.

Să ne uităm la totalitatea riscurilor reale pe care PHP le creează în lumina Hack:


Hack oferă o oportunitate pe care alți membri populari ai familiei MPDPL nu o au: capacitatea de a introduce un sistem tip după dezvoltarea principală și doar parțial, în acele părți ale sistemului în care valoarea depășește costul.

HHVM

Hack a fost dezvoltat inițial ca parte a HipHop Virtual Machine, sau HHVM, un mediu virtual open-source pentru PHP. HHVM oferă o altă opțiune importantă pentru un proiect de succes: capacitatea de a vă lansa site-ul mai rapid și mai economic. Facebook

Să aruncăm o privire rapidă la cum să configurați mai bine PHP-FPM pentru un proces de transfer mare, latență scăzută și o utilizare mai stabilă a CPU și a memoriei. Majoritatea setărilor PHP-FPM implicite au o linie cu PM (manager de proces) setată la dinamic, precum și recomandări pentru utilizarea la cerere în cazul în care întâmpinați probleme de disponibilitate a memoriei. Cu toate acestea, să aruncăm o privire la documentația de pe php.net și să comparăm ambele opțiuni de control și, de asemenea, să comparăm cu setarea mea preferată pentru trafic ridicat... pm = static:

pm = dinamic- numărul de procese copil este setat dinamic, pe baza următoarelor directive: pm.max_children, pm.start_servers, pm.min_spare_servers, pm.max_spare_servers.

pm = la cerere- procesele apar la cerere (dacă este necesar, spre deosebire de opțiunea dinamică, unde pm.start_servers sunt lansate la pornirea serviciului).

pm = static- numărul de procese copil este fixat de directiva pm.max_children.

...puteți vedea lista completă a directivelor php-fpm.conf pentru mai multe informații.

Managerul de proces al PHP-FPM este similar cu CPUFreq Governor

Acest lucru poate părea puțin în afara subiectului, dar sper să îl relaționez cu optimizarea noastră PHP-FPM. Da, cu toții am întâmpinat probleme cu performanța procesorului la un moment dat, fie că este vorba despre un laptop, o mașină virtuală sau un server dedicat. Vă amintiți scalarea frecvenței CPU? (CPUFreq guvernator) Aceste opțiuni, disponibile pe *nix și Windows, pot îmbunătăți performanța și capacitatea de răspuns a sistemului prin schimbarea setării guvernatorului CPU de la ondemand la performanță. Acum să comparăm descrierile și să căutăm asemănări:

guvernator=la cerere- Crește/descrește dinamic frecvența tacului procesorului în funcție de încărcarea sistemului. Emite până la frecvența maximă și apoi scade pe măsură ce timpul de inactivitate crește.

Guvernator = conservator- Similar cu la cerere, dar mai economic (se preferă viteze mai mici de ceas). Frecvența crește mai ușor.

Guvernator = performanta- Menține procesorul(ele) la viteza maximă de ceas.

...pentru mai multe informații, consultați lista completă a setărilor regulatorului CPUFreq.

Observați asemănările? Am vrut să folosesc mai întâi această comparație pentru a descrie mai clar și mai bine recomandarea de utilizat pm static pentru PHP-FPM ca prima alegere.

Setări performanţă Reglatorul CPU este o creștere a performanței destul de sigură, deoarece depinde aproape în totalitate de limita procesorului serverului tău. Dar există câteva efecte secundare (în timp ce îți menții ceasul procesorului la 100% tot timpul) - cum ar fi căldura, durata de viață a bateriei (laptop) și altele. Cu toate acestea, aceasta este cu adevărat cea mai rapidă setare pentru procesorul dvs.

Folosind pm=static pentru performanță maximă a serverului

Setarea pm=static în PHP-FPM depinde foarte mult de cantitatea de memorie liberă pe server. Practic, dacă suferiți de o lipsă de memorie a serverului, atunci pm la cerere sau dinamic pot fi opțiuni mai bune. Pe de altă parte, dacă aveți suficientă memorie liberă, puteți evita cea mai mare parte a sarcinii managerului de proces prin setare pm static până la capacitatea maximă a serverului. Cu alte cuvinte, atunci când faceți calculele, pm.static trebuie să fie setat la numărul maxim de procese PHP-FPM care pot rula fără a crea probleme de memorie sau cache; cu toate acestea, nu atât de mare încât să supraîncărcați procesorul (procesoarele) și să aveți o grămadă de operațiuni PHP-FPM în așteptare.

În captura de ecran de mai sus, acest server are set pm = static și pm.max_children = 100, care utilizează maxim aproximativ 10 GB din cei 32 GB instalați. Vă rugăm să rețineți coloanele evidențiate care vorbesc de la sine. La momentul acestei capturi de ecran erau aproximativ 200 de utilizatori activi (în ultimele 60 de secunde). La acest nivel de utilizatori, aproximativ 70% din procesele copil ale PHP-FPM sunt încă inactive. Aceasta înseamnă că PHP-FPM este configurat să utilizeze întotdeauna capacitatea maximă a resurselor serverului dvs., indiferent de traficul curent. Procesele care sunt inactive rămân „online” așteaptă ca o explozie de trafic să răspundă instantaneu, în loc să aștepte P.M.în timp ce creează procese copil și apoi le va ucide după expirarea pm.process_idle_timeout. În setările mele, pm.max_requests este setat extrem de ridicat, deoarece acesta este un server de producție care nu ar trebui să aibă pierderi de memorie în PHP. Puteți utiliza pm.max_requests = 0 în modul static dacă aveți încredere de 110% în scripturile PHP actuale și viitoare. Cu toate acestea, se recomandă să rulați din nou scripturile din când în când. Setați numărul de solicitări înainte de repornire la cea mai mare valoare pentru a evita supraîncărcarea PM. De exemplu, la un minim pm.max_requests = 1000... pe baza numărului dvs. de pm.max_children și a numărului de solicitări pe secundă.

Captura de ecran folosește Linux top. Nu toate procesele sunt afișate aici, ci doar partea care se potrivește în fereastra terminalului. În cazul nostru, sortat după %CPU (consumul procesorului). Pentru a vedea toate cele 100 de procese PHP-FPM, puteți folosi ceva de genul acesta:

Sus -bn1 | grep php-fpm

Când să utilizați pm la cerere și dinamic

Folosind modul dinamic, este posibil să întâmpinați erori precum aceasta:

AVERTISMENT: pare ocupat (poate fi necesar să măriți pm.start_servers sau pm.min/max_spare_servers), generând 32 de copii, sunt 4 inactiv și 59 de copii în total

Puteți încerca să creșteți/modificați setările și să vedeți în continuare aceeași eroare. O situație similară este descrisă în această întrebare pe Serverfault. În acest caz, pm.min a fost prea scăzut și, deoarece traficul fluctuează foarte mult, modul dinamic este destul de dificil de configurat corect. Sfat general: utilizați la cerere , după cum se recomandă în aceeași întrebare. Cu toate acestea, ceea ce este și mai rău este că la cerere va opri procesele inactive până la 0 atunci când există puțin trafic, apoi veți primi la fel de multă suprasarcină cât traficul crește. Cu excepția cazului în care, desigur, setați timeout-ul extrem de mare. În acest caz, trebuie doar să utilizați pm = static + high pm.max_requests .

În ciuda acestui fapt, modul dinamic și mai ales la cerere vă poate salva atunci când aveți mai multe pool-uri PHP-FPM. De exemplu, atunci când găzduiți mai multe conturi cPanel sau mai multe site-uri în grupuri diferite. Am un server cu, de exemplu, peste 100 de conturi cPanel și peste 200 de domenii și ar fi imposibil ca modul static sau chiar dinamic să mențină o performanță bună. Și numai modul la cerere face acest lucru bine, deoarece mai mult de două treimi din site-uri web au puțin trafic, iar cu la cerere acest lucru înseamnă că toți „copiii” vor fi finalizați, economisind tone de memorie de server! Din fericire, dezvoltatorii cPanel și-au dat seama de acest lucru și acum implicit la la cerere. Anterior de la dinamic modul implicit, utilizarea PHP-FPM pe servere partajate nu era o opțiune. Mulți au folosit suPHP, deoarece modul dinamic consuma memorie chiar și atunci când pool-urile PHP-FPM erau inactive. Probabil, dacă aveți trafic bun, nu veți fi găzduit pe un server cu un număr mare de Pool-uri PHP-FPM (gazduire partajată).

Concluzie

Când vine vorba de PHP-FPM, odată ce începeți să obțineți trafic serios, modurile la cerere și dinamice vă pot limita debitul din cauza supraîncărcării inerente. Cercetează-ți sistemul și setează numărul de procese la cel mai mare pe care îl poate gestiona serverul tău. Începeți cu pm.max_children setat pe baza utilizării maxime a modurilor dinamice sau la cerere, apoi creșteți până la punctul în care memoria și procesorul rămân neconstrânse. Veți observa că cu pm = static , deoarece păstrați totul în memorie, vârfurile de trafic vor avea un impact mai mic asupra creșterilor CPU în timp, iar mediile de încărcare și încărcare vor deveni mai fluide. Dimensiunea medie a procesului dvs. PHP-FPM va depinde de serverul web specific care necesită configurare manuală, motiv pentru care modurile automate sunt dinamicȘi la cerere- sunt recomandări mai populare. Sper că acesta a fost un articol util.

În articolele anterioare am evaluat performanța PHP pe diferite runtime, adăugând resurse de server (CPU și RAM) și comparând Symfony Proxy și Varnish - folosind eZ Platform - un CMS construit pe Symfony Framework.

Acum să încercăm o metodă neconvențională de executare a aplicațiilor PHP, PHP-PM.

PHP a devenit popular parțial datorită faptului că este foarte ușor și sigur de rulat. La fiecare solicitare, PHP începe de la zero, pornește aplicația, trimite răspunsul și moare.

Dezvoltatorii PHP nu trebuie să-și facă griji cu privire la complexitatea unei aplicații de lungă durată cu pierderi de memorie, dar repetarea continuă a acelorași sarcini de bază are un efect asupra performanței. Opcaching-ul ajută la îmbunătățirea performanței, dar mai este mult de lucru. pentru nimic".

În urmă cu aproape doi ani, în februarie 2014, a fost introdusă o modalitate alternativă de a rula PHP: Bring High Performance Into Your PHP App (cu ReactPHP) . După ce a provocat mai întâi unele valuri în comunitatea PHP, a dispărut în fundal.

Dar a condus direct la PHP-PM și probabil a influențat crearea PHPFastCGI. Ambele rulează PHP ca un proces continuu care răspunde solicitărilor, făcând posibilă eliminarea bootstrapping-ului de rutină din ecuație.

Acest lucru aduce o performanță crescută, dar face aplicația mai vulnerabilă la greșelile dezvoltatorului și scurgerile de memorie din cauza ciclului de viață mai lung. Acesta este motivul pentru care metoda este încă considerată experimentală, dar considerată de unii ca fiind viitorul executării PHP.

PHP-PM acceptă aplicațiile Symfony Framework în mod implicit și eZ Platform, așa cum a funcționat așa cum era de așteptat, imediat din cutie. Deci, merită o rundă de teste pentru a vedea cum rezistă într-o aplicație din lumea reală.

PHP-PM vs. Performanță PHP-FPM

În conformitate cu testele anterioare, am rulat cereri împotriva instalării eZ Platform Demo. Configurarea tradițională PHP-FPM rula pe PHP 7.0.1. PHP-PM a fost în spatele lui Nginx ca echilibrator de încărcare și au fost testate atât HHVM 3.11, cât și PHP 7.0.1.

Numărul de procese pentru PHP-PM a fost setat la dublu față de numărul de nuclee CPU, PHP-FPM a avut o limită max_child de 10 - Încercați versiunea de încercare gratuită pentru VPS de înaltă performanță pe UpCloud . Concurența solicitărilor a fost setată la 10. Testele au fost efectuate împotriva apelurilor Front Page și API-ul REST, fără Symfony Proxy sau altă memorie cache de nivel înalt. Testele au fost repetate de trei ori și sunt raportate rezultate medii.

Prima pagină fără Symfony Proxy

Pentru redarea întregii pagini, PHP-PM prezintă un avantaj semnificativ față de configurarea tradițională PHP-FPM. PHP-FPM rămâne în același stagiu cu PHP-PM. HHVM este în mod constant mai performant decât omologul PHP 7.


API fără Symfony Proxy

Pentru apelurile API, rulările PHP-PM produc rezultate semnificativ mai mari decât configurarea PHP-FPM, ceea ce indică faptul că un procent mai mare de timp în acestea este petrecut la bootsrapping în timp ce procesarea este minimă. HHVM începe de sus și după o egalitate la 2 procesoare, PHP 7 oferă randamente mai mari cu setările cu 4 și 8 procesoare.

Comparând PHP-FPM, PHP-PM, Symfony Proxy și Varnish

Pentru a pune numerele într-o perspectivă mai mare cu rezultatele stocate în cache, acestea sunt comparate cu rezultatele pentru rezultatele Symfony Proxied (rulat cu PHP-FPM) și Varnish.


Prima pagină completă

Pentru încărcările de pagină completă, atât Symfony PHP Reverse Proxy, cât și Varnish elimină orice încărcare a paginii generate dinamic. Cu o strategie bună de stocare în cache și îmbinarea fragmentelor cu ESI la nivel de proxy și un backend PHP-FPM va produce probabil cele mai bune rezultate din lumea reală.


Apel API REST

Pentru apelurile API REST cu procesare limitată PHP-PM cu PHP 7 inchi mai aproape de performanța Symfony Proxy. În timp ce proxy-ul PHP este încă de două ori mai rapid, merită să luați în considerare faptul că pentru cererile greu de păstrat în cache și de curățare, un backend dinamic suficient de rapid ar putea fi opțiunea practică.

Concluzii

Rularea proceselor PHP de lungă durată rămâne o curiozitate, dar rezultatele oferă o promisiune de performanță îmbunătățită semnificativ atunci când timpul petrecut pentru bootstrap al aplicației este relativ lung în comparație cu durata totală a procesării.

Un exemplu este un demon care rulează continuu în lumea actuală la modă a apelurilor minuscule API. În culise, acestea ar putea deveni o cascadă peste un lanț lung, de ex. un serviciu apelează la un API REST care apelează un API REST care apelează un API REST care apelează un API REST care apelează un API REST...

Din păcate, PHP-PM nu este încă o soluție practică pentru rularea serviciilor de producție, deoarece atât PHP 7, cât și HHVM ajung să se blocheze din când în când. Venind dintr-un sentiment pur, HHVM pare să fie un pic mai stabil din perechea cu PHP-PM.

După ce am scotocit prin schițele mele, am găsit un subiect destul de interesant - configurarea unui manager de proces pentru php-fpm și nginx. Voi încerca să ofer cât mai multe informații pe această temă. Vă voi spune cu exemple vizuale ce este mai bine și cum sunt calculați unii parametri importanți în php-fpm.

Deci, ce este „managerul de proces” în php-fpm? Manager de proces în php-fpm este un manager de proces pentru PHP-FPM care creează și utilizează procese PHP pentru a profita la maximum de serverul tău.

Tipuri de manager de proces în php-fpm:

  • dynamic — Are un număr dinamic de pm.max_children (procese copil). Care se modifică și este setat pe baza: pm.max_children, pm.start_servers, pm.min_spare_servers, pm.max_spare_servers.
  • static - Are un număr fix de pm.max_children (procese copil).
  • la cerere - Procesele copil nu sunt pornite de la bun început. Numărul de procese este creat la cerere (pe măsură ce solicitările apar, spre deosebire de PM dynamic, când un număr specificat de procese, egal cu pm.start_servers, sunt lansate la pornirea serviciului.

Aceștia sunt cei 3 principali manageri de proces pentru php-fpm.

Setarea managerului de proces ca dinamic pentru php-fpm pe Unix/Linux

Un manager de proces standard și este bun pentru că are mai mulți master PHP-FPM.

Și așa, ne edităm pool-ul și setăm:

Pm = dinamic

Și așa, acum puteți determina numărul maxim de procese. Există o formulă pentru asta:

Total max procese = (Total Ram - (Used Ram + Buffer)) / (Memorie per proces php)

Să presupunem că serverul are 6 GB de RAM, dar îl puteți vedea cu următorul utilitar:

# cat /proc/meminfo | grep -E „MemTotal” MemTotal: 6291456 kB

Verificăm câtă memorie folosește PHP-FPM folosind următoarea comandă:

# ps -aylC „php-fpm” | grep -Ev „grep” | sortare -n | awk "(suma+=8$; ++n) END (printează "Tot="sum"("n"";printează "Avg="sum"/"n"="sum/n/1024"MB)" Tot= 3126148(46) Avg=3126148/46=66,3669MB

Pentru a lista toate procesele php-fpm, utilizați:

# ps --no-headers -o "rss,cmd" -C php-fpm | sortare -n | awk "(printați $1/1024 " Mb)"

Cel mai gras proces:

# ps --no-headers -o "rss,cmd" -C php-fpm | sortare -n | awk „(printați $1/1024,”Mb”)” | coada -n1

Altă cale:

În prima filă rulăm:

#în timp ce este adevărat; face curl https://site &> /dev/null; somn 1; Terminat

În a doua filă rulăm verificarea:

# ps aux | grep -E "php-fpm"| grep -Ev „grep” | awk "(printați 6 USD/1024, "Mb")"

Din nou, am arătat o listă cu toate procesele. Depinde de tine să decizi ce să faci și să iei valoarea medie sau cel mult maxim. Totul trebuie testat! Cantitatea de memorie ocupată de procese poate fi verificată folosind utilitarul ps_mem:

Apoi se poate calcula numărul maxim de procese (am decis să dau toată RAM la PHP):

(1024*6) / 66 = 93.0909

Vedem că puteți folosi maxim 93 de servere pentru php-fpm:

Pm = pm dinamic.max_children = 93 pm.start_servers = 30 pm.min_spare_servers = 30 pm.max_spare_servers = 45 pm.process_idle_timeout = 10s;

Parametri principali:

  • pm = dinamic - După cum am menționat deja, acesta este un manager de proces. pm = dinamic
  • pm.max_children — Setează numărul maxim de procese copil (procese descendente) care sunt create de PM. pm.max_children= (cantitatea totală de memorie virtuală)/(memorie alocată unui proces php) = 93
  • pm.start_servers - Setează numărul de procese copil care vor fi create de PM când PHP-FMP este pornit. pm.start_servers = ~(pm.max_children/3) = 31
  • pm.min_spare_servers — Setează numărul de procese care ar trebui să rămână inactiv ca „de rezervă”, în așteptarea executării sarcinilor; dacă numărul este mai mic, vor fi create altele noi; pm.min_spare_servers = (setat la 1 nucleu) SAU ~(pm.max_children/3) = 31
  • pm.max_spare_servers - dimpotrivă, numărul maxim de procese care ar trebui să rămână inactive, dacă numărul este mai mare, unii copii vor fi distruși: pm.max_spare_servers = (număr total de nuclee) SAU ~(pm.max_children/2) = 45
  • pm.max_requests – numărul de solicitări pentru un proces după care acesta va fi recreat, util pentru prevenirea scurgerilor de memorie; pm.max_requests = 100000
  • pm.process_idle_timeout — timp în secunde după care procesul inactiv va fi șters. pm.process_idle_timeout = 10s

Rețineți că nu am luat în considerare (Used Ram + Buffer). Acest lucru ar fi necesar dacă serverul ar avea baze de date:

# cat /proc/meminfo | grep -E „(MemTotal|MemFree|Cached)” MemTotal: 6291456 kB MemFree: 1678704 kB În cache: 2205940 kB

Puteți verifica utilizarea tamponului și a memoriei cu următoarea comandă:

# liber -m total folosit gratuit partajat/cache disponibil Mem: 6144 1521 1622 641 3000 3716 Schimbare: 0 0 0

Total procese maxime = (6144 - (1521 + 3000)) / 66 = 24

Reporniți serviciul php-fpm:

# service php-fpm restart

Acum vom folosi htop/top și ab pentru a verifica ce și cum funcționează.

Efectuam testul:

Ab -n 10000 -c 500 http://localhost/index.php

# cd /usr/local/src && wget https://site/wp-content/uploads/scripts/php-fpm/php-fpmpal.sh -q -O - | bash

Oferă instrucțiuni destul de bune:

() (((*)\) (/()\))\))\) (` ((()/()\())(()/((())/((()/() \))())\ /(_))((_)\ /(_)) /(_)) /(_))((_)()\ `) (/(((_) (_) )) _((_)(_)) (_))_|(_)) (_()((_) /(/()(_)) _ | _ \ | || || _ \ ___ | |_ | _ \ | \/ |((_)_\ ((_)_ | | | _/ | __ || _/|___|| __| | _/ | |\/| || "_ \)/ _` || | |_| |_||_||_| |_| |_| |_| |_|| .__/ \__,_||_| ====== ====================================== |_| ========== ================ = AH00558: httpd: Nu s-a putut determina în mod fiabil numele de domeniu complet calificat al serverului, folosind 31.187.70.238. Setați directiva „ServerName” la nivel global pentru a suprima acest mesaj AH00558: httpd: Nu s-a putut determina în mod fiabil numele de domeniu complet calificat al serverului , folosind 31.187.70.238. Setați directiva „ServerName” la nivel global pentru a suprima acest mesaj ===== Listă de pool-uri PHP-FPM ===== - -- nagios --- Fișier de configurare: /etc/php-fpm.d/nagios.conf Lista proceselor: 53028 53029 53030 53031 53032 Număr de procese: 5 Valoarea curentă max_children: 50 Utilizarea totală a memoriei pentru pool în KB: 544440 Medie Utilizarea memoriei per proces în KB: 10888 Utilizare totală potențială a memoriei pentru pool (pe baza procesului mediu) (KB): 544400 Cel mai mare proces din acest pool este (KB): 10888 Utilizare totală potențială a memoriei pentru pool (pe baza procesului cel mai mare) (KB ): 544400 --- www --- Fișier de configurare: /etc/ php-fpm.d/www.conf Lista proceselor: 53033 53034 53035 53036 53037 53038 53039 53040 53041 53041 53042 53034 53034 53047 53048 53049 53050 53051 53052 53053 53054 53055 53056 53057 53058 53059 53060 53061 53062 53083 53119 53434 53491 61608 73379 Număr de procese de utilizare: max. 440 Utilizare medie de memorie per proces în KB: 63762 Utilizare totală potențială a memoriei pentru pool ( pe baza procesului mediu) (KB): 3188100 Cel mai mare proces din acest pool este (KB): 67792 Utilizarea totală potențială a memoriei pentru pool (bazat pe cel mai mare proces) (KB): 3389600 ===== Statistici de utilizare a memoriei serverului === == Memoria serverului totală în KB: 6291456 =Utilizarea totală a memoriei Apache în KB: 0 =Utilizarea totală a memoriei nginx în KB: 55868 =Utilizarea totală a memoriei Varnish în KB: 0 0 =Utilizarea totală a memoriei MySQL în KB: 201324.8 =Total PHP- Utilizarea memoriei FPM în KB: 2349880 Memorie disponibilă pentru a fi atribuită pool-urilor PHP-FPM în KB: 6099670 (memorie liberă totală + utilizarea curentă a memoriei PHP-FPM) Utilizare totală potențială a memoriei PHP-FPM bazată pe cele mai mari procese (KB): 3934000 (64,49%) ...BUN 🙂 Utilizarea totală potențială a memoriei PHP-FPM bazată pe dimensiunea medie a procesului (KB): 3732500 (61,19%) ...BUN 🙂 ===== Recomandări per grup ===== -- nagios -- utilizează în prezent 54440 KB memorie (2. 31% din toată utilizarea memoriei PHP-FPM). Ar trebui să fie permisă utilizarea a aproximativ 140902 KB din toată memoria disponibilă. Dimensiunea medie a procesului este de 10888 KB, așa că înseamnă că max_children ar trebui setat la ~12. În prezent este setat la 50 (acesta poate fi schimbat în /etc/php-fpm.d/nagios.conf). -- www -- folosește în prezent 2295440 KB de memorie (97,68% din toată utilizarea memoriei PHP-FPM). Ar trebui să fie permisă utilizarea a aproximativ 5958157 KB din toată memoria disponibilă. Dimensiunea medie a procesului este de 63762 KB, așa că aceasta înseamnă că max_children ar trebui setat la ~93. În prezent este setat la 50 (acesta poate fi schimbat în /etc/php-fpm.d/www.conf). ===== Alte considerații de luat în considerare ===== Din fișierele jurnal de erori PHP-FPM (/var/log/php-fpm/error.log): - pool www a atins valoarea maximă de copii de 50 pe 2 ocazie(e) Pentru aceste grupuri, vă recomandăm să comparați valoarea recomandată max_children cu aceste informații și să decideți dacă valoarea recomandată ar fi suficient de mare pentru a preveni atingerea maxim_children în viitor. Notă: Nu este ideal să rulați PHP-FPMpal la scurt timp după repornirea PHP-FPM sau a serviciilor dvs. web. Acest lucru se datorează faptului că PHP-FPMpal face recomandări bazate pe dimensiunea medie a procesului pool-ului și, dacă PHP-FPM a fost repornit cu puțin timp în urmă, probabilitatea este mare că nu vor fi fost multe solicitări făcute către site-uri de la repornire și valorile vor fi distorsionate și nu vor afișa o medie normalizată. De asemenea, merită remarcat faptul că, dacă ați repornit recent orice serviciu care consumă în mod normal o cantitate mare de memorie, atunci probabil că doriți să așteptați un timp înainte de a rula PHP-FPMpal (de exemplu, dacă MySQL folosește în mod normal 50% din memorie, dar tocmai ați repornit-o, atunci este posibil să utilizeze doar 10% din memorie chiar acum, astfel că recomandările vor fi foarte distorsionate). =============== ==================================================== =============

Setarea managerului de proces ca static pentru php-fpm pe Unix/Linux

Managerul de proces static nu este aproape niciodată folosit, datorită faptului că există 1 master PHP-FPM.

Deschideți piscina din php-fpm și modificați parametrii:

Pm = pm statice.max_children = 5

Reporniți serviciul php-fpm:

$ sudo service php5-fpm restart

# service php-fpm restart

PS: Utilizați comanda în funcție de tipul de sistem de operare.

Efectuam testul:

# ab -n 1000 -c 10 http://localhost/index.php # ab -n 5000 -c 20 http://localhost/index.php

Mai multe informații despre utilitarul „ab” pot fi găsite în articol:

Deschideți fișierul de configurare pentru pool-ul php-fpm. Îl poți găsi căutând (dacă cineva nu știe unde este).

Să decomentăm linia cu opțiunea „pm.max_requests”:

Pm.max_requests = 500

Reporniți php-fpm din nou și verificați încărcarea:

# ab -n 5000 -c 20 http://localhost/index.php

Puteți vedea că unele procese au murit, apoi unele procese au fost ucise și apoi au fost generate din nou!

Configurarea managerului de proces ca la cerere pentru php-fpm pe Unix/Linux

Cel mai avansat (după părerea mea) manager de proces. Din nume este evident că nu părăsește procese, ci le creează la nevoie.

Un exemplu de piscină arată astfel:

Utilizator = www-data group = www-data listen = /var/run/php5-fpm/linux-notes.og/sock listen.owner = www-data listen.group = www-data listen.mode = 770 chdir = / srv/www/wp-content/linux-notes.og/ pm = ondemand pm.max_children = 5 pm.max_requests = 500

Parametri principali:

  • pm = ondemand - După cum sa menționat deja, acesta este un manager de proces. pm = la cerere
  • pm.max_children — Setați numărul maxim de procese copil. pm.max_children= (cantitatea totală de memorie virtuală)/(memorie alocată unui proces php) = 93
  • pm.process_idle_timeout — Setați timpul în secunde după care procesul inactiv va fi șters. pm.process_idle_timeout = 10s
  • pm.max_requests — Setați numărul de cereri procesate, după care procesele php-fpm vor fi repornite. pm.max_requests = 100000

Dacă aveți nevoie de mai multă performanță, atunci managerul de proces OnDemand nu este pentru dvs. Cu toate acestea, 90% din timp, configurația PHP-FPM în modul OnDemand este mai bună decât statică sau dinamică.