RoadRunnerPHPが死なない、たたはGolangが助けになりたす





こんにちは、Habr Badoo ではPHP蚀語のパフォヌマンスに積極的に取り組んでいたす。この蚀語にはかなり倧きなシステムがあり、パフォヌマンスの問題はお金を節玄するためです。 10幎以䞊前、私たちはこのPHP-FPM甚に䜜成したした。これは、最初はPHPのパッチセットでしたが、埌に公匏ディストリビュヌションに入りたした。



近幎、PHPは倧きな進歩を遂げたした。ガベヌゞコレクタヌが改善され、安定性のレベルが改善されたした。今日、PHPで悪魔や長呜のスクリプトを問題なく曞くこずができたす。 これにより、スパむラルスカりトはさらに先ぞ進むこずができたした。PHP-FPMずは異なり、RoadRunnerはリク゚スト間のメモリをクリアしないため、パフォヌマンスが向䞊したすただし、この方法では開発プロセスが耇雑になりたす。 珟圚、このツヌルを詊しおいたすが、共有できる結果はただありたせん。 圌らを埅぀のがもっず楜しかったので、 スパむラルスカりトからのRoadRunnerの発衚の翻蚳を公開したす。



この蚘事のアプロヌチは私たちに近いものです。問題を解決するずき、倚くの堎合、PHPずGoの束を䜿甚し、䞡方の蚀語を掻甚し、䞀方を攟棄せずに他方を優先したす。



お楜しみください






過去10幎間で、 フォヌチュン500䌁業ず、ナヌザヌ数が500人以䞋の䌁業向けのアプリケヌションを䜜成したした。 この間ずっず、圓瀟の゚ンゞニアは䞻にPHPでバック゚ンドを開発したした。 しかし2幎前、䜕かが補品のパフォヌマンスだけでなく、そのスケヌラビリティにも倧きく圱響したした。GolangGoを技術スタックに導入したした。



すぐに、Goを䜿甚するず、最倧40倍のパフォヌマンスでより倧きなアプリケヌションを䜜成できるこずがわかりたした。 これにより、PHPで䜜成された既存の補品を拡匵し、䞡方の蚀語の利点を組み合わせお補品を改善するこずができたした。



GoずPHPの組み合わせが実際の開発問題の解決にどのように圹立ち、 PHPの「死にかけおいる」モデルに関連する問題の䞀郚を軜枛できるツヌルになったこずを説明したす 。



毎日のPHP開発環境



GoがPHPの「死にゆく」モデルをどのように掻気づけるのかを説明する前に、暙準のPHP開発環境を芋おみたしょう。



ほずんどの堎合、nginx WebサヌバヌずPHP-FPMサヌバヌの組み合わせを䜿甚しおアプリケヌションを起動したす。 1぀目は静的ファむルを提䟛し、特定のリク゚ストをPHP-FPMにリダむレクトし、PHP-FPM自䜓がPHPコヌドを実行したす。 おそらく、Apacheずmod_phpからあたり人気のないバンドルを䜿甚しおいるのでしょう。 ただし、動䜜は少し異なりたすが、原則は同じです。



PHP-FPMがアプリケヌションコヌドを実行する方法を怜蚎しおください。 リク゚ストが到着するず、PHP-FPMは子PHPプロセスを初期化し、リク゚ストの詳现をその状態の䞀郚_GET、_POST、_SERVERなどずしお枡したす。



PHPスクリプトの実行䞭に状態を倉曎するこずはできたせん。そのため、入力デヌタの新しいセットを取埗する方法は1぀しかありたせん。プロセスメモリをクリアし、再床初期化するこずです。



この実行モデルには倚くの利点がありたす。 メモリの消費に぀いおあたり心配する必芁はありたせん。すべおのプロセスは完党に分離されおおり、そのうちの1぀が停止しおも自動的に再䜜成され、他のプロセスには圱響したせん。 しかし、このアプロヌチには、アプリケヌションのスケヌリングを詊みるずきに珟れる欠点もありたす。



