#. 🎜 🎜#Le modèle de réacteur, également appelé modèle de conception de réacteur, est un modèle de conception d'événements permettant de traiter les demandes de service soumises simultanément à un ou plusieurs processeurs de service. Lorsque les requêtes arrivent, ces requêtes sont démultiplexées et distribuées aux processeurs de requêtes correspondants via le processeur de service. Le modèle Reactor se compose principalement de deux parties principales : le réacteur et le gestionnaire de processeur, comme le montre la figure ci-dessous. Ils sont responsables des éléments suivants :Le réacteur Le modèle de conception est un modèle de gestion d'événements permettant de gérer les demandes de service fournies simultanément à un gestionnaire de service par une ou plusieurs entrées. Le gestionnaire de service démultiplexe ensuite les demandes entrantes et les distribue de manière synchrone aux gestionnaires de demandes associés.
Dans la plupart des scénarios, le traitement d'une requête réseau comporte les étapes suivantes :Pour le mode Reactor, chaque fois qu'un événement est entré sur le serveur, le gestionnaire de service transmettra (enverra ) au gestionnaire correspondant pour traitement. Trois rôles définis dans le modèle Reactor :① read : lire à partir du socket Obtenir des données.
② décodage : Décodage, les données sur le réseau sont transmises sous forme d'octets. Pour obtenir la vraie requête, vous devez décoder
③ calculer : Calcul, c'est-à-dire traitement métier.
④ encodage : Encodage, les données sur le réseau sont transmises sous forme d'octets, c'est-à-dire que le socket ne reçoit que des octets, un encodage est donc nécessaire.
⑤ send : Envoyer les données de réponse
Le Reactor est chargé de surveiller et de distribuer les événements, et de les dispatcher vers les Handlers correspondants. Les nouveaux événements incluent l'établissement de la connexion prêt, la lecture prête, l'écriture prête, etc. Accepteur : Demande au connecteur de gérer les nouvelles connexions du client. Une fois que Reactor a reçu l'événement de connexion du client, il le transmet à Acceptor, qui reçoit la connexion du client, crée le gestionnaire correspondant et enregistre ce gestionnaire auprès de Reactor. Handler : Processeur de requêtes, responsable du traitement des événements, se liant aux événements, effectuant des tâches de lecture/écriture non bloquantes, complétant la lecture du canal et écrivant les résultats après avoir terminé le traitement de la logique métier. la chaîne. Les pools de ressources disponibles peuvent être gérés.Le modèle est à peu près tel qu'illustré ci-dessous : Pour les requêtes de lecture/écriture, le modèle Reactor est comme suit Traitement du processus :
1.1.1.1. ) Le thread Reactor écoute l'événement via select et le distribue via Dispatch après avoir reçu l'événement
(3) S'il s'agit d'un événement de lecture et d'écriture IO, Reactor transmettra l'événement à le gestionnaire actuellement connecté pour le traitement
① Performances : ne distinguant que les composants dans le code, l'opération globale est toujours monothread, incapable d'utiliser pleinement les ressources du processeur et la partie traitement métier du gestionnaire n'est pas asynchrone. Un Reactor doit être responsable du traitement des demandes de connexion et de la lecture. et l'écriture. De manière générale, le traitement des demandes de connexion est très rapide, mais le traitement des demandes de lecture et d'écriture implique un traitement de logique métier, qui est relativement lent. Étant donné que Reactor traite les requêtes de lecture et d'écriture, les autres requêtes seront bloquées, ce qui peut facilement entraîner des goulots d'étranglement dans les performances du système.
② Fiabilité : une fois que le thread Reactor est interrompu de manière inattendue ou entre dans une boucle infinie, l'ensemble du module de communication du système sera indisponible. Il ne peut pas être reçu et traité de messages externes, provoquant des pannes de nœuds. Par conséquent, le modèle à processus unique de Reactor n'est pas adapté au calcul de scénarios denses et ne convient qu'aux scènes de traitement métier très rapides. Le modèle de thread de Redis est implémenté sur la base du modèle à thread unique de Reactor. Étant donné que le traitement métier de Redis est principalement effectué en mémoire, la vitesse de fonctionnement est très rapide et le goulot d'étranglement des performances ne concerne pas le processeur, donc Redis traite les commandes dans un. processus unique.
Afin de résoudre les problèmes de performances du modèle mono-thread Single Reactor, le modèle multi-thread Single Reactor a évolué, qui utilise le multi-threading (pool de threads) dans le partie du processeur d'événement
(2) S'il s'agit d'un événement d'établissement de connexion, l'événement sera distribué à l'accepteur et l'accepteur passera. La méthode accept() obtient la connexion et crée un objet Handler pour gérer les événements de réponse ultérieurs
(3) S'il s'agit d'un événement de lecture et d'écriture IO, le Reactor le fera remettre l'événement au gestionnaire correspondant à la connexion actuelle pour traitement
(4) Différent d'un seul Reactor et d'un seul thread, le gestionnaire n'effectue plus de traitement métier spécifique, mais est uniquement responsable de la réception et de la réponse aux événements après réception. les données via la lecture, il envoie les données au pool de threads de travail suivant pour le traitement métier.
(5) Le pool de threads de travail alloue des threads pour le traitement métier et, une fois terminé, les résultats de la réponse sont envoyés au gestionnaire pour traitement.
(6) Après avoir reçu le résultat de la réponse, le gestionnaire renvoie le résultat de la réponse au client par envoi.
2.2. Avantages et inconvénients :
Par rapport au premier modèle, après avoir traité la logique métier, c'est-à-dire après avoir obtenu les événements de lecture et d'écriture d'E/S, elle est transmise au pool de threads pour traitement. réponse, il enverra le résultat de la réponse renvoyé au client. Cela peut réduire la surcharge de performances de Reactor, lui permettant de se concentrer davantage sur la distribution des événements et d'améliorer le débit de l'ensemble de l'application. De plus, le gestionnaire utilise le mode multithread pour utiliser pleinement les performances du processeur. Mais il y a des problèmes avec ce modèle :
(2) Réacteur unique Responsable de la surveillance, de la distribution et de la réponse à tous les événements, il peut facilement provoquer des goulots d'étranglement de performances dans des scénarios à forte concurrence.
3. Modèle multithread maître-esclave Reactor :
Le modèle multithread unique Reactor résout le problème de performances monothread de Handler, mais Reactor est toujours monothread et il y aura toujours des goulots d'étranglement en termes de performances pour une concurrence élevée. scénarios, donc Reactor doit être ajusté en mode multi-threading, c'est le modèle multi-threading maître-esclave de Reactor qui sera introduit ensuite. Dans le modèle multithread maître-esclave du Reactor, le Reactor est divisé en deux parties
(2) SubReactor : responsable de la lecture et de l'écriture des événements, de la maintenance de son propre sélecteur, de l'exécution d'événements de lecture et d'écriture d'E/S séparés multicanaux basés sur le SocketChannel enregistré par MainReactor, de la lecture et de l'écriture des données réseau et de la gestion sur le traitement métier vers le pool de threads de travail pour achèvement. Le nombre de SubReactors est généralement le même que le nombre de CPU
3.1. Flux de traitement :
(1) L'objet MainReactor dans le thread principal écoute les événements via select et les distribue via Dispatch après avoir reçu l'événement. . Si le type d'événement est connexion L'événement d'établissement est distribué à l'accepteur pour l'établissement de la connexionÉtablissement de la connexion :① Sélectionnez au hasard un thread Reactor dans le pool de threads principal en tant que thread Acceptor pour lier le port d'écoute et recevoir les connexions client
② Une fois que le thread Acceptor a reçu la demande de connexion client, il crée un nouveau SocketChannel et l'enregistre avec d'autres threads dans le pool principal. pool de threads. Sur le thread Reactor, il est responsable de l'authentification d'accès, du filtrage des listes noires et blanches IP, de la prise de contact et d'autres opérations.
③ Une fois l'étape ② terminée, le lien de la couche métier est officiellement établi. Supprimez le SocketChannel du multiplexeur du thread Reactor du pool de threads principal, réenregistrez-le dans le thread du pool de threads SubReactor et créez un. Gestionnaire de traitement de divers événements de connexion
(2) Si l'événement reçu n'est pas un événement d'établissement de connexion, il est distribué à SubReactor, et SubReactor appelle le gestionnaire correspondant à la connexion actuelle pour traitement
(3) Une fois que le gestionnaire a lu le données via la lecture, il distribue les données au Worker. Le pool de threads effectue le traitement métier et le pool de threads Worker alloue les threads pour le traitement métier. Une fois terminé, le résultat de la réponse est envoyé au Handler
(4) Une fois que le Handler a reçu le. résultat de la réponse, il renvoie le résultat de la réponse au client via send
L'avantage du modèle multithread maître-esclave de Reactor est la division du travail entre le thread principal et les sous-threads. est clair. Le thread principal est uniquement responsable de la réception des nouvelles connexions, et les sous-threads sont responsables de l'achèvement des traitements métier ultérieurs. En même temps, l'interaction entre le thread principal et les sous-threads est également très simple. -les threads reçoivent le thread principal.Une fois le thread connecté, vous pouvez simplement vous concentrer sur le traitement métier sans prêter attention au thread principal. Vous pouvez directement envoyer les résultats du traitement au client dans le sous-thread.
Ce modèle Reactor est adapté aux scénarios de concurrence élevée, et le cadre de communication réseau Netty adopte également cette implémentation
(1) Réponse rapide, pas besoin d'être bloqué par une seule heure de synchronisation, bien que Reactor lui-même soit toujours synchrone ;
(2) Peut éviter au maximum les problèmes complexes de multi-threading et de synchronisation, et éviter la surcharge de commutation multi-thread/processus
(3) L'évolutivité, qui peut être facilement augmentée en augmentant la nombre d'instances Reactor Utiliser pleinement les ressources CPU ;
(4) Réutilisabilité, le modèle Reactor lui-même n'a rien à voir avec une logique de traitement d'événements spécifique et a une grande réutilisabilité.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!