受信バッファーが小さすぎると、 socket_recvmsgに頻繁に呼び出され、システムが頻繁に呼び出されます。バッファが大きすぎる場合、メモリを無駄にする可能性があります。アプリケーションシナリオに従ってバッファサイズを調整することをお勧めします。
<span><span><span class="hljs-variable">$buf_size</span></span><span> = </span><span><span class="hljs-number">8192</span></span><span>; </span><span><span class="hljs-comment">// パケットサイズとスループットに従って調整します</span></span><span>
</span><span><span class="hljs-variable">$msg</span></span><span> = </span><span><span class="hljs-title function_ invoke__">socket_recvmsg</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>, </span><span><span class="hljs-variable">$buf_size</span></span><span>);
</span></span>さまざまなバッファーサイズでスループットとレイテンシをテストすることは、最適化の重要なステップです。
ReceiverがSocket_RecvMSGが呼び出されるたびに1つの小さなメッセージのみを読み取る場合、関数呼び出しの数とCPUコンテキストスイッチングの数が増加します。
解決:
可能であれば、複数のメッセージを一緒に送信します。
受信側では、一度にデータを読んでから開梱してみてください。
PHPでは、 socket_recvmsgは毎回データをPHP変数にコピーします。最適化のため:
参照パスを使用するか、基礎となるバッファを直接処理してください。
変数を最初に読み取り、次に別の配列に転送するなど、繰り返しコピーを複数回避けてください。
高性能要件については、PHP拡張またはFFIを検討してメモリを直接操作できます。
異なるソケットタイプとプロトコルは、パフォーマンスに大きな影響を与えます。
通常、UDPソケットは、小さなメッセージシナリオではTCPよりも効率的です。
TCPソケットは、大量のトラフィックや信頼できる送信に適していますが、ナグルアルゴリズムが遅延を引き起こす可能性があることに注意してください。
TCPソケットの場合、ナグルアルゴリズムを無効にすることができます。
<span><span><span class="hljs-title function_ invoke__">socket_set_option</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>, SOL_TCP, TCP_NODELAY, </span><span><span class="hljs-number">1</span></span><span>);
</span></span>アプリケーションが高い並行性シナリオにある場合は、たとえば、ブロッキング操作を最小限に抑えるようにしてください。
受信ループでSleep()を使用しないでください。
Socket_SelectまたはStream_Selectを使用して、単一のsocket_recvmsgでブロックする代わりに複数のソケットをリッスンします。
大規模なネットワークアプリケーションの場合、 LibeventやReactPhpの使用などのイベント駆動型モデルは、データの到着イベントをより効率的に処理できます。
このアプローチは、ポーリングとアイドルの待機を減らし、CPUの使用とスループットを改善します。
socket_recvmsgパフォーマンスを最適化するためのコアアイデアは次のとおりです。
非ブロッキングモード+イベント駆動型。
妥当なバッファサイズとバッチ読み取り。
データのコピーを削減します。
適切なソケットタイプとプロトコルを選択します。
システムコールのブロックを避けてください。
上記の方法を包括的に適用することにより、 Socket_RecvMSGのパフォーマンスは、特に高い並行性と大規模なデータボリュームシナリオで大幅に改善できます。