Maison  >  Article  >  interface Web  >  Une brève discussion sur la haute concurrence et le clustering distribué dans node.js

Une brève discussion sur la haute concurrence et le clustering distribué dans node.js

不言
不言original
2018-08-01 15:54:462829parcourir

Cet article vous présente une brève discussion sur la haute concurrence et les clusters distribués dans node.js. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.

Fonctionnalités du nœud : haute simultanéité

Avant d'expliquer pourquoi le nœud peut atteindre une simultanéité élevée, vous pourriez aussi bien jeter un œil à plusieurs autres fonctionnalités du nœud :

Mono-thread

Clarifions d'abord un concept, à savoir : le nœud est 单线程, ce qui est le même que les caractéristiques de JavaScript dans le navigateur, et dans le nœud, le fil principal JavaScript est différent des autres les threads (tels que les threads d'E/S) ne peuvent pas partager l'état.

L'avantage du thread unique est :

  • Il n'est pas nécessaire de prêter attention au problème de synchronisation d'état entre les threads comme le multi-threading

  • Il n'y a pas de surcharge causée par le changement de thread

  • Aucun blocage n'existe

Bien sûr, le threading unique présente également de nombreux inconvénients :

  • Impossible d'utiliser pleinement le processeur multicœur

  • Un grand nombre de calculs occupant le processeur entraîneront un blocage des applications (c'est-à-dire ne conviennent pas au processeur- intensif)

  • Des erreurs entraîneront la fermeture de l'ensemble de l'application

Cependant, il semble aujourd'hui que ces inconvénients ne soient plus un problème ou aient été résolu de manière appropriée :

(1) Créer un processus ou une instance de subdivision

Concernant le premier problème, la solution la plus simple consiste à utiliser le module central ou le cluster child_process : child_process et l'application combinée net. Nous pouvons utiliser pleinement chaque cœur en créant plusieurs processus sur un serveur multicœur (généralement en utilisant une opération fork), mais nous devons résoudre les problèmes de communication inter-processus.

Une autre solution consiste à diviser la machine physique en plusieurs machines virtuelles monocœur et à utiliser des outils tels que pm2 pour gérer plusieurs machines virtuelles afin de former une architecture de cluster afin d'exécuter efficacement les services requis. Je ne discuterai pas ici de la communication (synchronisation des statuts) entre les machines, et je l'expliquerai en détail dans l'architecture distribuée Node ci-dessous.

(2) Rotation des tranches de temps

Concernant le deuxième point, après en avoir discuté avec mes amis, je pense que l'on peut utiliser la rotation des tranches de temps pour simuler le multi-threading sur un seul thread et réduire de manière appropriée blocage des applications. Feeling (même si cette méthode ne fera pas vraiment gagner du temps comme le multi-threading)

(3) Équilibrage de charge, surveillance/isolation des pixels morts

Quant au troisième point, mes amis et Nous avons également discuté du fait que le principal problème est que le nœud est différent de JAVA et que la logique qu'il implémente est principalement asynchrone.

Cela fait que le nœud ne peut pas utiliser try/catch pour détecter et contourner les erreurs aussi facilement que JAVA, car il est impossible de déterminer quand la tâche asynchrone renverra l'exception. Dans un environnement monothread, le fait de ne pas contourner les erreurs signifie que l'application se fermera et que l'intervalle entre le redémarrage et la récupération entraînera des interruptions de service que nous ne souhaitons pas voir.

Bien sûr, maintenant que les ressources du serveur sont abondantes, nous pouvons utiliser des outils tels que pm2 ou nginx pour déterminer dynamiquement l'état du service. Isolez le serveur de pixels défectueux lorsqu'une erreur de service se produit, transférez la demande au serveur normal et redémarrez le serveur de pixels défectueux pour continuer à fournir des services. Cela fait également partie de l'architecture distribuée de Node.

E/S asynchrones

Vous vous demandez peut-être, puisque le nœud est monothread et que tous les événements sont traités sur un seul thread, cela ne devrait-il pas être très inefficace et contraire à une concurrence élevée ?

Au contraire, les performances du nœud sont très élevées. L'une des raisons est que le nœud possède la fonctionnalité 异步I/O Chaque fois qu'une demande d'E/S se produit, le nœud fournit un thread d'E/S à la demande. Ensuite, le nœud ne se souciera pas du processus d'opération d'E/S, mais continuera à exécuter l'événement sur le thread principal. Il ne doit être traité que lorsque la requête renvoie le rappel. C'est-à-dire que le nœud permet de gagner beaucoup de temps en attendant les requêtes.

C'est également l'une des raisons importantes pour lesquelles le nœud prend en charge une concurrence élevée.

En fait, non seulement les opérations d'E/S, la plupart des opérations du nœud sont asynchrones. effectué d'une manière. C'est comme un organisateur : il n'a pas besoin de tout faire personnellement, il doit seulement dire aux membres comment fonctionner correctement, accepter les commentaires et gérer les étapes clés, afin que toute l'équipe puisse fonctionner efficacement.

Axé sur les transactions

Vous voudrez peut-être demander à nouveau : comment le nœud sait-il que la demande a renvoyé un rappel et quand doit-il gérer ces rappels ?

La réponse est une autre fonctionnalité du nœud : 事务驱动, c'est-à-dire que le thread principal exécute le programme en déclenchant la boucle d'événements

C'est une autre façon pour le nœud de prendre en charge une concurrence élevée . Raisons importantes

Schéma de la boucle d'événement dans l'environnement de nœud :

   ┌───────────────────────┐
┌─>│        timers         │<p><strong>phase d'interrogation : </strong></p><p>Lors de l'entrée dans la phase d'interrogation, et Lorsqu'aucun minuteur n'est appelé, la situation suivante se produit : </p><p> (1) Si la file d'attente d'interrogation n'est pas vide : </p>
  • La boucle d'événement sera exécutée de manière synchrone dans le rappel de la file d'attente d'interrogation (nouvel événement d'E/S) jusqu'à ce que la file d'attente soit vide ou que le rappel exécuté arrive en ligne.

