{"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\/sv\/blog\/administrirovanie\/roadrunner-php-ne-sozdan-chtoby-umirat-ili-golang-speshit-na-pomoshh","title":{"rendered":"RoadRunner: PHP \u00e4r inte skapat f\u00f6r att d\u00f6, eller Golang kommer till hj\u00e4lp","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"RoadRunner: PHP \u00e4r inte skapat f\u00f6r att d\u00f6, eller Golang kommer till hj\u00e4lp\" src=\"\/wp-content\/uploads\/2019\/06\/d2a69318cf25caa8fb49efedb333d7f8.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nHej, Habr! Vi p\u00e5 Badoo arbetar aktivt <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/company\/badoo\/blog\/430722\/\">med prestandan av PHP<\/a><\/noindex>, eftersom vi har ett ganska stort system p\u00e5 detta spr\u00e5k och prestandafr\u00e5gan handlar om kostnadsbesparingar. F\u00f6r mer \u00e4n tio \u00e5r sedan skapade vi PHP-FPM f\u00f6r detta, vilket f\u00f6rst var en upps\u00e4ttning patchar f\u00f6r PHP, och senare blev en del av den officiella distributionen.<\/p>\n<p>Under de senaste \u00e5ren har PHP gjort stort framsteg: skr\u00e4psamlaren har f\u00f6rb\u00e4ttrats, stabiliteten har \u00f6kat \u2013 idag g\u00e5r det utan st\u00f6rre problem att skriva demoner och l\u00e5nglivade skript i PHP. Detta har lett Spiral Scout till att ta ytterligare steg: RoadRunner, till skillnad fr\u00e5n PHP-FPM, frig\u00f6r inte minnet mellan f\u00f6rfr\u00e5gningar, vilket ger en ytterligare prestanda\u00f6kning (\u00e4ven om detta tillv\u00e4gag\u00e5ngss\u00e4tt komplicerar utvecklingsprocessen). Vi experimenterar f\u00f6r n\u00e4rvarande med detta verktyg, men vi har \u00e4nnu inga resultat att dela med oss av. F\u00f6r att g\u00f6ra v\u00e4ntan mer underh\u00e5llande, <b>publicerar vi en \u00f6vers\u00e4ttning av RoadRunner-meddelandet fr\u00e5n Spiral Scout.<\/b><\/p>\n<p>Tillv\u00e4gag\u00e5ngss\u00e4ttet i artikeln ligger oss n\u00e4ra: n\u00e4r vi l\u00f6ser v\u00e5ra problem anv\u00e4nder vi ocks\u00e5 oftast kombinationen av PHP och Go, d\u00e4r vi drar nytta av f\u00f6rdelarna med b\u00e5da spr\u00e5ken utan att avst\u00e5 fr\u00e5n det ena till f\u00f6rm\u00e5n f\u00f6r det andra.<\/p>\n<p>Njut!<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>Under de senaste tio \u00e5ren har vi skapat applikationer b\u00e5de f\u00f6r f\u00f6retag p\u00e5 listan <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/Fortune_Global_500\">Fortune 500<\/a><\/noindex>, s\u00e5v\u00e4l som f\u00f6r verksamheter med en publik p\u00e5 h\u00f6gst 500 anv\u00e4ndare. Under hela denna tid har v\u00e5ra ingenj\u00f6rer huvudsakligen utvecklat backend i PHP. Men f\u00f6r tv\u00e5 \u00e5r sedan p\u00e5verkade n\u00e5got starkt inte bara prestandan hos v\u00e5ra produkter, utan \u00e4ven deras skalbarhet \u2013 vi inf\u00f6rde Golang (Go) i v\u00e5r teknologistack.<\/p>\n<p>N\u00e4stan omedelbart uppt\u00e4ckte vi att Go l\u00e5ter oss skapa st\u00f6rre applikationer med en prestandaf\u00f6rb\u00e4ttring p\u00e5 upp till 40 g\u00e5nger. Med hj\u00e4lp av det kunde vi ut\u00f6ka befintliga produkter skrivna i PHP, vilket f\u00f6rb\u00e4ttrade dem genom att kombinera f\u00f6rdelarna med b\u00e5da spr\u00e5ken.<\/p>\n<p>Vi kommer att ber\u00e4tta hur kombinationen av Go och PHP hj\u00e4lper till att l\u00f6sa verkliga utvecklingsproblem och hur den har blivit ett verktyg som kan frig\u00f6ra oss fr\u00e5n vissa problem relaterade till <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/post\/179399\/\">PHP:s \"d\u00f6ende\"-modell<\/a><\/noindex>.<\/p>\n<h3>Din dagliga PHP-utvecklingsmilj\u00f6<\/h3>\n<p>\nInnan vi ber\u00e4ttar hur Go kan \u00e5teruppliva PHP:s \"d\u00f6ende\"-modell, l\u00e5t oss titta p\u00e5 din standard PHP-utvecklingsmilj\u00f6.<\/p>\n<p>I de flesta fall startar du applikationen med en kombination av webbservern nginx och PHP-FPM-servern. Den f\u00f6rsta hanterar statiska filer och vidarebefordrar specifika f\u00f6rfr\u00e5gningar till PHP-FPM, som i sin tur utf\u00f6r PHP-koden. Kanske anv\u00e4nder du en mindre popul\u00e4r kombination av Apache och mod_php. Men \u00e4ven om den fungerar lite annorlunda, \u00e4r principerna desamma.<\/p>\n<p>L\u00e5t oss titta p\u00e5 hur PHP-FPM utf\u00f6r applikationskoden. N\u00e4r en f\u00f6rfr\u00e5gan kommer, initialiserar PHP-FPM en underordnad PHP-process och \u00f6verf\u00f6r f\u00f6rfr\u00e5gningens detaljer som en del av dess tillst\u00e5nd (_GET, _POST, _SERVER osv.). <\/p>\n<p>Tillst\u00e5ndet kan inte \u00e4ndras under k\u00f6rningen av PHP-skriptet, s\u00e5 f\u00f6r att f\u00e5 en ny upps\u00e4ttning ing\u00e5ngsdata finns det bara ett s\u00e4tt: att reng\u00f6ra processens minne och initialisera den p\u00e5 nytt.<\/p>\n<p>Denna exekveringsmodell har m\u00e5nga f\u00f6rdelar. Du beh\u00f6ver inte oroa dig mycket f\u00f6r minnesanv\u00e4ndning, alla processer \u00e4r helt isolerade, och om en av dem \"d\u00f6r\", kommer den automatiskt att \u00e5terskapas utan att p\u00e5verka de andra processerna. Men denna metod har ocks\u00e5 nackdelar som visar sig n\u00e4r man f\u00f6rs\u00f6ker skala applikationen.<\/p>\n<h3>Nackdelar och ineffektivitet med en vanlig PHP-milj\u00f6<\/h3>\n<p>\nOm du arbetar med professionell PHP-utveckling vet du att du ska b\u00f6rja ett nytt projekt med att v\u00e4lja ett ramverk. Det best\u00e5r av bibliotek f\u00f6r beroendeinjektion, ORM:er, \u00f6vers\u00e4ttningar och mallar. Och sj\u00e4lvklart kan alla anv\u00e4ndardata enkelt samlas i ett objekt (Symfony\/HttpFoundation eller PSR-7). Ramverk \u00e4r fantastiska!<\/p>\n<p>Men allt har sitt pris. I vilket f\u00f6retagsramverk som helst m\u00e5ste du ladda minst tiotals filer, skapa m\u00e5nga klasser och analysera flera konfigurationer f\u00f6r att hantera en enkel anv\u00e4ndarf\u00f6rfr\u00e5gan eller databasanslutning. Men det v\u00e4rsta \u00e4r att efter att varje uppgift har utf\u00f6rts m\u00e5ste allt rensas och b\u00f6rja om: all kod du just har initierat blir v\u00e4rdel\u00f6s, och med den kan du inte bearbeta ytterligare en f\u00f6rfr\u00e5gan. Ber\u00e4tta detta f\u00f6r en programmerare som skriver i ett annat spr\u00e5k, s\u00e5 kommer du se f\u00f6rundran i deras ansikte.<\/p>\n<p>PHP-ingenj\u00f6rer har i \u00e5ratal letat efter s\u00e4tt att l\u00f6sa detta problem, anv\u00e4nt genomt\u00e4nkta metoder f\u00f6r \"lazy\" inl\u00e4sning, mikroramverk, optimerade bibliotek, cache, osv. Men i slut\u00e4ndan m\u00e5ste man \u00e4nd\u00e5 \u00e5terst\u00e4lla hela applikationen och b\u00f6rja om, g\u00e5ng p\u00e5 g\u00e5ng.<i> (\u00d6vers\u00e4ttarens anm\u00e4rkning: delvis kommer detta problem att l\u00f6sas med inf\u00f6randet av <noindex><a rel=\"nofollow\" href=\"https:\/\/wiki.php.net\/rfc\/preload\">preload<\/a><\/noindex> PHP 7.4)<\/p>\n<h3>Kan PHP med hj\u00e4lp av Go hantera mer \u00e4n en beg\u00e4ran?<\/h3>\n<p>\n<\/i>Det g\u00e5r att skriva PHP-skript som lever l\u00e4ngre \u00e4n n\u00e5gra minuter (upp till timmar eller dagar): exempelvis cron-jobb, CSV-parsare, k\u00f6hanterare. Alla arbetar enligt samma schema: de plockar upp en uppgift, utf\u00f6r den, v\u00e4ntar p\u00e5 n\u00e4sta. Koden finns st\u00e4ndigt i minnet, vilket sparar dyrbar millisekund, eftersom det kr\u00e4vs m\u00e5nga ytterligare \u00e5tg\u00e4rder f\u00f6r att ladda ramverket och applikationen.<\/p>\n<p>Men att utveckla l\u00e5nglivade skript \u00e4r inte s\u00e5 enkelt. Ett enda fel kan helt d\u00f6da processen, att diagnostisera minnesl\u00e4ckor \u00e4r frustrerande, och det g\u00e5r inte l\u00e4ngre att anv\u00e4nda F5 f\u00f6r fels\u00f6kning.<\/p>\n<p>Situationen har f\u00f6rb\u00e4ttrats med PHP 7: en p\u00e5litlig skr\u00e4psamlar installerades, det blev l\u00e4ttare att hantera fel, och k\u00e4rntill\u00e4gg \u00e4r nu skyddade mot l\u00e4ckor. Visst m\u00e5ste ingenj\u00f6rerna fortfarande hantera minnet varsamt och t\u00e4nka p\u00e5 kodens tillst\u00e5ndsproblem (finns det n\u00e5got spr\u00e5k d\u00e4r man kan bortse fr\u00e5n s\u00e5dana saker?). Trots det finns det f\u00e4rre ov\u00e4ntade \u00f6verraskningar med PHP 7.<\/p>\n<p>Kan man ta modellen f\u00f6r arbete med l\u00e5nglivade PHP-skript, anpassa den f\u00f6r mer triviala uppgifter som att hantera HTTP-beg\u00e4rningar, och p\u00e5 s\u00e5 s\u00e4tt undkomma behovet att ladda allt fr\u00e5n b\u00f6rjan vid varje beg\u00e4ran?<\/p>\n<p>F\u00f6r att l\u00f6sa detta problem beh\u00f6vde man f\u00f6rst implementera en serverapplikation som kunde ta emot HTTP-beg\u00e4rningar och dirigera dem en i taget till en PHP-arbetare, utan att d\u00f6da den varje g\u00e5ng.<\/p>\n<p>Vi visste att vi skulle kunna skriva en webbserver i ren PHP (PHP-PM) eller med hj\u00e4lp av C-till\u00e4gg (Swoole). Och \u00e4ven om varje metod har sina f\u00f6rdelar, var ingen av dem tillr\u00e4cklig f\u00f6r oss \u2013 vi ville ha n\u00e5got mer. Vi beh\u00f6vde inte bara en webbserver \u2013 vi f\u00f6rv\u00e4ntade oss en l\u00f6sning som skulle befria oss fr\u00e5n problemen med \"tung start\" i PHP, och som dessutom skulle kunna anpassas och ut\u00f6kas l\u00e4tt f\u00f6r specifika applikationer. Det vill s\u00e4ga, vi beh\u00f6vde en applikationsserver.<\/p>\n<p>Kan Go hj\u00e4lpa till med detta? Vi visste att den kunde, eftersom spr\u00e5ket kompilerar applikationer till enstaka bin\u00e4rfiler; det \u00e4r plattformsoberoende; det anv\u00e4nder en egen, mycket elegant modell f\u00f6r samtidighet (concurrency) och ett bibliotek f\u00f6r att hantera HTTP; och slutligen skulle vi f\u00e5 tillg\u00e5ng till tusentals open-source-bibliotek och integrationer.<\/p>\n<h3>Sv\u00e5righeterna med att sammanf\u00f6ra tv\u00e5 programmeringsspr\u00e5k<\/h3>\n<p>\nF\u00f6rst och fr\u00e4mst var det n\u00f6dv\u00e4ndigt att definiera hur tv\u00e5 eller flera applikationer skulle kommunicera med varandra.<\/p>\n<p>Till exempel genom<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/deuill\/go-php\"> det fantastiska biblioteket<\/a><\/noindex> av Alex Palastras, som kunde g\u00f6ra det m\u00f6jligt f\u00f6r PHP- och Go-processer att dela minne (p\u00e5 liknande s\u00e4tt som mod_php i Apache). Men detta bibliotek har funktioner som begr\u00e4nsar dess till\u00e4mpning f\u00f6r att l\u00f6sa v\u00e5rt problem.<\/p>\n<p>Vi besl\u00f6t att anv\u00e4nda en annan, mer utbredd metod: att bygga interaktionen mellan processerna genom sockets\/pipelines. Denna metod har under de senaste decennierna visat sig vara p\u00e5litlig och har optimerats v\u00e4l p\u00e5 operativsystemsniv\u00e5.<\/p>\n<p>Till att b\u00f6rja med skapade vi ett enkelt bin\u00e4rt protokoll f\u00f6r datakommunikation mellan processer och hantering av \u00f6verf\u00f6ringsfel. I sin enklaste form p\u00e5minner ett protokoll av denna typ om <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Netstring\">netstring<\/a><\/noindex> med<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/spiral\/goridge\/blob\/master\/prefix.go\"> med fast storlek p\u00e5 paketets header<\/a><\/noindex> (i v\u00e5rt fall 17 byte), vilket inneh\u00e5ller information om paketets typ, dess storlek och en bin\u00e4r mask f\u00f6r att kontrollera integriteten i data.<\/p>\n<p>P\u00e5 PHP-sidan anv\u00e4nde vi <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/spiral\/goridge\/blob\/master\/php-src\/SocketRelay.php#L247\">funktionen pack<\/a><\/noindex>, medan vi p\u00e5 Go-sidan anv\u00e4nde biblioteket<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/spiral\/goridge\/blob\/master\/prefix.go\"> encoding\/binary<\/a><\/noindex>.<\/p>\n<p>Det verkade som om vi beh\u00f6vde mer \u00e4n ett protokoll \u2013 s\u00e5 vi lade till m\u00f6jligheten att anropa<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/spiral\/goridge\/blob\/master\/codec.go\"> Go-tj\u00e4nster net\/rpc direkt fr\u00e5n PHP<\/a><\/noindex>. Senare hj\u00e4lpte detta oss mycket i utvecklingen, eftersom vi enkelt kunde integrera Go-bibliotek i PHP-applikationer. Resultatet av detta arbete kan ses, till exempel, i v\u00e5r andra open-source-produkt<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/spiral\/goridge\"> Goridge<\/a><\/noindex>.<\/p>\n<h3>Uppdelning av uppgifter mellan flera PHP-arbetare<\/h3>\n<p>\nEfter implementeringen av interaktionsmekanismen b\u00f6rjade vi t\u00e4nka p\u00e5 hur vi effektivast kunde \u00f6verf\u00f6ra uppgifter till PHP-processerna. N\u00e4r en uppgift anl\u00e4nder, m\u00e5ste applikationsservern v\u00e4lja en ledig arbetare f\u00f6r att utf\u00f6ra den. Om arbetaren\/processen avslutade arbetet med ett fel eller \"dog\", tar vi bort den och skapar en ny i dess st\u00e4lle. Och om arbetaren\/processen k\u00f6rs framg\u00e5ngsrikt, \u00e5terl\u00e4mnar vi den till poolen av arbetare som \u00e4r tillg\u00e4ngliga f\u00f6r att utf\u00f6ra uppgifter.<\/p>\n<p><img decoding=\"async\" alt=\"RoadRunner: PHP \u00e4r inte skapat f\u00f6r att d\u00f6, eller Golang kommer till hj\u00e4lp\" src=\"\/wp-content\/uploads\/2019\/06\/fe94ef304e0327247973ddd15723285a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nF\u00f6r att lagra poolen av aktiva arbetare anv\u00e4nde vi<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/spiral\/roadrunner\/blob\/master\/static_pool.go\"> en buffrad kanal<\/a><\/noindex>, f\u00f6r att ta bort ov\u00e4ntat \"d\u00f6da\" arbetare fr\u00e5n poolen lade vi till en mekanism f\u00f6r att sp\u00e5ra fel och arbetarnas tillst\u00e5nd.<\/p>\n<p>Som ett resultat fick vi en fungerande PHP-server som kan hantera alla f\u00f6rfr\u00e5gningar som presenteras i bin\u00e4rt format.<\/p>\n<p>F\u00f6r att v\u00e5r applikation skulle b\u00f6rja fungera som en webbserver, var vi tvungna att v\u00e4lja en p\u00e5litlig PHP-standard f\u00f6r att representera alla inkommande HTTP-f\u00f6rfr\u00e5gningar. I v\u00e5rt fall <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/spiral\/roadrunner\/blob\/master\/service\/http\/request.go\">omvandlar vi<\/a><\/noindex> net\/http-f\u00f6rfr\u00e5gan fr\u00e5n Go till formatet<noindex><a rel=\"nofollow\" href=\"https:\/\/www.php-fig.org\/psr\/psr-7\/meta\/\"> PSR-7<\/a><\/noindex>, s\u00e5 att den \u00e4r kompatibel med de flesta tillg\u00e4ngliga PHP-ramverken idag.<\/p>\n<p>Eftersom PSR-7 anses vara of\u00f6r\u00e4nderlig (n\u00e5gon skulle s\u00e4ga att det tekniskt sett inte \u00e4r s\u00e5), m\u00e5ste utvecklare skriva applikationer som i princip inte hanterar f\u00f6rfr\u00e5gan som en global entitet. Detta passar perfekt med konceptet av l\u00e5nglivade PHP-processer. V\u00e5r slutliga implementering, som \u00e4nnu inte f\u00e5tt n\u00e5got namn, s\u00e5g ut s\u00e5 h\u00e4r:<\/p>\n<p><img decoding=\"async\" alt=\"RoadRunner: PHP \u00e4r inte skapat f\u00f6r att d\u00f6, eller Golang kommer till hj\u00e4lp\" src=\"\/wp-content\/uploads\/2019\/06\/e3a3a1af1925dfc60b7f8fd256d1ae11.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h3>Vi presenterar RoadRunner \u2014<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/spiral\/roadrunner\"> en h\u00f6gpresterande server f\u00f6r PHP-applikationer<\/a><\/noindex><\/h3>\n<p>\nV\u00e5r f\u00f6rsta testuppgift var en API-backend, d\u00e4r det periodiskt of\u00f6ruts\u00e4gbart uppstod toppar av f\u00f6rfr\u00e5gningar (mycket oftare \u00e4n vanligt). \u00c4ven om nginx:s kapacitet i de flesta fall var tillr\u00e4cklig, st\u00f6tte vi regelbundet p\u00e5 fel 502, eftersom vi inte kunde balansera systemet tillr\u00e4ckligt snabbt f\u00f6r att m\u00f6ta den f\u00f6rv\u00e4ntade \u00f6kningen av belastningen.<\/p>\n<p>F\u00f6r att ers\u00e4tta denna l\u00f6sning implementerade vi i b\u00f6rjan av 2018 v\u00e5r f\u00f6rsta PHP\/Go-applikationsserver. Och vi fick omedelbart en otrolig effekt! Vi inte bara helt eliminerade fel 502, utan kunde ocks\u00e5 minska antalet servrar med tv\u00e5 tredjedelar, och sparade massor av pengar och huvudv\u00e4rk f\u00f6r ingenj\u00f6rer och produktchefer.<\/p>\n<p>I mitten av \u00e5ret f\u00f6rb\u00e4ttrade vi v\u00e5r l\u00f6sning, publicerade den p\u00e5 GitHub under MIT-licensen och d\u00f6pte den till <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/spiral\/roadrunner\">RoadRunner<\/a><\/noindex>, vilket framh\u00e4ver dess otroliga hastighet och effektivitet.<\/p>\n<h3>Hur RoadRunner kan f\u00f6rb\u00e4ttra din utvecklingsstack<\/h3>\n<p>\nTill\u00e4mpning<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/spiral\/roadrunner\"> RoadRunner<\/a><\/noindex> gjorde det m\u00f6jligt f\u00f6r oss att anv\u00e4nda Middleware net\/http p\u00e5 Go-sidan f\u00f6r att genomf\u00f6ra JWT-verifiering innan beg\u00e4ran ens n\u00e5r PHP, samt f\u00f6r att hantera WebSockets och globalt aggregera tillst\u00e5nd i Prometheus. <\/p>\n<p>Tack vare den inbyggda RPC kan man \u00f6ppna API:er fr\u00e5n valfria Go-bibliotek f\u00f6r PHP utan att skriva runtill\u00e4gg. Vad som \u00e4r \u00e4nnu viktigare \u00e4r att med RoadRunner kan man distribuera nya servrar som skiljer sig fr\u00e5n HTTP. Exempelvis kan man k\u00f6ra PHP-hanterare,<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/spiral\/roadrunner\/wiki\/AWS-Lambda\"> AWS Lambda<\/a><\/noindex>skapa p\u00e5litliga k\u00f6parsers och till och med l\u00e4gga till<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/spiral\/php-grpc\"> gRPC<\/a><\/noindex> i v\u00e5ra applikationer.<\/p>\n<p>Med hj\u00e4lp av PHP- och Go-gemenskaperna har vi f\u00f6rb\u00e4ttrat l\u00f6sningens stabilitet, \u00f6kat prestandan i vissa tester upp till 40 g\u00e5nger, f\u00f6rb\u00e4ttrat debuggningsverktygen, implementerat integration med ramverket Symfony och lagt till st\u00f6d f\u00f6r HTTPS, HTTP\/2, plugins och PSR-17.<\/p>\n<h3>Slutsats<\/h3>\n<p>\nVissa \u00e4r fortfarande fast i den f\u00f6r\u00e5ldrade uppfattningen om PHP som ett l\u00e5ngsamt och skrymmande spr\u00e5k, som bara \u00e4r anv\u00e4ndbart f\u00f6r att skriva plugins till WordPress. Dessa personer kan till och med h\u00e4vda att PHP har en s\u00e5dan begr\u00e4nsning: n\u00e4r en applikation blir tillr\u00e4ckligt stor, m\u00e5ste man v\u00e4lja ett mer \"mognat\" spr\u00e5k och skriva om den kodbas som byggts upp under m\u00e5nga \u00e5r.<\/p>\n<p>Ang\u00e5ende detta vill vi s\u00e4ga: t\u00e4nk en g\u00e5ng till. Vi tror att det \u00e4r ni sj\u00e4lva som s\u00e4tter begr\u00e4nsningar f\u00f6r PHP. Ni kan spendera hela livet p\u00e5 att byta mellan spr\u00e5k i jakt p\u00e5 den perfekta l\u00f6sningen f\u00f6r era behov, eller s\u00e5 kan ni b\u00f6rja se spr\u00e5k som verktyg. Illusionen av spr\u00e5kets brister som PHP kan faktiskt vara anledningen till dess framg\u00e5ng. Och om ni kombinerar det med ett annat spr\u00e5k som Go, kommer ni att skapa betydligt kraftfullare produkter \u00e4n om ni begr\u00e4nsar er till att anv\u00e4nda ett enda spr\u00e5k.<\/p>\n<p>Efter att ha arbetat med kombinationen Go och PHP kan vi s\u00e4ga att vi \u00e4lskar dem. Vi planerar inte att offra det ena f\u00f6r det andra - tv\u00e4rtom kommer vi att s\u00f6ka s\u00e4tt att f\u00e5 \u00e4nnu mer nytta av denna dubbelstack.<\/p>\n<p><i>UPD: v\u00e4lkomna skaparen av RoadRunner och medf\u00f6rfattaren till den ursprungliga artikel \u2014 <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/users\/lachezis\/\" class=\"user_link\">Lachezis<\/a><\/noindex><\/i><br \/>\n<br \/>K\u00e4lla: <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.4 - 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\/sv\/blog\/administrirovanie\/roadrunner-php-ne-sozdan-chtoby-umirat-ili-golang-speshit-na-pomoshh\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"sv_SE\" \/>\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\/sv\/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 \u00e4r inte skapat f\u00f6r att d\u00f6, eller s\u00e5 skyndar sig Golang till unds\u00e4ttning | ProHoster","description":"Hej, Habr!","canonical_url":"https:\/\/prohoster.info\/sv\/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":"sv_SE","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\/sv\/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\/sv\/wp-json\/wp\/v2\/posts\/35722","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/comments?post=35722"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/posts\/35722\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/media\/26762"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/media?parent=35722"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/categories?post=35722"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/tags?post=35722"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}