RoadRunner: PHP pa bati pou mouri, oswa Golang pou sekou

RoadRunner: PHP pa bati pou mouri, oswa Golang pou sekou

Hey Habr! Nou aktif nan Badoo ap travay sou pèfòmans PHP, depi nou gen yon sistèm jistis gwo nan lang sa a ak pwoblèm nan pèfòmans se yon pwoblèm ekonomize lajan. Plis pase dis ane de sa, nou te kreye PHP-FPM pou sa a, ki nan premye te yon seri plak pou PHP, epi pita te antre nan distribisyon ofisyèl la.

Nan dènye ane yo, PHP te fè gwo pwogrè: pèseptè fatra a amelyore, nivo estabilite a ogmante - jodi a ou ka ekri demon ak script ki dire lontan nan PHP san okenn pwoblèm. Sa a te pèmèt Spiral Scout ale pi lwen: RoadRunner, kontrèman ak PHP-FPM, pa netwaye memwa ant demann, ki bay yon benefis pèfòmans adisyonèl (byenke apwòch sa a konplike pwosesis devlopman). Kounye a n ap fè eksperyans ak zouti sa a, men nou poko gen okenn rezilta pou nou pataje. Pou fè tann yo plis plezi, nou pibliye tradiksyon anons RoadRunner soti nan Spiral Scout.

Apwòch la soti nan atik la se tou pre nou: lè rezoud pwoblèm nou yo, nou menm tou nou pi souvan itilize yon pakèt moun sou PHP ak Go, jwenn benefis yo nan tou de lang epi yo pa abandone youn an favè lòt la.

Amize!

Nan dis dènye ane yo, nou te kreye aplikasyon pou konpayi yo nan lis la Fortune 500, ak pou biznis ki gen yon odyans ki pa plis pase 500 itilizatè. Pandan tout tan sa a, enjenyè nou yo te devlope backend la sitou nan PHP. Men, de zan de sa, yon bagay te gen yon gwo enpak pa sèlman sou pèfòmans pwodwi nou yo, men tou sou évolutivité yo - nou te prezante Golang (Ale) nan pil teknoloji nou an.

Prèske imedyatman, nou dekouvri ke Go pèmèt nou bati pi gwo aplikasyon ak amelyorasyon pèfòmans jiska 40 fwa. Avèk li, nou te kapab pwolonje pwodwi PHP ki deja egziste nou yo, amelyore yo pa konbine benefis tou de lang yo.

Nou pral di w kouman konbinezon Go ak PHP ede rezoud pwoblèm devlopman reyèl ak ki jan li te tounen yon zouti pou nou ki ka debarase m de kèk nan pwoblèm ki asosye ak Modèl PHP mouri.

Anviwònman devlopman PHP chak jou ou

Anvan nou pale sou fason ou ka itilize Go pou reviv modèl PHP mouri a, ann gade nan anviwònman devlopman PHP default ou.

Nan pifò ka yo, ou kouri aplikasyon w lan lè l sèvi avèk yon konbinezon de sèvè entènèt nginx ak sèvè PHP-FPM la. Ansyen an sèvi fichye estatik ak redireksyon demann espesifik nan PHP-FPM, pandan y ap PHP-FPM tèt li egzekite kòd PHP. Ou ka itilize konbinezon mwens popilè Apache ak mod_php. Men, byenke li travay yon ti kras diferan, prensip yo se menm bagay la.

Ann pran yon gade nan ki jan PHP-FPM egzekite kòd aplikasyon an. Lè yon demann vini, PHP-FPM inisyalize yon pwosesis pitit PHP epi li pase detay demann lan kòm yon pati nan eta li (_GET, _POST, _SERVER, elatriye).

Eta a pa ka chanje pandan ekzekisyon PHP script, kidonk gen yon sèl fason pou jwenn yon nouvo seri done antre: pa netwaye memwa pwosesis la epi re-inisyalize li.