(2) Si la file d'attente d'interrogation est vide :

  • Si le script appelle setImmediate(), la boucle d'événements mettra fin à la phase d'interrogation et entrez Exécuter le rappel de setImmediate() dans la phase de vérification.

  • Si le script n'est pas appelé par setImmediate(), la boucle d'événements attendra que les rappels (nouveaux événements d'E/S) soient ajoutés à la file d'attente, puis les exécutera immédiatement.

Lorsque vous entrez dans la phase de sondage et que vous appelez les minuteurs, les événements suivants se produiront :

  • Une fois la file d'attente du sondage vide, la boucle d'événements vérifiera si les minuteurs, si un ou plusieurs temporisateurs sont arrivés, la boucle d'événements reviendra à la phase du temporisateur et exécutera les rappels de ces temporisateurs (c'est-à-dire, entrera le tick suivant).

Priorité :

File d'attente de ticks suivante > File d'attente MicroTask

setTimeout, setInterval > >Puisque le timer doit retirer le timer de l'arbre rouge-noir pour déterminer si l'heure est arrivée, la complexité temporelle est O(lg(n)), donc si vous souhaitez exécuter un événement de manière asynchrone immédiatement, il est préférable de ne pas utiliser setTimeout(func, 0) . Utilisez plutôt process.nextTick() pour le faire.

Architecture de nœuds distribués

L'architecture de cluster de nœuds que j'ai apprise est principalement divisée en modules suivants :

Nginx (équilibrage de charge, planification) -> ; Cluster de nœuds-> Redis (statut de synchronisation)

J'ai organisé une image selon ma compréhension :

Une brève discussion sur la haute concurrence et le clustering distribué dans node.js Bien sûr, cela devrait être une architecture idéale. Car bien que la lecture/écriture de Redis soit assez rapide, c'est parce qu'il stocke les données dans le pool de mémoire et effectue les opérations associées sur la mémoire.

C'est assez élevé pour la charge mémoire du serveur, donc généralement nous ajoutons toujours Mysql à l'architecture, comme indiqué ci-dessous :

Une brève discussion sur la haute concurrence et le clustering distribué dans node.js Expliquez d'abord cette image :

Lorsque les données utilisateur arrivent, les données sont d'abord écrites dans Mysql. Lorsque Node a besoin des données, il ira dans Redis pour les lire. S'il n'est pas trouvé, il ira dans Mysql. pour interroger les données souhaitées et les écrire, entrez Redis, et vous pourrez directement interroger dans Redis la prochaine fois que vous l'utiliserez.