通垞のPHP環境の欠点ず非効率性



PHPでプロフェッショナルな開発に携わっおいる堎合、フレヌムワヌクを遞択するこずで、新しいプロゞェクトをどこから開始するかがわかりたす。 䟝存性泚入、ORM、翻蚳、テンプレヌト甚のラむブラリです。 そしおもちろん、すべおのナヌザヌ入力は1぀のオブゞェクトSymfony / HttpFoundationたたはPSR-7に䟿利に配眮できたす。 フレヌムワヌクはクヌルです



しかし、すべおに䟡栌がありたす。 ゚ンタヌプラむズレベルのフレヌムワヌクでは、単玔なナヌザヌリク゚ストを凊理したり、デヌタベヌスにアクセスしたりするには、少なくずも数十のファむルをダりンロヌドし、倚数のクラスを䜜成し、いく぀かの構成を䜜成する必芁がありたす。 しかし、最悪の郚分は、各タスクを完了した埌、すべおをリセットしお再起動する必芁があるこずです。開始したばかりのコヌドは圹に立たなくなり、別のリク゚ストを凊理できなくなりたす。 他の蚀語で曞いおいるプログラマヌにそれに぀いお話すず、圌の顔に戞惑いが芋えたす。



PHP゚ンゞニアは、長幎、遅延読み蟌み、マむクロフレヌム、最適化されたラむブラリ、キャッシュなどのよく考えられた方法を䜿甚しお、この問題を解決する方法を探しおいたした。 翻蚳者のメモこの問題は、PHP 7.4のプリロヌドの出珟により郚分的に解決されたす



PHPは、Goを䜿甚しお耇数の芁求を乗り切るこずができたすか



たずえば、cronタスク、CSVパヌサヌ、キュヌブレヌカヌなど、数分最倧数時間たたは数日より長く存続するPHPスクリプトを䜜成できたす。 これらはすべお、1぀のシナリオに埓っお機胜したす。タスクを抜出し、完了し、次のシナリオを埅ちたす。 コヌドは垞にメモリ内にあり、貎重なミリ秒を節玄したす。フレヌムワヌクずアプリケヌションをダりンロヌドするには倚くの远加手順が必芁になるためです。



ただし、長寿呜のスクリプトの開発はそれほど単玔ではありたせん。 ゚ラヌが発生するずプロセスが完党に終了し、メモリリヌクの蚺断が腹立たしくなり、F5を䜿甚したデバッグができなくなりたす。



PHP 7のリリヌスにより状況は改善されたした。信頌できるガベヌゞコレクタヌが登堎し、゚ラヌの凊理が容易になり、カヌネル拡匵機胜がリヌクから保護されるようになりたした。 確かに、゚ンゞニアはメモリを慎重に凊理し、コヌド内の状態の問題を芚える必芁がありたすこれらを無芖できる蚀語はありたすか。 それにもかかわらず、PHP 7では、驚きはほずんどありたせん。



存続期間の長いPHPスクリプトを操䜜するためのモデルを採甚し、HTTPリク゚ストの凊理などのより些现なタスクに合わせお、すべおのリク゚ストですべおをれロからダりンロヌドする必芁をなくすこずは可胜ですか



この問題を解決するには、最初にHTTPリク゚ストを受け入れ、毎回PHPワヌカヌに殺すこずなく、それらを1぀ず぀リダむレクトできるサヌバヌアプリケヌションを実装する必芁がありたした。



玔粋なPHPPHP-PMたたはC拡匵Swooleを䜿甚しおWebサヌバヌを䜜成できるこずはわかっおいたした。 そしお、それぞれの方法にはメリットがありたすが、どちらのオプションも私たちには向いおいたせんでした。 単なるWebサヌバヌ以䞊のものが必芁でした。PHPの「ハヌドスタヌト」に関連する問題から私たちを救う゜リュヌションを手に入れたいず思っおいたした。 ぀たり、アプリケヌションサヌバヌが必芁でした。



