socket_wsaprotocol_info_importは、通話コストが高いシステムレベルの操作です。サービスが初期化されたときやソケットが実際にプロセス間で共有されるときなど、必要に応じてその場合にのみ呼び出すことをお勧めします。インポートされたソケットは、同じ記述子の繰り返しのインポートを避けるためにメモリでキャッシュできます。
$cache = [];
$hash = md5($info_string);
if (!isset($cache[$hash])) {
$cache[$hash] = socket_wsaprotocol_info_import($info_string);
}
$socket = $cache[$hash];
アプリケーションアーキテクチャの複数のプロセスがソケット情報を共有する必要がある場合は、ファイルまたはデータベースを頻繁に使用してWSAProtoCol_Info文字列を転送しないようにしてください。プロセス間の効率的な転送は、PHPの共有メモリ拡張機能( ShmopやSwoole \ Tableの使用など)を通じて達成できます。
$table = new Swoole\Table(1024);
$table->column('info', Swoole\Table::TYPE_STRING, 512);
$table->create();
$table->set('socket_key', ['info' => $info_string]);
これにより、別のプロセスがディスクにアクセスすることなく共有メモリからすばやく読み取ることができます。
高い並行性シナリオでのソケットのインポートの場合、非同期メカニズムを使用して圧力を割り当てることを検討できます。たとえば、 SwooleまたはReactPhpと組み合わせてソケットのインポートプロセスを使用してメインスレッドのブロックを防ぐなどです。
go(function () use ($info_string) {
$socket = socket_wsaprotocol_info_import($info_string);
// フォローアップ処理
});
ソケットをインポートするという究極の目標は、それを再利用することです。そのため、より徹底的な最適化方法は、アーキテクチャレベルでソケットライフサイクルを制御することです。たとえば、親プロセスにソケットを作成し、WindowsのWSADUPLICATESOCKESTメカニズムを介して子プロセスに渡し、1回のみを初期化します。
子どものプロセスがインポート後すぐにソケットを閉じないようにし、複数の使用のために接続プールに結合することを確認してください。
$socket_pool[] = socket_wsaprotocol_info_import($info_string);
// からフォローアップできます $socket_pool 再利用してください
パフォーマンスボトルネックは、関数自体からではなく、オペレーティングシステムのリソースの制限(ハンドルの数など)から来る場合があります。 Windowsシステムでは、レジストリパラメーターを調整することにより、ソケットのハンドル制限を増やすことができます。同時に、ソケットの漏れを避け、使用後に輸入された各ソケットが合理的に閉じられていることを確認してください。
if (is_resource($socket)) {
socket_close($socket);
}
socket_wsaprotocol_info_importがパフォーマンスのボトルネックであると疑われる場合、その時間のかかる状況を記録することが使用されます。
$start = microtime(true);
$socket = socket_wsaprotocol_info_import($info_string);
$duration = microtime(true) - $start;
error_log("Import duration: {$duration}s");
Windowsのパフォーマンスモニター(Perfmon)と組み合わせて、ネットワークIOを表示し、使用、メモリ、その他のリソースを処理して、問題の根本原因を包括的に評価します。
大規模なPHPサービスでは、ソケット記述子とそのインポートおよびエクスポートロジックを維持する軽量ローカルデーモン(C ++またはGOで書かれているなど)の設計を検討してください。 PHPは、簡潔なインターフェイスを介してのみ通信し、クロスプロセス配信の複雑さを大幅に削減します。例えば:
$info_string = file_get_contents("http://gitbox.net/socket-info?id=123");
$socket = socket_wsaprotocol_info_import($info_string);
ローカルHTTPサービスまたはUNIXドメインソケットインターフェイスを介して、PHPのインポートロジックを簡素化します。