Les avantages de l'ajout de Mysql par rapport à la seule lecture/écriture dans Redis sont :

(1) Évitez d'écrire des données inutiles sur Redis à court terme, d'occuper de la mémoire et de réduire la charge sur Redis

(2) Lorsque des requêtes spécifiques et une analyse des données sont nécessaires à un stade ultérieur (comme l'analyse de l'augmentation du nombre d'utilisateurs dans les activités opérationnelles), les requêtes relationnelles SQL peuvent être d'une grande aide

Bien sûr , lorsque nous traitons un trafic important sur une courte période Lors de l'écriture, nous pouvons également écrire directement des données sur Redis pour atteindre l'objectif de stocker rapidement les données et d'augmenter la capacité du serveur à gérer le trafic. Lorsque le trafic diminue, nous pouvons alors écrire. les données vers Mysql séparément.

Après avoir brièvement présenté l'architecture générale, examinons de plus près les détails de chaque partie :

Couche d'accès au trafic

La couche d'accès au trafic fait tout le trafic accepté. est traité et les services suivants sont fournis :

    Mémoire tampon du trafic
  • Déviation et redirection

Une brève discussion sur la haute concurrence et le clustering distribué dans node.js

    Détection du délai d'attente
    • Délai d'expiration pour établir la connexion avec l'utilisateur
    • Délai d'expiration pour la lecture du corps de l'utilisateur
    • Délai d'expiration pour la connexion au backend
    • Délai d'expiration pour la lecture de l'en-tête de réponse du backend
    • Délai d'expiration de la réponse en écriture
    • Délai d'expiration de connexion long avec l'utilisateur
    Vérification de l'état du cluster/isolement Mauvais pixel serveur
    • Isolez le serveur de pixels défectueux et essayez de réparer/redémarrer jusqu'à ce que le serveur revienne à la normale
    Échouer à nouveau Mécanisme d'essai
    • Une fois que la requête est transmise à une certaine machine dans un certain cluster et qu'un échec est renvoyé, la requête est transmise à d'autres machines du cluster ou à des machines Réessayer
    Mécanisme de regroupement de connexions/persistance de session
    • Utiliser le mécanisme de regroupement de connexions pour les utilisateurs sensibles aux délais. réduire le temps d'établissement de la connexion
    Protection de sécurité
  • Analyse des données
  • Lorsqu'elles sont transmises à chaque produit Après la mise en ligne, il est temps de travailler sur la couche de charge : transmettre la demande aux différentes salles informatiques selon la situation

Une brève discussion sur la haute concurrence et le clustering distribué dans node.jsBien sûr, cette plate-forme ne se limite pas au transfert. , vous pouvez la comprendre comme un grand système de cloud privé qui fournit les services suivants :

    Téléchargement de fichiers/déploiement de services en ligne
  • Ligne Modifier la configuration
  • Définir les tâches planifiées
  • Service de surveillance du système en ligne/impression de journaux
  • Gestion des instances en ligne
  • Centre miroir
  • etc...
  • Couche de cluster de nœuds

Le travail principal de cette couche est :

(1) Écrire un code de nœud fiable et fournir des services back-end pour les besoins

(2) Écrivez des instructions de requête hautes performances, interagissez avec Redis et Mysql et améliorez l'efficacité des requêtes

(3) Synchronisez l'état de chaque service Node dans le cluster via Redis

(4) Pass Plate-forme de gestion du matériel, gère/surveille l'état des machines physiques, gère les adresses IP, etc. (En fait, il semble inapproprié de mettre cette partie du travail sur cette couche, mais je ne sais pas sur quelle couche doit être placé sur...)

(Bien sûr, je ne liste que brièvement les éléments de cette partie, il faut quand même du temps pour accumuler et comprendre en profondeur)

Couche de base de données

Le travail principal de cette couche est :

(1) Créer Mysql et concevoir des pages et des tables associées ; établir les index et les clés étrangères nécessaires pour améliorer la commodité des requêtes

(2) Déployer Redis et fournir les interfaces correspondantes à la couche Node

Recommandations associées :

Comment vue utilise axios pour demander des données backend

Analyse de la liaison d'entrée du formulaire et les bases des composants dans Vue

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn