RoadRunner: PHP ne ji bo mirinê, an jî Golang ji bo rizgarkirinê hatî çêkirin

RoadRunner: PHP ne ji bo mirinê, an jî Golang ji bo rizgarkirinê hatî çêkirin

Hey Habr! Em li Badoo çalak in li ser performansa PHP-ê dixebitin, ji ber ku di vî zimanî de pergalek me ya pir mezin heye û pirsgirêka performansê pirsgirêkek teserûfa drav e. Zêdetirî deh sal berê, me ji bo vê yekê PHP-FPM afirand, ku di destpêkê de ji bo PHP-ê komek paçeyan bû, û paşê jî ket belavkirina fermî.

Di van salên dawî de, PHP pêşkeftinek mezin çêkir: berhevkarê çopê çêtir bûye, asta aramiyê zêde bûye - îro hûn dikarin di PHP-ê de şeytan û nivîsarên demdirêj bêyî pirsgirêk binivîsin. Vê yekê hişt ku Spiral Scout pêşdetir biçe: RoadRunner, berevajî PHP-FPM, bîranînê di navbera daxwazan de paqij nake, ku ev yek qezencek performansa zêde dide (her çend ev nêzîkatî pêvajoya pêşkeftinê tevlihev dike). Em niha bi vê amûrê diceribînin, lê hêj ti encamek me tune ku em parve bikin. Ji bo ku li benda wan bêtir kêfxweş bibin, em wergerandina ragihandina RoadRunner ji Spiral Scout diweşînin.

Nêzîkatiya ji gotarê nêzîkê me ye: dema ku pirsgirêkên xwe çareser dikin, em di heman demê de pir caran komek PHP û Go bikar tînin, ji her du zimanan sûd werdigirin û yek di berjewendiya ya din de nahêlin.

Hizkirin!

Di deh salên dawî de, me ji navnîşê ji bo pargîdaniyan serîlêdan çêkirin Fortune 500, û ji bo karsaziyên ku ji 500 bikarhêneran zêdetir temaşevan hene. Hemî vê demê, endezyarên me bi taybetî di PHP-ê de paşnavê pêşve xistin. Lê du sal berê, tiştek bandorek mezin ne tenê li ser performansa hilberên me, lê di heman demê de li ser mezinbûna wan jî hebû - me Golang (Go) xist nav stoka teknolojiya xwe.

Hema di cih de, me kifş kir ku Go destûr da me ku em bi baştirkirina performansa 40x-ê serîlêdanên mezintir ava bikin. Bi wê re, me karîbû hilberên heyî yên ku bi PHP-ê hatine nivîsandin berfireh bikin, bi berhevkirina avantajên her du zimanan wan baştir bikin.

Em ê ji we re vebêjin ka tevliheviya Go û PHP-ê çawa dibe alîkar ku pirsgirêkên pêşkeftina rastîn çareser bikin û ew çawa ji me re bûye amûrek ku dikare ji hin pirsgirêkên têkildar xilas bibe. Modela mirinê ya PHP.

Jîngeha pêşveçûna weya rojane ya PHP

Berî ku em bipeyivin ka hûn çawa dikarin Go bikar bînin da ku modela mirinê ya PHP-ê vejînin, werin em li hawîrdora pêşkeftina PHP-ya xweya xwerû binêrin.

Di pir rewşan de, hûn serîlêdana xwe bi karanîna tevhevek servera webê nginx û servera PHP-FPM dimeşînin. Ya berê pelên statîk pêşkêşî dike û daxwazên taybetî beralî dike PHP-FPM, dema ku PHP-FPM bixwe koda PHP-ê pêk tîne. Dibe ku hûn berhevoka kêmtir populer a Apache û mod_php bikar bînin. Lê her çend ew hinekî cûda dixebite jî, prensîb yek in.

Ka em mêze bikin ka PHP-FPM çawa koda serîlêdanê dimeşîne. Dema ku daxwazek tê, PHP-FPM pêvajoyek zarokê PHP-ê dest pê dike û hûrguliyên daxwazê ​​wekî beşek dewleta xwe derbas dike (_GET, _POST, _SERVER, hwd.).

Dewlet nikare di dema darvekirina script PHP-ê de biguhezîne, ji ber vê yekê tenê rêyek heye ku meriv komek nû ya daneya têketinê bigire: paqijkirina bîranîna pêvajoyê û ji nû ve destpêkirina wê.

Ev modela darvekirinê gelek avantajên xwe hene. Hûn ne hewce ne ku pir zêde li ser vexwarina bîranînê bitirsin, hemî pêvajo bi tevahî veqetandî ne, û heke yek ji wan "bimire", ew ê bixweber were afirandin û ew ê bandorê li pêvajoyên mayî neke. Lê ev nêzîkatî di heman demê de dezawantajên xwe jî hene ku dema ku hewl didin pîvandina serîlêdanê xuya dikin.

Dezawantaj û bêserûberiya Jîngehek PHP-ya Birêkûpêk

Ger hûn pêşdebirek PHP-ya profesyonel in, wê hingê hûn dizanin ku hûn li ku derê projeyek nû dest pê bikin - bi hilbijartina çarçoveyek. Ew ji pirtûkxaneyên derzîlêdanê yên girêdayîbûnê, ORM, werger û şablonan pêk tê. Û, bê guman, hemî têketina bikarhêner dikare bi rehetî li yek tiştan were danîn (Symfony / HttpFoundation an PSR-7). Çarçove xweş in!

Lê her tiştî bihayê xwe heye. Di her çarçoveyek asta pargîdanî de, ji bo ku hûn daxwazek bikarhênerek hêsan an gihîştina databasek pêvajo bikin, hûn ê neçar bin ku bi kêmî ve bi dehan pelan bar bikin, gelek çînan biafirînin û çend mîhengan pars bikin. Lê ya herî xirab ev e ku piştî qedandina her peywirê, hûn ê hewce bikin ku her tiştî ji nû ve saz bikin û ji nû ve dest pê bikin: hemî koda ku we nû daye destpêkirin bêkar dibe, bi alîkariya wê hûn ê êdî daxwazek din pêve nekin. Vê yekê ji her bernameçêkerê re ku bi zimanekî din dinivîse re bêje, û hûn ê li rûyê wî matmayî bibînin.

Endezyarên PHP-ê bi salan li awayên çareserkirina vê pirsgirêkê digerin, bi karanîna teknîkên barkirina tembel a jîr, mîkroframeworks, pirtûkxaneyên xweşbînkirî, cache, hwd. Lê di dawiyê de, hûn dîsa jî neçar in ku hemî serîlêdanê ji nû ve bikin û ji nû ve, dîsa û dîsa dest pê bikin. (Têbînîya wergêr: ev pirsgirêk bi hatina wê re dê qismî çareser bibe barkirin di PHP 7.4 de)

Ma PHP bi Go re dikare ji yek daxwazek zêdetir bijî?

Mimkun e ku meriv nivîsarên PHP-ê yên ku ji çend hûrdeman dirêjtir dijîn (heta demjimêr an rojan) binivîsin: mînakî, karên cron, parserkerên CSV, şikênerên rêzê. Ew hemî li gorî heman senaryoyê dixebitin: ew peywirek vedigirin, wê pêk tînin û li benda ya din bisekinin. Kod her dem di bîranînê de dimîne, millisecondên hêja hildibijêre ji ber ku ji bo barkirina çarçove û serîlêdanê gelek gavên din hewce ne.

Lê pêşxistina nivîsarên demdirêj ne hêsan e. Her xeletiyek bi tevahî pêvajoyê dikuje, teşhîskirina lepikên bîranînê aciz e, û xeletkirina F5 êdî ne gengaz e.

Bi berdana PHP 7 re rewş baştir bûye: berhevkarek çopê pêbawer xuya bû, birêvebirina xeletiyan hêsantir bûye, û dirêjkirina kernelê naha belkî ne. Rast e, hîna jî pêdivî ye ku endezyar ji bîrê baldar bin û hay ji pirsgirêkên dewletê yên di kodê de hebin (gelo zimanek heye ku van tiştan paşguh bike?). Dîsa jî, PHP 7 ji me re kêmtir surprîz hene.

Ma gengaz e ku meriv modela xebata bi nivîsarên PHP-ya demdirêj bigire, wê li gorî peywirên piçûktir ên mîna pêvajokirina daxwazên HTTP-ê biguncîne, û bi vî rengî ji hewcedariya barkirina her tiştî ji sifirê bi her daxwazekê re xilas bibe?

Ji bo çareserkirina vê pirsgirêkê, pêşî me hewce bû ku em serîlêdanek serverek bicîh bikin ku karibe daxwazên HTTP qebûl bike û wan yek bi yek beralî bike xebatkarê PHP-ê bêyî ku her carê bikuje.

Me dizanibû ku em dikarin serverek malperê bi PHP-ya paqij (PHP-PM) an jî bi dirêjkirina C (Swoole) binivîsin. Û her çend her rêbaz xwedan taybetmendiyên xwe ye, her du vebijark li me nebûn - me tiştek bêtir dixwest. Pêdiviya me bi tenê serverek webê hebû - me li bendê bû ku em çareseriyek bi dest bixin ku bikaribe me ji pirsgirêkên ku bi "destpêkek dijwar" a PHP-ê ve girêdayî ne xilas bike, ku di heman demê de dikare bi hêsanî ji bo serîlêdanên taybetî were adaptekirin û dirêj kirin. Ango pêdiviya me bi serverek serîlêdanê hebû.

