{"id":35722,"date":"2019-10-31T22:05:58","date_gmt":"2019-10-31T19:05:58","guid":{"rendered":"https:\/\/prohoster.info\/blog\/roadrunner-php-ne-sozdan-chtoby-umirat-ili-golang-speshit-na-pomoshh\/"},"modified":"2019-10-31T22:05:58","modified_gmt":"2019-10-31T19:05:58","slug":"roadrunner-php-ne-sozdan-chtoby-umirat-ili-golang-speshit-na-pomoshh","status":"publish","type":"post","link":"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/roadrunner-php-ne-sozdan-chtoby-umirat-ili-golang-speshit-na-pomoshh","title":{"rendered":"RoadRunner: PHP nu este f\u0103cut pentru a muri, sau Golang gr\u0103be\u0219te \u00een ajutor","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"RoadRunner: PHP nu este f\u0103cut pentru a muri, sau Golang gr\u0103be\u0219te \u00een ajutor\" src=\"\/wp-content\/uploads\/2019\/06\/d2a69318cf25caa8fb49efedb333d7f8.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSalut, Habr! Noi, la Badoo, lucr\u0103m activ <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/company\/badoo\/blog\/430722\/\">pentru a \u00eembun\u0103t\u0103\u021bi performan\u021ba PHP<\/a><\/noindex>, deoarece avem un sistem destul de mare construit pe acest limbaj, iar problema performan\u021bei este o chestiune de economisire a banilor. Cu peste zece ani \u00een urm\u0103, am creat PHP-FPM, care a fost la \u00eenceput un set de patch-uri pentru PHP, dar care mai t\u00e2rziu a fost inclus \u00een livrarea oficial\u0103.<\/p>\n<p>\u00cen ultimii ani, PHP a avansat semnificativ: colectorul de gunoi s-a \u00eembun\u0103t\u0103\u021bit, stabilitatea a crescut \u2014 ast\u0103zi po\u021bi scrie demoni \u0219i scripturi de lung\u0103 durat\u0103 pe PHP f\u0103r\u0103 probleme mari. Acest lucru a permis lui Spiral Scout s\u0103 mearg\u0103 mai departe: RoadRunner, spre deosebire de PHP-FPM, nu cur\u0103\u021b\u0103 memoria \u00eentre cereri, ceea ce ofer\u0103 un c\u00e2\u0219tig suplimentar \u00een performan\u021b\u0103 (de\u0219i acest abordare complic\u0103 procesul de dezvoltare). Acum experiment\u0103m cu acest instrument, dar nu am ob\u021binut rezultate de \u00eemp\u0103rt\u0103\u0219it. Pentru a face a\u0219teptarea mai pl\u0103cut\u0103, <b>public\u0103m traducerea anun\u021bului RoadRunner de la Spiral Scout.<\/b><\/p>\n<p>Abordarea din articol ne este familiar\u0103: atunci c\u00e2nd ne rezolv\u0103m sarcinile, folosim adesea combina\u021bia PHP \u0219i Go, ob\u021bin\u00e2nd avantajele ambelor limbaje f\u0103r\u0103 a renun\u021ba la unul \u00een favoarea altuia.<\/p>\n<p>Bucur\u0103-te!<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>\u00cen ultimii zece ani, am creat aplica\u021bii \u0219i pentru companii din lista <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/Fortune_Global_500\">Fortune 500<\/a><\/noindex>, \u0219i pentru afaceri cu o audien\u021b\u0103 de maximum 500 de utilizatori. \u00cen tot acest timp, inginerii no\u0219tri au dezvoltat backend-ul predominant \u00een PHP. Dar acum doi ani, un lucru a avut un impact semnificativ nu doar asupra performan\u021bei produselor noastre, ci \u0219i asupra scalabilit\u0103\u021bii acestora \u2014 am introdus Golang (Go) \u00een stiva noastr\u0103 de tehnologii.<\/p>\n<p>Aproape imediat, am observat c\u0103 Go ne permite s\u0103 cre\u0103m aplica\u021bii mai mari cu o cre\u0219tere a performan\u021bei de p\u00e2n\u0103 la 40 de ori. Cu ajutorul s\u0103u, am reu\u0219it s\u0103 extindem produsele existente, scrise \u00een PHP, \u00eembun\u0103t\u0103\u021bindu-le prin combina\u021bia avantajelor ambelor limbaje.<\/p>\n<p>V\u0103 vom povesti cum combina\u021bia Go \u0219i PHP ajut\u0103 la rezolvarea problemelor reale de dezvoltare \u0219i cum a devenit pentru noi un instrument capabil s\u0103 elimine o parte din problemele legate de <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/post\/179399\/\">modelul de \u00abmoarte\u00bb al PHP<\/a><\/noindex>.<\/p>\n<h3>Mediul dumneavoastr\u0103 de dezvoltare PHP cotidiana<\/h3>\n<p>\n\u00cenainte de a explica cum Go poate revitaliza modelul de \u00abmoarte\u00bb al PHP, s\u0103 examin\u0103m mediul dumneavoastr\u0103 standard de dezvoltare PHP.<\/p>\n<p>\u00cen cele mai multe cazuri, aplica\u021bia este rulat\u0103 folosind o combina\u021bie de server web nginx \u0219i server PHP-FPM. Primul serve\u0219te fi\u0219iere statice \u0219i redirec\u021bioneaz\u0103 cererile specifice la PHP-FPM, care execut\u0103 codul PHP. S-ar putea s\u0103 folosi\u021bi o combina\u021bie mai pu\u021bin popular\u0103 din Apache \u0219i mod_php. \u00cens\u0103, de\u0219i func\u021bioneaz\u0103 pu\u021bin diferit, principiile sunt acelea\u0219i.<\/p>\n<p>S\u0103 vedem cum execut\u0103 PHP-FPM codul aplica\u021biei. C\u00e2nd vine o cerere, PHP-FPM ini\u021biaz\u0103 un proces PHP fiu, iar detaliile cererii sunt transmise ca parte din starea sa (_GET, _POST, _SERVER etc.). <\/p>\n<p>Starea nu poate fi schimbat\u0103 \u00een timpul execu\u021biei scriptului PHP, a\u0219a c\u0103 un nou set de date de intrare poate fi ob\u021binut doar printr-un singur mod: cur\u0103\u021b\u00e2nd memoria procesului \u0219i ini\u021biindu-l din nou.<\/p>\n<p>Aceast\u0103 model de execu\u021bie are multe avantaje. Nu trebuie s\u0103 v\u0103 face\u021bi prea multe griji cu privire la consumul de memorie, toate procesele sunt complet izolate, iar dac\u0103 unul dintre ele \"moare\", acesta va fi recreat automat \u0219i nu va afecta celelalte procese. Dar acest lucru are \u0219i dezavantaje, care devin evidente atunci c\u00e2nd se \u00eencearc\u0103 scalarea aplica\u021biei.<\/p>\n<h3>Dezavantajele \u0219i ineficien\u021ba unei medii PHP obi\u0219nuite<\/h3>\n<p>\nDac\u0103 sunte\u021bi implicat \u00een dezvoltarea profesional\u0103 \u00een PHP, \u0219ti\u021bi cu ce trebuie s\u0103 \u00eencepe\u021bi un nou proiect - cu alegerea unui cadru. Acesta const\u0103 \u00een biblioteci pentru injectarea dependen\u021belor, ORM-uri, traduceri \u0219i \u0219abloane. \u0218i, desigur, toate datele de intrare ale utilizatorului pot fi u\u0219or plasate \u00eentr-un singur obiect (Symfony\/HttpFoundation sau PSR-7). Cadrele sunt grozave!<\/p>\n<p>Dar orice are un cost. \u00cen orice cadru de nivel enterprise, pentru a gestiona o cerere simpl\u0103 de utilizator sau pentru a accesa baza de date, va trebui s\u0103 \u00eenc\u0103rca\u021bi cel pu\u021bin zeci de fi\u0219iere, s\u0103 crea\u021bi numeroase clase \u0219i s\u0103 analiza\u021bi mai multe configura\u021bii. Dar cel mai r\u0103u este c\u0103, dup\u0103 ce cada sarcin\u0103 este finalizat\u0103, totul trebuie resetat \u0219i \u00eenceput din nou: tot codul pe care tocmai l-a\u021bi ini\u021biat devine inutil, iar cu acesta nu ve\u021bi putea procesa o alt\u0103 cerere. Spune\u021bi aceasta oric\u0103rui programator care scrie \u00eentr-o alt\u0103 limb\u0103 \u0219i ve\u021bi vedea confuzia pe chipul lui.<\/p>\n<p>Inginerii PHP au c\u0103utat ani de zile solu\u021bii pentru aceast\u0103 problem\u0103, utiliz\u00e2nd metodologii g\u00e2ndite pentru \u201e\u00eenc\u0103rcarea lene\u0219\u0103\u201d, micro-framework-uri, biblioteci optimizate, cache etc. Dar, \u00een cele din urm\u0103, tot trebuie s\u0103 reseteze \u00eentreaga aplica\u021bie \u0219i s\u0103 \u00eenceap\u0103 din nou, din nou \u0219i din nou.<i> (Nota traduc\u0103torului: par\u021bial, aceast\u0103 problem\u0103 va fi rezolvat\u0103 odat\u0103 cu apari\u021bia <noindex><a rel=\"nofollow\" href=\"https:\/\/wiki.php.net\/rfc\/preload\">preload<\/a><\/noindex> \u00een PHP 7.4)<\/p>\n<h3>Poate PHP s\u0103 gestioneze mai mult de o cerere cu ajutorul Go?<\/h3>\n<p>\n<\/i>Se pot scrie scripturi PHP care dureaz\u0103 mai mult de c\u00e2teva minute (chiar \u0219i ore sau zile): de exemplu, sarcini cron, parsere CSV, analizatori de cozi. Toate func\u021bioneaz\u0103 dup\u0103 acela\u0219i scenariu: extrag o sarcin\u0103, o execut\u0103, a\u0219teapt\u0103 urm\u0103toarea. Codul r\u0103m\u00e2ne constant \u00een memorie, economisind pre\u021bioase milisecunde, deoarece pentru a \u00eenc\u0103rca framework-ul \u0219i aplica\u021bia sunt necesare multe ac\u021biuni suplimentare.<\/p>\n<p>Dar a dezvolta scripturi care dureaz\u0103 mult nu este u\u0219or. Orice eroare distruge complet procesul, diagnosticarea scurgerilor de memorie este frustrant\u0103, iar utilizarea depan\u0103rii cu F5 nu mai este posibil\u0103.<\/p>\n<p>Situa\u021bia s-a \u00eembun\u0103t\u0103\u021bit odat\u0103 cu lansarea PHP 7: a ap\u0103rut un colector de gunoi fiabil, a devenit mai u\u0219or s\u0103 se gestioneze erorile, iar extensiile nucleului sunt acum protejate \u00eempotriva scurgerilor. Totu\u0219i, inginerii trebuie s\u0103 fie \u00eenc\u0103 precau\u021bi cu privire la memorie \u0219i s\u0103 fie con\u0219tien\u021bi de problemele de stare din cod (exist\u0103 oare o limb\u0103 \u00een care s\u0103 nu fie nevoie s\u0103 se acorde aten\u021bie acestor lucruri?). \u0218i totu\u0219i, \u00een PHP 7 ne a\u0219teapt\u0103 mai pu\u021bine surprize.<\/p>\n<p>Se poate lua modelul de lucru cu scripturi PHP de lung\u0103 durat\u0103, s\u0103 fie adaptat pentru sarcini mai triviale, cum ar fi gestionarea cererilor HTTP \u0219i astfel s\u0103 evit\u0103m necesitatea de a \u00eenc\u0103rca totul de la zero la fiecare cerere?<\/p>\n<p>Pentru a rezolva aceast\u0103 problem\u0103, a fost necesar\u0103 implementarea unei aplica\u021bii server care s\u0103 poat\u0103 accepta cereri HTTP \u0219i s\u0103 le redirec\u021bioneze una c\u00e2te una c\u0103tre un worker PHP, f\u0103r\u0103 a-l omor\u00ee de fiecare dat\u0103.<\/p>\n<p>\u0218tiam c\u0103 putem scrie un server web folosind PHP pur (PHP-PM) sau cu ajutorul unei extensii C (Swoole). De\u0219i fiecare metod\u0103 are avantajele sale, ambele op\u021biuni nu ne-au satisf\u0103cut \u2013 ne doream ceva mai mult. Aveam nevoie nu doar de un server web \u2013 ne a\u0219teptam s\u0103 ob\u021binem o solu\u021bie capabil\u0103 s\u0103 ne scape de problemele legate de \u201e\u00eenc\u0103rcarea grea\u201d \u00een PHP, care, \u00een acela\u0219i timp, s\u0103 fie u\u0219or adaptabil\u0103 \u0219i extensibil\u0103 pentru aplica\u021bii specifice. Cu alte cuvinte, aveam nevoie de un server de aplica\u021bii.<\/p>\n<p>Poate Go s\u0103 ajute la asta? \u0218tiam c\u0103 poate, pentru c\u0103 acest limbaj compileaz\u0103 aplica\u021biile \u00een fi\u0219iere binare unice; este multiplatform\u0103; utilizeaz\u0103 un model de procesare concurent\u0103 foarte elegant \u0219i o bibliotec\u0103 pentru lucrul cu HTTP; \u0219i, \u00een cele din urm\u0103, ne vor fi disponibile mii de biblioteci open-source \u0219i integr\u0103ri.<\/p>\n<h3>Dificult\u0103\u021bi \u00een combina\u021bia a dou\u0103 limbi de programare<\/h3>\n<p>\n\u00cen primul r\u00e2nd, a trebuit s\u0103 definim cum vor comunica \u00eentre ele dou\u0103 sau mai multe aplica\u021bii.<\/p>\n<p>De exemplu, prin<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/deuill\/go-php\"> minunata bibliotec\u0103<\/a><\/noindex> a lui Alex Pal\u00e6stra, era posibil s\u0103 implement\u0103m partajarea memoriei \u00eentre procesele PHP \u0219i Go (analog cu mod_php \u00een Apache). Dar aceast\u0103 bibliotec\u0103 are particularit\u0103\u021bi care \u00eei limiteaz\u0103 utilizarea pentru a rezolva problema noastr\u0103.<\/p>\n<p>Am decis s\u0103 folosim o alt\u0103 abordare, mai r\u0103sp\u00e2ndit\u0103: s\u0103 construim interac\u021biunea \u00eentre procese prin socket-uri \/ pipe-uri. Aceast\u0103 abordare \u0219i-a dovedit fiabilitatea \u00een ultimele decenii \u0219i a fost bine optimizat\u0103 la nivelul sistemului de operare.<\/p>\n<p>La \u00eenceput, am creat un protocol binar simplu pentru schimbul de date \u00eentre procese \u0219i pentru gestionarea erorilor de transmitere. \u00cen forma sa cea mai simpl\u0103, un protocol de acest tip sem\u0103n\u0103 cu <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Netstring\">netstring<\/a><\/noindex> de<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/spiral\/goridge\/blob\/master\/prefix.go\"> cu un antet de pachet de dimensiune fix\u0103<\/a><\/noindex> (\u00een cazul nostru 17 octe\u021bi), care con\u021bine informa\u021bii despre tipul pachetului, dimensiunea acestuia \u0219i o masc\u0103 binar\u0103 pentru verificarea integrit\u0103\u021bii datelor.<\/p>\n<p>Pe partea PHP, am folosit <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/spiral\/goridge\/blob\/master\/php-src\/SocketRelay.php#L247\">func\u021bia pack<\/a><\/noindex>, iar pe partea Go \u2013 biblioteca<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/spiral\/goridge\/blob\/master\/prefix.go\"> encoding \/ binary<\/a><\/noindex>.<\/p>\n<p>Ne-a p\u0103rut insuficient un singur protocol \u2013 \u0219i am ad\u0103ugat posibilitatea de a apela<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/spiral\/goridge\/blob\/master\/codec.go\"> serviciile Go net \/ rpc direct din PHP<\/a><\/noindex>. Asta ne-a ajutat mult \u00een dezvoltare, deoarece am putut integra cu u\u0219urin\u021b\u0103 bibliotecile Go \u00een aplica\u021biile PHP. Rezultatul acestei lucr\u0103ri poate fi v\u0103zut, de exemplu, \u00een alt produs open-source de-al nostru<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/spiral\/goridge\"> Goridge<\/a><\/noindex>.<\/p>\n<h3>Distribu\u021bia sarcinilor \u00eentre mai mul\u021bi lucr\u0103tori PHP<\/h3>\n<p>\nDup\u0103 implementarea mecanismului de interac\u021biune, ne-am g\u00e2ndit cum s\u0103 transmit\u0103 cel mai eficient sarcinile c\u0103tre procesele PHP. C\u00e2nd vine o sarcin\u0103, serverul de aplica\u021bii trebuie s\u0103 aleag\u0103 un lucr\u0103tor liber pentru a o executa. Dac\u0103 lucr\u0103torul\/procesul a terminat munca cu o eroare sau a \u201emurit\u201d, ne debaras\u0103m de el \u0219i cre\u0103m unul nou \u00een loc. Iar dac\u0103 lucr\u0103torul\/procesul a func\u021bionat cu succes, \u00eel return\u0103m \u00een pool-ul lucr\u0103torilor disponibili pentru executarea sarcinilor.<\/p>\n<p><img decoding=\"async\" alt=\"RoadRunner: PHP nu este f\u0103cut pentru a muri, sau Golang gr\u0103be\u0219te \u00een ajutor\" src=\"\/wp-content\/uploads\/2019\/06\/fe94ef304e0327247973ddd15723285a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPentru stocarea pool-ului de lucr\u0103tori activi am folosit<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/spiral\/roadrunner\/blob\/master\/static_pool.go\"> un canal tamponat<\/a><\/noindex>, pentru a elimina lucrarea \u201emuribund\u0103\u201d din pool, am ad\u0103ugat un mecanism de monitorizare a erorilor \u0219i a st\u0103rii lucr\u0103torilor.<\/p>\n<p>Ca rezultat, am ob\u021binut un server PHP func\u021bional, capabil s\u0103 proceseze orice cereri prezentate \u00een format binar.<\/p>\n<p>Pentru ca aplica\u021bia noastr\u0103 s\u0103 \u00eenceap\u0103 s\u0103 func\u021bioneze ca un server web, a fost necesar s\u0103 alegem un standard PHP fiabil pentru reprezentarea tuturor cererilor HTTP de intrare. \u00cen cazul nostru, pur \u0219i simplu <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/spiral\/roadrunner\/blob\/master\/service\/http\/request.go\">transform\u0103m<\/a><\/noindex> cererea net\/http din Go \u00een formatul<noindex><a rel=\"nofollow\" href=\"https:\/\/www.php-fig.org\/psr\/psr-7\/meta\/\"> PSR-7<\/a><\/noindex>, pentru a fi compatibil cu majoritatea framework-urilor PHP disponibile ast\u0103zi.<\/p>\n<p>Deoarece PSR-7 este considerat nemodificabil (de\u0219i unii ar spune c\u0103 tehnic nu este a\u0219a), dezvoltatorii trebuie s\u0103 scrie aplica\u021bii care \u00een principiu nu trateaz\u0103 cererea ca pe o entitate global\u0103. Aceasta se potrive\u0219te perfect cu conceptul de procese PHP de lung\u0103 durat\u0103. Implementarea noastr\u0103 final\u0103, care nu a primit \u00eenc\u0103 un nume, ar\u0103ta astfel:<\/p>\n<p><img decoding=\"async\" alt=\"RoadRunner: PHP nu este f\u0103cut pentru a muri, sau Golang gr\u0103be\u0219te \u00een ajutor\" src=\"\/wp-content\/uploads\/2019\/06\/e3a3a1af1925dfc60b7f8fd256d1ae11.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h3>V\u0103 prezent\u0103m RoadRunner \u2014<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/spiral\/roadrunner\"> un server PHP de aplica\u021bii de \u00eenalt\u0103 performan\u021b\u0103<\/a><\/noindex><\/h3>\n<p>\nPrima noastr\u0103 sarcin\u0103 de testare a fost un backend API, care experimenta periodic v\u00e2rfuri de cereri imprevizibile (de multe ori mai frecvente dec\u00e2t de obicei). De\u0219i \u00een cele mai multe cazuri capacit\u0103\u021bile nginx erau suficiente, ne confruntam regulat cu eroarea 502, deoarece nu puteam echilibra sistemul suficient de repede pentru a face fa\u021b\u0103 cre\u0219terii a\u0219teptate a sarcinilor.<\/p>\n<p>Pentru a \u00eenlocui aceast\u0103 solu\u021bie, la \u00eenceputul anului 2018 am desf\u0103\u0219urat primul nostru server de aplica\u021bii PHP\/Go. \u0218i am ob\u021binut imediat un efect incredibil! Nu numai c\u0103 ne-am debarasat complet de eroarea 502, dar am reu\u0219it s\u0103 reducem num\u0103rul serverelor cu dou\u0103 treimi, economisind o gr\u0103mad\u0103 de bani \u0219i pastile \u00eempotriva durerilor de cap pentru ingineri \u0219i manageri de produse.<\/p>\n<p>La mijlocul anului, ne-am \u00eembun\u0103t\u0103\u021bit solu\u021bia, am publicat-o pe GitHub sub licen\u021ba MIT \u0219i am numit-o <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/spiral\/roadrunner\">RoadRunner<\/a><\/noindex>, subliniind astfel viteza \u0219i eficien\u021ba sa incredibil\u0103.<\/p>\n<h3>Cum poate RoadRunner s\u0103 \u00eembun\u0103t\u0103\u021beasc\u0103 stiva dumneavoastr\u0103 de dezvoltare<\/h3>\n<p>\nAplicare<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/spiral\/roadrunner\"> RoadRunner<\/a><\/noindex> ne-a permis s\u0103 utiliz\u0103m Middleware net\/http pe partea de Go, pentru a efectua verificarea JWT \u00eenainte ca solicitarea s\u0103 ajung\u0103 \u00een PHP, precum \u0219i pentru a gestiona WebSockets \u0219i a agrega global st\u0103rile \u00een Prometheus. <\/p>\n<p>Datorit\u0103 RPC-ului integrat, putem expune API-urile oric\u0103ror biblioteci Go pentru PHP f\u0103r\u0103 a scrie extensii-wrapper. Mai important, cu ajutorul RoadRunner, putem desf\u0103\u0219ura noi servere diferite de HTTP. Exemplele includ lansarea handler-elor PHP<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/spiral\/roadrunner\/wiki\/AWS-Lambda\"> AWS Lambda<\/a><\/noindex>, crearea de parseri de cozi fiabili \u0219i chiar ad\u0103ugarea<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/spiral\/php-grpc\"> gRPC<\/a><\/noindex> \u00een aplica\u021biile noastre.<\/p>\n<p>Cu ajutorul comunit\u0103\u021bilor PHP \u0219i Go, am crescut stabilitatea solu\u021biei, \u00een unele teste am crescut performan\u021ba aplica\u021biilor de p\u00e2n\u0103 la 40 de ori, am \u00eembun\u0103t\u0103\u021bit instrumentele de depanare, am realizat integrarea cu cadrul Symfony \u0219i am ad\u0103ugat suport pentru HTTPS, HTTP\/2, pluginuri \u0219i PSR-17.<\/p>\n<h3>Concluzie<\/h3>\n<p>\nUnii \u00eenc\u0103 sunt prizonieri ai viziunii \u00eenvechite despre PHP ca fiind un limbaj lent \u0219i bulky, potrivit doar pentru scrierea pluginurilor \u00een WordPress. Ace\u0219ti oameni pot chiar s\u0103 spun\u0103 c\u0103 PHP are o astfel de limitare: atunci c\u00e2nd aplica\u021bia devine suficient de mare, trebuie s\u0103 alegi un limbaj mai \u201ematur\u201d \u0219i s\u0103 rescrii baza de cod acumulat\u0103 de-a lungul anilor.<\/p>\n<p>La toate acestea se impune un r\u0103spuns: g\u00e2nde\u0219te-te din nou. Credem c\u0103 doar tu \u00ee\u021bi stabile\u0219ti limit\u0103rile pentru PHP. Po\u021bi petrece toat\u0103 via\u021ba f\u0103c\u00e2nd tranzi\u021bii de la un limbaj la altul, \u00eencerc\u00e2nd s\u0103 g\u0103se\u0219ti combina\u021bia perfect\u0103 pentru nevoile tale, sau po\u021bi \u00eencepe s\u0103 percepi limbajele ca pe instrumente. Aparentele dezavantaje ale limbajului, precum PHP, pot fi de fapt cauzele succesului s\u0103u. Iar dac\u0103 \u00eel combini cu un alt limbaj, cum ar fi Go, vei crea produse mult mai puternice dec\u00e2t dac\u0103 te-ai limita la utilizarea unui singur limbaj.<\/p>\n<p>Dup\u0103 ce am lucrat cu combina\u021bia Go \u0219i PHP, putem spune c\u0103 le-am \u00eendr\u0103git. Nu inten\u021bion\u0103m s\u0103 sacrific\u0103m unul \u00een favoarea celuilalt - dimpotriv\u0103, vom c\u0103uta modalit\u0103\u021bi de a extrage \u0219i mai multe beneficii din aceast\u0103 dupl\u0103 stiv\u0103.<\/p>\n<p><i>UPD: salut\u0103m creatorul RoadRunner \u0219i coautorul articolului original - <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/users\/lachezis\/\" class=\"user_link\">Lachezis<\/a><\/noindex><\/i><br \/>\n<br \/>Sursa: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/badoo\/blog\/434272\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440! \u041c\u044b \u0432 Badoo \u0430\u043a\u0442\u0438\u0432\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u043d\u0430\u0434 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e PHP, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0443 \u043d\u0430\u0441 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u043d\u0430 \u044d\u0442\u043e\u043c \u044f\u0437\u044b\u043a\u0435 \u0438 \u0432\u043e\u043f\u0440\u043e\u0441 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u2014 \u044d\u0442\u043e \u0432\u043e\u043f\u0440\u043e\u0441 \u044d\u043a\u043e\u043d\u043e\u043c\u0438\u0438 \u0434\u0435\u043d\u0435\u0433. \u0411\u043e\u043b\u0435\u0435 \u0434\u0435\u0441\u044f\u0442\u0438 \u043b\u0435\u0442 \u043d\u0430\u0437\u0430\u0434 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e PHP-FPM, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u043b \u0441\u043e\u0431\u043e\u0439 \u043d\u0430\u0431\u043e\u0440 \u043f\u0430\u0442\u0447\u0435\u0439 \u0434\u043b\u044f PHP, \u0430 \u043f\u043e\u0437\u0436\u0435 \u0432\u043e\u0448\u0451\u043b \u0432 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u0443\u044e \u043f\u043e\u0441\u0442\u0430\u0432\u043a\u0443. \u0417\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 \u0433\u043e\u0434\u044b PHP \u0441\u0438\u043b\u044c\u043d\u043e [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":26762,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-35722","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440!\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/roadrunner-php-ne-sozdan-chtoby-umirat-ili-golang-speshit-na-pomoshh\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"ro_RO\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47RoadRunner: PHP \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u043d, \u0447\u0442\u043e\u0431\u044b \u0443\u043c\u0438\u0440\u0430\u0442\u044c, \u0438\u043b\u0438 Golang \u0441\u043f\u0435\u0448\u0438\u0442 \u043d\u0430 \u043f\u043e\u043c\u043e\u0449\u044c | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440!\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/roadrunner-php-ne-sozdan-chtoby-umirat-ili-golang-speshit-na-pomoshh\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T19:05:58+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T19:05:58+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47RoadRunner: PHP nu a fost creat pentru a muri, sau Golang vine \u00een ajutor | ProHoster","description":"Salut, Habr!","canonical_url":"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/roadrunner-php-ne-sozdan-chtoby-umirat-ili-golang-speshit-na-pomoshh","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"ro_RO","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47RoadRunner: PHP \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u043d, \u0447\u0442\u043e\u0431\u044b \u0443\u043c\u0438\u0440\u0430\u0442\u044c, \u0438\u043b\u0438 Golang \u0441\u043f\u0435\u0448\u0438\u0442 \u043d\u0430 \u043f\u043e\u043c\u043e\u0449\u044c | ProHoster","og:description":"\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440!","og:url":"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/roadrunner-php-ne-sozdan-chtoby-umirat-ili-golang-speshit-na-pomoshh","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T19:05:58+00:00","article:modified_time":"2019-10-31T19:05:58+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"35722","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-22 00:30:57","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 01:57:45","updated":"2026-01-22 00:30:57","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts\/35722","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/comments?post=35722"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts\/35722\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/media\/26762"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/media?parent=35722"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/categories?post=35722"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/tags?post=35722"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}