Modèl ekzekisyon sa a gen anpil avantaj. Ou pa bezwen enkyete twòp sou konsomasyon memwa, tout pwosesis yo konplètman izole, epi si youn nan yo "mouri", li pral otomatikman rkree epi li pa pral afekte rès la nan pwosesis yo. Men, apwòch sa a tou gen dezavantaj ki parèt lè w ap eseye echèl aplikasyon an.

Dezavantaj ak inefikasite nan yon anviwònman PHP regilye

Si ou se yon pwomotè PHP pwofesyonèl, Lè sa a, ou konnen ki kote yo kòmanse yon nouvo pwojè - ak chwa pou yo yon fondasyon. Li konsiste de bibliyotèk piki depandans, ORM, tradiksyon ak modèl. Epi, nan kou, tout opinyon itilizatè yo ka fasilman mete nan yon sèl objè (Symfony/HttpFoundation oswa PSR-7). Kad yo fre!

Men, tout bagay gen pri li yo. Nan nenpòt kad nan nivo antrepriz, pou trete yon demann itilizatè senp oswa aksè nan yon baz done, ou pral oblije chaje omwen plizyè douzèn fichye, kreye anpil klas ak analize plizyè konfigirasyon. Men, bagay ki pi mal la se ke apre w fin ranpli chak travay, w ap bezwen reset tout bagay epi kòmanse sou: tout kòd la ou jis inisye vin initil, ak èd li ou pa pral trete yon lòt demann ankò. Di sa a nenpòt pwogramè ki ekri nan kèk lòt lang, epi ou pral wè dezòd sou figi l '.

Enjenyè PHP yo te chèche fason yo rezoud pwoblèm sa a pou plizyè ane, lè l sèvi avèk teknik entelijan loading parese, microframeworks, bibliyotèk optimize, kachèt, elatriye Men, nan fen a, ou toujou gen Reyajiste aplikasyon an antye epi kòmanse ankò, ankò e ankò. (Nòt tradiktè a: pwoblèm sa a pral pasyèlman rezoud ak avènement de précharge nan PHP 7.4)

Èske PHP ak Go siviv plis pase yon demann?

Ou ka ekri script PHP ki viv pi lontan pase kèk minit (jiska èdtan oswa jou): pou egzanp, travay cron, analizeur CSV, disjoncteur keu. Yo tout travay dapre menm senaryo a: yo rekipere yon travay, egzekite li, epi tann pou pwochen an. Kòd la rete nan memwa tout tan tout tan an, ekonomize milisgond presye paske gen anpil etap adisyonèl ki nesesè pou chaje kad la ak aplikasyon an.

Men, devlope scripts ki dire lontan pa fasil. Nenpòt erè konplètman touye pwosesis la, dyagnostik fwit memwa se an kòlè, ak debogaj F5 pa posib ankò.

Sitiyasyon an amelyore ak lage PHP 7: yon pèseptè fatra serye te parèt, li te vin pi fasil pou jere erè, ak ekstansyon nwayo yo kounye a se prèv koule. Se vre, enjenyè toujou bezwen fè atansyon ak memwa epi yo dwe okouran de pwoblèm eta nan kòd (èske gen yon lang kote ou ka inyore bagay sa yo?). Toujou, PHP 7 gen mwens supriz nan magazen pou nou.

Èske li posib pou pran modèl travay ak script PHP ki dire lontan, adapte li nan travay plis trivial tankou trete demann HTTP, epi kidonk debarase m de nesesite pou chaje tout bagay soti nan grafouyen ak chak demann?

Pou rezoud pwoblèm sa a, nou te premye bezwen aplike yon aplikasyon sèvè ki ta ka aksepte demann HTTP epi redireksyon yo youn pa youn nan travayè PHP a san yo pa touye li chak fwa.

Nou te konnen ke nou te kapab ekri yon sèvè entènèt nan pi PHP (PHP-PM) oswa lè l sèvi avèk yon ekstansyon C (Swoole). Ak byenke chak metòd gen pwòp baz byenfonde li yo, tou de opsyon pa t 'kostim nou - nou te vle yon bagay plis. Nou te bezwen plis pase jis yon sèvè entènèt - nou te espere jwenn yon solisyon ki ta ka sove nou anba pwoblèm ki asosye ak yon "kòmansman difisil" nan PHP, ki an menm tan an ta ka fasil adapte ak pwolonje pou aplikasyon espesifik. Sa vle di, nou te bezwen yon sèvè aplikasyon.

Èske Go ka ede ak sa a? Nou te konnen li te kapab paske lang lan konpile aplikasyon nan binè sèl; li se kwa-platfòm; sèvi ak pwòp modèl pwosesis paralèl li yo (konkou) ak yon bibliyotèk pou travay ak HTTP; epi finalman, plizyè milye bibliyotèk ouvè ak entegrasyon yo pral disponib pou nou.

Difikilte pou konbine de langaj pwogramasyon

Premye a tout, li te nesesè yo detèmine ki jan de oswa plis aplikasyon yo pral kominike youn ak lòt.

Pou egzanp, lè l sèvi avèk ekselan bibliyotèk Alex Palaestras, li te posib yo pataje memwa ant PHP ak Go pwosesis (menm jan ak mod_php nan Apache). Men, bibliyotèk sa a gen karakteristik ki limite itilizasyon li pou rezoud pwoblèm nou an.

Nou deside sèvi ak yon apwòch diferan, ki pi komen: bati entèraksyon ant pwosesis atravè priz / tiyo. Apwòch sa a te pwouve yo dwe serye sou deseni ki sot pase yo e li te byen optimize nan nivo sistèm operasyon an.

Pou kòmanse, nou te kreye yon pwotokòl binè senp pou fè echanj done ant pwosesis ak manyen erè transmisyon. Nan fòm ki pi senp li yo, kalite pwotokòl sa a sanble ak netstring с fiks gwosè pake header (nan ka nou an 17 bytes), ki gen enfòmasyon sou kalite pake a, gwosè li yo ak yon mask binè yo tcheke entegrite nan done yo.

Sou bò PHP nou te itilize fonksyon pake, ak sou bò Go, bibliyotèk la kodaj/binè.

Li te sanble pou nou ke yon pwotokòl pa t ase - epi nou te ajoute kapasite nan rele net/rpc ale sèvis ki sòti dirèkteman nan PHP. Apre sa, sa te ede nou anpil nan devlopman, paske nou te kapab byen entegre bibliyotèk Go nan aplikasyon PHP. Rezilta travay sa a ka wè, pou egzanp, nan lòt pwodwi sous ouvè nou an Goridge.

Distribiye travay atravè plizyè travayè PHP

Apre aplike mekanis entèraksyon an, nou te kòmanse reflechi sou fason ki pi efikas pou transfere travay nan pwosesis PHP. Lè yon travay rive, sèvè aplikasyon an dwe chwazi yon travayè gratis pou egzekite li. Si yon travayè/pwosesis sòti ak yon erè oswa "mouri", nou debarase m de li epi kreye yon nouvo pou ranplase li. Epi si travayè/pwosesis la fini avèk siksè, nou retounen li nan rezèvwa travayè ki disponib pou fè travay yo.

RoadRunner: PHP pa bati pou mouri, oswa Golang pou sekou

Pou estoke pisin nan travayè aktif, nou te itilize chanèl tanpon, pou retire travayè "mouri" san atann nan pisin lan, nou te ajoute yon mekanis pou swiv erè ak eta travayè yo.

Kòm yon rezilta, nou te resevwa yon sèvè PHP k ap travay ki kapab trete nenpòt demann prezante nan fòm binè.

Pou aplikasyon nou an te kòmanse travay kòm yon sèvè entènèt, nou te oblije chwazi yon estanda PHP serye pou reprezante nenpòt demann HTTP fèk ap rantre. Nan ka nou an, nou jis transfòme net/http demann soti nan Ale nan fòma Lakay.pst-7konsa ke li konpatib ak pi fò nan kad PHP ki disponib jodi a.

Paske PSR-7 konsidere kòm imuiabl (kèk ta di teknikman li pa), devlopè yo dwe ekri aplikasyon ki pa trete demann lan kòm yon antite mondyal nan prensip. Sa a adapte byen ak konsèp nan pwosesis PHP ki dire lontan. Enplemantasyon final nou an, ki poko nonmen, te sanble ak sa a:

RoadRunner: PHP pa bati pou mouri, oswa Golang pou sekou

Prezante RoadRunner - sèvè aplikasyon PHP segondè pèfòmans

Premye travay tès nou an se te yon backend API, ki detanzantan pete enprevizib (pi souvan pase nòmal). Malgre ke nginx te ase nan pifò ka yo, nou te rankontre regilyèman 502 erè paske nou pa t 'kapab balanse sistèm lan ase byen vit pou ogmantasyon espere nan chaj.

Pou ranplase solisyon sa a, nou te deplwaye premye sèvè aplikasyon PHP/Go nou an nan kòmansman 2018. Epi imedyatman te resevwa yon efè enkwayab! Non sèlman nou te debarase m de erè 502 la nèt, men nou te kapab redwi kantite serveurs pa de tyè, ekonomize anpil lajan ak grenn tèt fè mal pou enjenyè ak manadjè pwodwi yo.

Nan mitan ane a, nou te amelyore solisyon nou an, nou te pibliye l sou GitHub anba lisans MIT epi nou te ba l non. ROADRUNNER, konsa mete aksan sou vitès enkwayab li yo ak efikasite.

Ki jan RoadRunner ka amelyore pil devlopman ou

Aplikasyon ROADRUNNER pèmèt nou sèvi ak Middleware net/http sou bò Go pou fè verifikasyon JWT anvan demann lan rive nan PHP, osi byen ke jere WebSockets ak eta totalman globalman nan Prometheus.

Mèsi a RPC entegre a, ou ka louvri API nenpòt bibliyotèk Go pou PHP san w pa ekri ekstansyon wrappers. Sa ki pi enpòtan, ak RoadRunner ou ka deplwaye nouvo sèvè ki pa HTTP. Egzanp yo gen ladan yo kouri okipe nan PHP AWS Lambda, kreye brekè keu serye, e menm ajoute gRPC nan aplikasyon nou yo.

Avèk èd nan kominote PHP ak Go, nou amelyore estabilite solisyon an, ogmante pèfòmans aplikasyon an jiska 40 fwa nan kèk tès, amelyore zouti debogaj, aplike entegrasyon ak kad Symfony, epi ajoute sipò pou HTTPS, HTTP/2, grefon, ak PSR-17.

Konklizyon

Gen kèk moun ki toujou kenbe nan nosyon an demode nan PHP kòm yon lang dousman, difisil sèlman bon pou ekri grefon pou WordPress. Moun sa yo ta ka menm di ke PHP gen yon limit konsa: lè aplikasyon an vin gwo ase, ou dwe chwazi yon lang ki pi "matirite" epi reekri baz kòd la akimile pandan plizyè ane.

Pou tout sa mwen vle reponn: reflechi ankò. Nou kwè se sèlman ou mete nenpòt restriksyon pou PHP. Ou ka pase tout lavi w ap fè tranzisyon soti nan yon lang nan yon lòt, ap eseye jwenn match pafè a pou bezwen ou yo, oswa ou ka kòmanse panse a lang kòm zouti. Sipoze defo yon lang tankou PHP ka aktyèlman rezon ki fè siksè li. Men, si ou konbine li ak yon lòt lang tankou Go, Lè sa a, ou pral kreye pwodwi pi pwisan pase si ou te limite a itilize nenpòt lang.

Lè nou te travay ak yon pakèt Go ak PHP, nou ka di ke nou renmen yo. Nou pa planifye pou sakrifye youn pou lòt - okontrè, nou pral chèche fason pou jwenn menm plis valè nan pil doub sa a.

UPD: nou akeyi kreyatè RoadRunner ak ko-otè atik orijinal la - Lachesis

Sous: www.habr.com

Add nouvo kòmantè