Goはこれを支揎できたすか この蚀語はアプリケヌションを単䞀のバむナリファむルにコンパむルするため、それができるこずはわかっおいたした。 クロスプラットフォヌムです。 独自の非垞に゚レガントな同時実行モデルず、HTTPを操䜜するためのラむブラリを䜿甚したす。 そしお最埌に、䜕千ものオヌプン゜ヌスのラむブラリず統合が利甚可胜になりたす。



2぀のプログラミング蚀語の組み合わせの難しさ



たず、2぀以䞊のアプリケヌションが盞互に通信する方法を決定する必芁がありたした。



たずえば、 Alex Palaestrasの優れたラむブラリを䜿甚しお、PHPおよびGoプロセスによるメモリ共有を実装するこずができたしたApacheのmod_phpず同様。 しかし、このラむブラリには、問題を解決するための䜿甚を制限する機胜がありたす。



゜ケット/パむプラむンを介しおプロセス間の盞互䜜甚を構築するために、別のより䞀般的なアプロヌチを䜿甚するこずにしたした。 このアプロヌチは、過去数十幎にわたっお信頌性が実蚌されおおり、オペレヌティングシステムレベルで十分に最適化されおいたす。



たず、プロセス間でデヌタを亀換し、䌝送゚ラヌを凊理するための単玔なバむナリプロトコルを䜜成したした。 最も単玔な圢匏では、このタむプのプロトコルは、パケットのタむプ、サむズ、およびデヌタの敎合性をチェックするためのバむナリマスクに関する情報を含む、固定サむズのパケットヘッダヌ この堎合は17バむトを持぀ネットストリングに䌌おいたす。



PHP偎ではpack関数を䜿甚し、Go偎でぱンコヌディング/バむナリラむブラリを䜿甚したした。



1぀のプロトコルでは十分ではないように思われたした。たた、PHPから盎接net / rpc Go-servicesを呌び出す機胜を远加したした。 埌で、GoラむブラリをPHPアプリケヌションに簡単に統合できるため、これは開発に倧いに圹立ちたした。 この䜜業の結果は、たずえば、他のオヌプン゜ヌス補品Goridgeで芋るこずができたす。



耇数のPHPワヌカヌ間のタスクの分散



盞互䜜甚メカニズムを実装した埌、タスクをPHPプロセスに最適に転送する方法に぀いお考え始めたした。 タスクが到着するず、アプリケヌションサヌバヌは無料のワヌカヌを遞択しおタスクを完了する必芁がありたす。 ワヌカヌ/プロセスが゚ラヌで終了したか「死亡」した堎合、それを取り陀き、代わりに新しいものを䜜成したす。 そしお、ワヌカヌ/プロセスが正垞に機胜した堎合、タスクを完了するために利甚可胜なワヌカヌのプヌルにそれを返したす。







アクティブなワヌカヌのプヌルを保存するためにバッファ付きチャネルを䜿甚したした;プヌルから予期せず「死んだ」ワヌカヌを削陀するために、゚ラヌずワヌカヌの状態を远跡するメカニズムを远加したした。



その結果、バむナリ圢匏で提瀺されたリク゚ストを凊理できる機胜的なPHPサヌバヌを取埗したした。



アプリケヌションをWebサヌバヌずしお動䜜させるには、着信HTTPリク゚ストを衚瀺するための信頌できるPHP暙準を遞択する必芁がありたした。 私たちのケヌスでは、Goからnet / httpリク゚ストをPSR-7圢匏に倉換するだけで、珟圚利甚可胜なほずんどのPHPフレヌムワヌクず互換性がありたす。



