socket_wsaprotocol_info_import est une opération au niveau du système avec un coût élevé d'appel. Il est recommandé de l'appeler uniquement si nécessaire, par exemple lorsque le service est initialisé ou lorsque la prise est réellement partagée entre les processus. La prise importée peut être mise en cache en mémoire pour éviter l'importation répétée du même descripteur:
$cache = [];
$hash = md5($info_string);
if (!isset($cache[$hash])) {
$cache[$hash] = socket_wsaprotocol_info_import($info_string);
}
$socket = $cache[$hash];
Si plusieurs processus de votre architecture d'application doivent partager des informations sur socket, évitez l'utilisation fréquente de fichiers ou de bases de données pour transférer des chaînes WSAPROTOCOL_INFO . Un transfert efficace entre les processus peut être réalisé grâce à des extensions de mémoire partagées de PHP (telles que SHMOP ou à utiliser Swoole \ Table ):
$table = new Swoole\Table(1024);
$table->column('info', Swoole\Table::TYPE_STRING, 512);
$table->create();
$table->set('socket_key', ['info' => $info_string]);
De cette façon, un autre processus peut rapidement lire à partir de la mémoire partagée sans accéder à des disques.
Pour l'importation de socket dans des scénarios de concurrence élevés, vous pouvez envisager d'utiliser un mécanisme asynchrone pour allouer la pression, tels que l'utilisation du processus d'importation de socket de coroutine en combinaison avec Swoole ou ReactPHP pour empêcher le blocage du fil principal.
go(function () use ($info_string) {
$socket = socket_wsaprotocol_info_import($info_string);
// Traitement de suivi
});
L'objectif ultime d'importer une prise est de le réutiliser, donc une méthode d'optimisation plus approfondie est de contrôler le cycle de vie du socket au niveau architectural. Par exemple, créez une prise dans le processus parent, puis transmettez-la au processus de l'enfant via le mécanisme WsaDuplicate de Windows, et ne l'initialisez qu'une seule fois.
Assurez-vous que le processus de l'enfant ne ferme pas la prise immédiatement après l'importation, mais rejoint le pool de connexion à usage multiple:
$socket_pool[] = socket_wsaprotocol_info_import($info_string);
// Vous pouvez suivre $socket_pool Obtenir une réutilisation
Le goulot d'étranglement des performances peut ne pas provenir de la fonction elle-même, mais des limitations des ressources du système d'exploitation (comme le nombre de poignées). Sur les systèmes Windows, les limites de poignée de socket peuvent être augmentées en ajustant les paramètres de registre. Dans le même temps, évitez les fuites de socket et assurez-vous que chaque prise importée est raisonnablement fermée après utilisation:
if (is_resource($socket)) {
socket_close($socket);
}
Lorsque socket_wsaprotocol_info_import est soupçonné d'être un goulot d'étranglement des performances, la connexion de sa situation chronophage est utilisée:
$start = microtime(true);
$socket = socket_wsaprotocol_info_import($info_string);
$duration = microtime(true) - $start;
error_log("Import duration: {$duration}s");
En conjonction avec le moniteur de performances de Windows (perfmon) pour afficher le réseau IO, gérer l'utilisation, la mémoire et autres ressources, afin d'évaluer de manière approfondie la cause profonde du problème.
Dans les grands services PHP, envisagez de concevoir un démon local léger (comme écrit en C ++ ou GO) qui maintient les descripteurs de socket et leur logique d'importation et d'exportation. PHP ne communique qu'à travers une interface concise, réduisant considérablement la complexité de la livraison de processus croisé. Par exemple:
$info_string = file_get_contents("http://gitbox.net/socket-info?id=123");
$socket = socket_wsaprotocol_info_import($info_string);
Simplifie la logique d'importation PHP via une interface de socket de domaine HTTP locale ou UNIX.