過去 10 年間、当社は Fortune 500 企業 およびユーザー数 500 人以下の企業向けのアプリケーションを開発してきました。これまで、当社のエンジニアは主に PHP を使用してバックエンドを開発してきました。しかし 2 年前、当社製品のパフォーマンスだけでなくスケーラビリティにも深刻な影響を与えるいくつかの問題が発生しました。そこで、当社は Golang (Go) を当社のテクノロジー スタックに導入しました。
ほぼ同時に、Go を使用すると大規模なアプリケーションを作成できるだけでなく、パフォーマンスが最大 40 倍向上することもわかりました。これにより、PHP で書かれた既存の製品を拡張し、両方の言語の長所を組み合わせて改良することができます。
Go と PHP の豊富な経験を通じて、それを実際の開発上の問題を解決するために使用する方法、およびそれを PHP Death Model を排除するツールに変える方法を説明します。いくつかの質問。
Web サーバーは純粋な PHP (PHP-PM) または C 拡張機能 (Swoole) で作成できることがわかっています。それぞれのアプローチには利点がありますが、どちらのオプションも私たちにとってはうまくいきませんでした。私はもっと何かが欲しかったのです。私たちは単なる Web サーバー以上のものを必要としていました。PHP の「再起動」に関連する問題を回避しながら、特定のアプリケーションに簡単に適応および拡張できるソリューションを求めていました。つまり、アプリケーションサーバーが必要です。
Go はこの問題の解決に役立つでしょうか?この言語がアプリケーションを単一のバイナリにコンパイルすること、クロスプラットフォームであること、HTTP を処理するために独自の並列処理モデル (同時実行性) とライブラリを使用すること、そして最終的には、より多くのオープン ソース ライブラリをプログラム。
まず、2 つ以上のアプリケーションが相互に通信する方法を決定する必要があります。
たとえば、Alex Palaestras の go-php ライブラリを使用すると、PHP と Go プロセス (Apache の mod_php など) の間でメモリ共有を実現できます。ただし、このライブラリの機能により、問題を解決するための使用が制限されます。
私たちは、ソケット/パイプラインを使用してプロセス間の対話を構造化するという、別のより一般的なアプローチを使用することにしました。このアプローチは過去 10 年間にわたってその信頼性が証明されており、オペレーティング システム レベルで適切に最適化されています。
まず、プロセス間でデータを交換し、送信エラーを処理するための単純なバイナリ プロトコルを作成しました。最も単純な形式では、このタイプのプロトコルは、固定サイズのパケット ヘッダー (この例では 17 バイト) を持つ netstring に似ています。ここで含まれる情報は、パケット タイプ、そのサイズ、およびバイナリ マスクです。データの整合性をチェックするために使用される情報。
PHP 側ではpack 関数 を使用し、Go 側では encoding/binary ライブラリを使用しました。
1 つのプロトコルは私たちにとって少し時代遅れになっており、net /rpc Go サービス を PHP から直接呼び出す機能を追加しました。この機能は、Go ライブラリを PHP アプリケーションに簡単に統合できるため、後の開発で非常に役立ちました。この作業の結果は、当社の別のオープンソース製品 Goridge で見ることができます。
バッファ チャネル を使用します。予期しない「デッド」ワーカー プロセスをプールに、エラーとワーカー プロセスのステータスを追跡するメカニズムを追加しました。
ついに、バイナリ形式でレンダリングされたあらゆるリクエストを処理できる、動作する PHP サーバーが完成しました。 アプリケーションが Web サーバーとして動作できるようにするには、受信 HTTP リクエストを処理するための信頼できる PHP 標準を選択する必要があります。この例では、単純な net/http リクエストを Goから PSR-7 形式に変換するだけで、現在利用可能な PHP フレームワークのほとんどと互換性があります。
PSR-7 は不変であると考えられているため (技術的に不変であるという人もいます)、開発者は原則としてリクエストをグローバル エンティティとして扱わないアプリケーションを作成する必要があります。これは、PHP 常駐プロセスの概念と完全に一致しています。最終的な実装 (まだ名前は付けられていません) は次のようになります:最初のテスト タスクは、定期的に (通常より頻繁に) 予測できないリクエストのバーストが発生する API バックエンドです。ほとんどの場合、nginx の機能で十分ですが、予想される負荷の増加に応じてシステムのバランスを迅速にとることができないため、502 エラーが発生することがよくあります。
この問題を解決するために、2018 年初めに最初の PHP/Go アプリケーション サーバーをデプロイしました。そしてすぐに驚くべき結果を達成しました! 502 エラーを完全に排除しただけでなく、サーバーの数を 3 分の 2 に減らし、大量のコストを節約し、エンジニアやプロダクト マネージャーの悩みを解決しました。
今年の半ばに、私たちはソリューションを改良し、#RoadRunner という名前で MIT ライセンスの下で GitHub 上でリリースし、その驚くべきスピードと効率性を強調しました。
RoadRunner を使用すると、Go 側でもミドルウェア net/http を使用できるようになります。リクエストが PHP に送信される前の JWT 検証、および Prometheus での WebSocket とグローバル集約状態の処理。
組み込み RPC のおかげで、拡張パッケージを作成しなくても、PHP で Go ライブラリの API を開くことができます。さらに、RoadRunner を使用すると、HTTP とは異なる新しいサーバーを展開できます。例には、PHP での AWS Lambda プロセッサの実行、強力なキュー セレクター、 の作成、さらにはアプリケーションへの gRPC の追加などが含まれます。
PHP と Go の両方を使用することで、ソリューションは着実に改善され、一部のテストではアプリケーションのパフォーマンスが 40 倍向上し、デバッグ ツールが改善され、Symfony フレームワークとの統合が可能になり、HTTPS、HTTP/2、プラグインのサポートが追加されました。そしてPSR-17。
一部の人々は依然として PHP の時代遅れの概念に縛られており、PHP は遅くて扱いにくい言語であり、WordPress でプラグインを作成する場合にのみ適していると考えています。これらの人々は、PHP には限界があるとまで言います。アプリケーションが十分に大きくなると、より「成熟した」言語を選択し、長年にわたって蓄積されたコード ベースを書き直さなければなりません。
これらの質問に対する私の答えは、「もう一度考えてください」です。 PHP に制限を設けているのはあなただけだと思います。自分のニーズに完全に一致する言語を見つけようとして、ある言語から別の言語に人生を移すこともできますし、言語をツールとして扱うこともできます。 PHP のような言語では、その想定される欠陥が成功の本当の理由である可能性があります。 Go などの別の言語と組み合わせると、1 つの言語を使用するよりも強力な製品を作成できます。
Go と PHP を同じ意味で使用した後、私たちはそれらが好きだと言えます。私たちは一方を犠牲にして他方を犠牲にするつもりはありません。代わりに、この二重アーキテクチャからより多くを引き出す方法を見つけるつもりです。
英語の元のアドレス: https://sudonull.com/post/6470-RoadRunner-PHP-is-not-created-to-die-or-Golang-to-the-rescue
翻訳アドレス: https://learnku.com/php/t/61733
推奨学習: 「PHP ビデオ チュートリアル 」
以上がスピードのために生まれた: PHP と Golang の組み合わせ - RoadRunnerの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。