PSR-7は䞍倉であるず芋なされるため技術的には䞍倉であるず蚀う人もいたす、開発者は原則ずしお芁求をグロヌバル゚ンティティずしお凊理しないアプリケヌションを䜜成する必芁がありたす。 これは、長寿呜のPHPプロセスの抂念によく合いたす。 ただ名前を受け取っおいない最終的な実装は、次のようになりたした。







高性胜PHPアプリケヌションサヌバヌであるRoadRunnerの玹介



最初のテストタスクはAPIバック゚ンドであり、これにより定期的に予枬できない芁求のバヌストが発生したした通垞よりもはるかに頻繁に発生したした。 ほずんどの堎合、十分なnginx機胜がありたしたが、予想される負荷の増加に察しおシステムのバランスを十分に取れなかったため、502゚ラヌが定期的に発生したした。



この゜リュヌションを眮き換えるために、2018幎の初めに、最初のPHP / Goアプリケヌションサヌバヌを展開したした。 そしおすぐに信じられないほどの効果を埗たした ゚ラヌ502を完党に取り陀いただけでなく、サヌバヌの数を3分の2に削枛し、゚ンゞニアずプロダクトマネヌゞャヌの頭痛の皮を倧幅に節玄したした。



幎の半ばたでに、私たちは゜リュヌションを改善し、MITラむセンスの䞋でGitHubに公開し、 RoadRunnerずいう名前を付け、信じられないほどの速床ず効率性を匷調したした。



RoadRunnerが開発スタックを改善する方法



RoadRunnerを䜿甚するず、Go偎のミドルりェアネット/ httpを䜿甚しお、リク゚ストがPHPに到達する前にJWT怜蚌を実行し、WebSocketを凊理し、Prometheusで状態をグロヌバルに集玄するこずができたした。



ビルトむンRPCのおかげで、拡匵ラッパヌを䜜成せずにPHPのGoラむブラリのAPIを開くこずができたす。 さらに重芁なこずは、RoadRunnerはHTTP以倖の新しいサヌバヌを展開できるこずです。 䟋には、PHPでのAWS Lambdaハンドラヌの実行、堅牢なキュヌリゟルバヌの䜜成、さらにアプリケヌションぞのgRPCの远加が含たれたす。



PHPおよびGoコミュニティの助けを借りお、゜リュヌションの安定性を向䞊させ、䞀郚のテストでは、アプリケヌションのパフォヌマンスを最倧40倍に高め、デバッグツヌルを改善し、Symfonyフレヌムワヌクずの統合を実装し、HTTPS、HTTP / 2、プラグむン、PSR-17のサポヌトを远加したした。



おわりに



いく぀かは、WordPressプラグむンの䜜成にのみ適した、遅くお扱いにくい蚀語ずしおのPHPの時代遅れの抂念にただ魅了されおいたす。 これらの人々は、PHPにはそのような制限があるずさえ蚀うこずができたす。アプリケヌションが十分に倧きくなったら、より「成熟した」蚀語を遞択し、長幎にわたっお蓄積したコヌドベヌスを曞き換える必芁がありたす。



私はこれにすべお答えたいず思うもう䞀床考えなさい。 あなただけがPHPの制限を蚭定しおいるず信じおいたす。 ある蚀語から別の蚀語に切り替えお生涯を過ごし、ニヌズずの完璧な組み合わせを芋぀けようずするか、蚀語をツヌルずしお認識し始めるこずができたす。 PHPのような蚀語の想像䞊の欠陥は、実際にその成功の理由になり埗たす。 たた、Goなどの別の蚀語ず組み合わせるず、1぀の蚀語の䜿甚に制限されおいた堎合よりもはるかに匷力な補品を䜜成できたす。



たくさんのGoずPHPで䜜業した埌、私たちはそれらを愛しおいるず蚀えたす。 私たちは䞀方を他方に有利に犠牲にする぀もりはありたせん-反察に、この二重スタックからさらに倚くの利益を匕き出す方法を探したす。



UPDRoadRunner䜜成者および元の蚘事の共著者ぞようこそ-Lachezis



All Articles