Dikare Go bi vê yekê re bibe alîkar? Me dizanibû ku ew dikare ji ber ku ziman sepanan di nav binarên yekane de berhev dike; ew cross-platform e; Ji bo xebata bi HTTP-ê re modela xweya pir xweşik, pir xweşik û paralel (hevdemî) û pirtûkxaneyek bikar tîne; û di dawiyê de, bi hezaran pirtûkxane û entegrasyonên çavkaniya vekirî dê ji me re peyda bibin.

Zehmetiyên Têkelkirina Du Zimanên Bernamesaziyê

Berî her tiştî, pêdivî bû ku were destnîşankirin ka dê du an bêtir serlêdan çawa bi hevûdu re têkilî daynin.

Ji bo nimûne, bi kar tînin pirtûkxaneya hêja Alex Palaestras, gengaz bû ku bîranîn di navbera pêvajoyên PHP û Go de were parve kirin (wek mod_php di Apache de). Lê ev pirtûkxane xwedî taybetmendiyên ku karanîna wê ji bo çareserkirina pirsgirêka me sînordar dike.

Me biryar da ku em rêgezek cûda, hevpartir bikar bînin: danûstendina di navbera pêvajoyan de bi riya soketan / lûleyan ve ava bikin. Ev nêzîkatî di dehsalên borî de pêbawer îsbat kiriye û di asta pergala xebitandinê de baş xweştir bûye.

Ji bo destpêkê, me protokolek binary a hêsan ji bo veguheztina daneyan di navbera pêvajoyan û birêvebirina xeletiyên veguheztinê de çêkir. Di forma xweya herî hêsan de, ev celeb protokol dişibihe netstring с sernavê pakêta mezinahiya sabît (di doza me de 17 byte), ku agahdariya li ser celebê pakêtê, mezinahiya wê û maskek binary heye ku yekbûna daneyan kontrol bike.

Li aliyê PHP-ê me bikar anî fonksiyona pakkirinê, û li aliyê Go, pirtûkxane şîfrekirin/binary.

Ji me re xuya bû ku yek protokol ne bes e - û me şiyana bangkirinê lê zêde kir net/rpc go xizmetê rasterast ji PHP. Dûv re, vê yekê di pêşkeftinê de pir alîkariya me kir, ji ber ku me bi hêsanî dikarî pirtûkxaneyên Go-yê di serîlêdanên PHP-ê de yek bikin. Encama vê xebatê dikare, mînakî, di hilbera meya çavkaniya vekirî ya din de were dîtin Gorridge.

Belavkirina peywiran li ser gelek xebatkarên PHP-ê

Piştî bicihanîna mekanîzmaya danûstendinê, me dest pê kir ku li ser awayê herî bikêrhatî ji bo veguheztina peywiran li pêvajoyên PHP-ê bifikirin. Dema ku peywirek tê, servera serîlêdanê divê xebatkarek belaş hilbijêrin ku wê bicîh bîne. Ger xebatkarek/pêvajoyek bi xeletiyekê derkeve an jî "bimire", em jê xilas dibin û yekî nû li şûna wê diafirînin. Û heke xebatkar / pêvajo bi serfirazî qediya, em wê vedigerînin hewza karkerên ku ji bo pêkanîna karan hene.

RoadRunner: PHP ne ji bo mirinê, an jî Golang ji bo rizgarkirinê hatî çêkirin

Ji bo depokirina hewza karkerên çalak, me bikar anî kanala tampon, ji bo ku karkerên neçaverêkirî "mirî" ji hewzê derxînin, me mekanîzmayek ji bo şopandina xeletî û rewşa karkeran lê zêde kir.

Wekî encamek, me serverek PHP-ya xebitandinê peyda kir ku dikare hemî daxwazên ku di forma binary de têne pêşkêş kirin bişopîne.

Ji bo ku serîlêdana me wekî serverek malperê dest bi xebatê bike, diviya bû ku me standardek pêbawer a PHP-ê hilbijêrin ku her daxwazên HTTP-ê yên hatinî temsîl bike. Di doza me de, em tenê veguherînin net/http daxwaza ji Go to format PSR-7da ku ew bi piraniya çarçoveyên PHP-ê yên ku îro hene re hevaheng e.

