SOCKET_SET_BLOCK Une fois que Socket est réglé sur le mode de blocage, les opérations IO (telles que socket_read , socket_write ) bloqueront le processus ou le thread actuel jusqu'à ce que la lecture des données soit terminée ou que l'écriture soit réussie. Ceci est très simple et efficace dans les scénarios monomoder ou à faible monnaie, mais dans les scénarios à haut niveau, les risques se reflètent principalement dans les points suivants:
Le blocage provoque une occupation des ressources <br> Le mode de blocage fera un instant le programme qui gère une demande incapable de continuer à exécuter l'exécution, en particulier lorsque le réseau est retardé ou que le pair répond lentement, le processus "collé" au stade IO, provoquant l'occupation d'un grand nombre de processus et des ressources.
Diminution du débit, augmentation de la latence de réponse <br> Lorsqu'un grand nombre de connexions sont bloquées, le serveur ne peut pas traiter de nouvelles demandes de connexion à temps, ce qui entraîne un temps de réponse plus long et une pire expérience utilisateur.
Le nombre de threads / processus est limité <br> La capacité de concurrence du serveur est limitée par le nombre de threads ou de processus disponibles. Les opérations de blocage rendent ces fils ou processus dans un état d'attente, ce qui est très facile à épuiser le pool de threads.
Risque de blocage <br> Si la concurrence pour les ressources mutuellement exclusives est impliquée lors du blocage et de l'attente, il est facile de provoquer des blocages et de provoquer un programme coincé.
En appelant Socket_Set_NonBlock pour définir Socket en mode non bloquant, les opérations IO ne bloqueront pas le processus actuel, mais reviendront immédiatement. Combiné avec des mécanismes pilotés par des événements (tels que SELECT , Poll ou Libevent dans les extensions de PHP) peut efficacement améliorer les capacités de traitement simultanées.
<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($socket, '0.0.0.0', 8080);
socket_listen($socket);
socket_set_nonblock($socket);
while (true) {
$client = @socket_accept($socket);
if ($client === false) {
// Pas de nouvelle connexion,Continuer la boucle
usleep(10000); // Faire une pause,réduireCPUOccupation
continue;
}
// Au client socket Définir également le non-bloquant
socket_set_nonblock($client);
// Lors de la lecture ou de l'écriture de données,Combiné socket_select Statut d'écoute
}
?>
Socket_Select peut écouter l'état de lecture et d'écriture de plusieurs prises, éviter de bloquer une seule connexion et améliorer l'efficacité du serveur pour traiter plusieurs connexions.
<?php
$read = [$socket];
$write = null;
$except = null;
if (socket_select($read, $write, $except, 0, 200000)) {
foreach ($read as $readSocket) {
if ($readSocket === $socket) {
$client = socket_accept($socket);
socket_set_nonblock($client);
// Ajouter pour écouter
} else {
$data = socket_read($readSocket, 1024);
if ($data === false || $data === '') {
socket_close($readSocket);
// Supprimer de la liste de la liste
} else {
// Traitement des données
}
}
}
}
?>
À l'aide de cadres asynchrones tels que Swoole et ReactPHP, le blocage peut être complètement évité, et un grand nombre de connexions simultanées peuvent être traitées de manière asynchrone, améliorant considérablement les performances.
<?php
use Swoole\Coroutine\Http\Server;
$server = new Server("0.0.0.0", 9501);
$server->handle('/', function ($request, $response) {
$response->end("Hello, Swoole!");
});
$server->start();
?>
Utilisez raisonnablement le traitement multiproce ou multi-thread pour attribuer des opérations de blocage à des threads ou processus de travailleurs indépendants pour éviter le blocage du thread principal.
Points de risque | Mesures de réponse |
---|---|
Le blocage provoque le processus d'attendre l'utilisation des ressources | Utiliser le mode non bloquant ou le pilote d'événement |
La latence de réponse et la chute de débit | Utilisez socket_select pour écouter plusieurs connexions |
Pool de filetage épuisé | Utilisez des pools multi-thread / multi-processus pour partager le stress |
Risque de blocage | Concevoir une stratégie d'accès aux ressources raisonnable pour éviter les impasses mutuellement exclusives |
Dans un environnement à forte concurrence, essayez d'éviter d'utiliser des prises de blocage et d'utiliser rationnel des modèles non bloqués et axés sur les événements et des cadres asynchrones pour assurer le fonctionnement efficace et stable des programmes PHP.