Ji ber ku PSR-7 neguhêrbar tê hesibandin (hinek ji hêla teknîkî ve ne wusa ye), pêşdebir neçar in ku serîlêdanên ku di prensîbê de daxwazê ​​wekî saziyek gerdûnî nagirin binivîsin. Ev bi têgeha pêvajoyên PHP-ê yên demdirêj re xweş tê. Pêkanîna meya dawîn, ku hîna navê wê nehatiye kirin, bi vî rengî xuya bû:

RoadRunner: PHP ne ji bo mirinê, an jî Golang ji bo rizgarkirinê hatî çêkirin

Danasîna RoadRunner - servera serîlêdana PHP-ê ya performansa bilind

Karê ceribandina meya yekem paşvekêşana API-ê bû, ku bi awayekî periyodîk bêpêşbînî diqelişe (pir caran ji gelemperî). Her çend nginx di pir rewşan de bes bû jî, em bi rêkûpêk rastî 502 xeletiyan hatin ji ber ku me nekarî bi lez û bez pergalê ji bo zêdekirina barkirinê ya bendewarî hevseng bike.

Ji bo ku vê çareseriyê biguhezînin, me di destpêka sala 2018-an de servera serîlêdana xweya yekem PHP/Go bicîh kir. Û tavilê bandorek nedîtbar girt! Ne tenê me ji xeletiya 502 bi tevahî xilas kir, lê me karî hejmara serveran ji sê paran duyan kêm bikin, ji bo endezyar û rêveberên hilberê gelek drav û hebên serêşê teserûf bikin.

Di nîvê salê de, me çareseriya xwe baştir kir, ew li ser GitHub di bin lîsansa MIT-ê de weşand û navê wê kir. roadrunner, bi vî rengî leza xwe û karbidestiya wê ya bêhempa tekez dike.

Çawa RoadRunner dikare stûna pêşkeftina we baştir bike

Serîlêdana roadrunner destûr da me ku em net/http li aliyê Go-yê bikar bînin da ku verastkirina JWT-ê berî ku daxwaz bigihîje PHP-ê, û her weha WebSockets û dewleta tevhev a gerdûnî li Prometheus bi rê ve bibe.

Spas ji RPC-ya çêkirî, hûn dikarin API-ya her pirtûkxaneyên Go-yê ji bo PHP-ê bêyî nivîsandina pêlavên dirêjkirinê vekin. Ya girîngtir, bi RoadRunner re hûn dikarin serverên nû yên ne-HTTP bicîh bikin. Nimûne di PHP-ê de rêvebirên xebitandinê hene AWS Lambda, çêkirina şikestên rêza pêbawer, û tewra lê zêde dike gRPC ji bo sepanên me.

Bi alîkariya civakên PHP û Go, me aramiya çareseriyê baştir kir, di hin ceribandinan de performansa serîlêdanê heya 40 carî zêde kir, amûrên debugê çêtir kirin, bi çarçoweya Symfony re entegrasyonê pêk anîn, û piştgiriya HTTPS, HTTP/2 zêde kir, pêvekên, û PSR-17.

encamê

Hin kes hîn jî di nav têgihîştina PHP-ê de wekî zimanek hêdî, bêhêz tenê ji bo nivîsandina pêvekên ji bo WordPress-ê baş e têne girtin. Dibe ku ev kes bibêjin ku PHP xwedan sînorkirinek wusa ye: gava ku serîlêdan têra xwe mezin dibe, divê hûn zimanek "gihîştî" hilbijêrin û bingeha kodê ya ku di gelek salan de hatî berhev kirin ji nû ve binivîsin.

Ji van hemûyan re ez dixwazim bersiv bidim: dîsa bifikire. Em bawer dikin ku tenê hûn ji bo PHP-ê ti sînoran danîne. Hûn dikarin tevahiya jiyana xwe bi derbasbûna ji zimanekî bo zimanekî din derbas bikin, hewl bidin ku li gorî hewcedariyên xwe hevrêzek bêkêmasî bibînin, an jî hûn dikarin dest pê bikin ku zimanan wekî amûr bifikirin. Dibe ku kêmasiyên zimanekî mîna PHP-ê bi rastî bibe sedema serkeftina wî. Û eger hûn wê bi zimanekî din ên mîna Go re hev bikin, wê hingê hûn ê ji ya ku hûn bi karanîna yek zimanî sînordar bûne hilberên pir bi hêztir biafirînin.

Bi komek Go û PHP re xebitîn, em dikarin bibêjin ku em ji wan hez dikin. Em ne plan dikin ku yek ji bo yê din bikin qurban - berevajî vê, em ê li rêyên ku ji vê stûna dualî hîn bêtir nirx bistînin bigerin.

UPD: em pêşwaziya afirînerê RoadRunner û hev-nivîskarê gotara orjînal dikin - Lachesis

Source: www.habr.com

Add a comment