Maison >interface Web >js tutoriel >Une analyse approfondie du mécanisme du disjoncteur dans Node.js
Cet article vous présentera le mécanisme du disjoncteur dans Node.js J'espère qu'il vous sera utile !
Lorsque nous utilisons l'architecture CS traditionnelle, le serveur bloque les requêtes en raison de pannes et d'autres raisons, ce qui peut entraîner une perte de réponse des requêtes du client, ce qui à son tour entraînera un lot de les utilisateurs après une période de temps ne peuvent pas obtenir le service. L'impact possible de cette situation est limité et peut être estimé.
Cependant, dans un système de microservices, votre serveur peut s'appuyer sur plusieurs autres microservices, et ces microservices peuvent à leur tour s'appuyer sur d'autres microservices. Dans ce cas, un certain service peut provoquer une congestion en aval en un instant (en quelques secondes). la consommation en cascade des ressources entraîne des conséquences catastrophiques sur l'ensemble de la liaison, nous appelons cela « l'effondrement du service ». [Apprentissage recommandé : "tutoriel Nodejs"]
Mode fusible : Comme son nom l'indique, tout comme un circuit domestique, si la tension d'une ligne est trop élevé, le fusible sautera pour éviter un incendie. Dans un système utilisant le mode disjoncteur, s'il s'avère que l'appel de service en amont est lent ou qu'il y a un grand nombre de délais d'attente, l'appel au service sera directement terminé, les informations seront renvoyées directement et les ressources seront libérées. rapidement. L'appel ne sera repris que lorsque le service en amont s'améliorera.
L'existence du disjoncteur équivaut à nous donner une couche de protection lors de l'appel de services et de ressources qui ne sont pas stables ou susceptibles de tomber en panne, le disjoncteur peut les surveiller. erreur et échouer la demande après avoir atteint un certain seuil pour éviter une consommation excessive de ressources. De plus, le disjoncteur a également pour fonction d'identifier automatiquement l'état du service et de le restaurer. Lorsque le service en amont revient à la normale, le disjoncteur peut automatiquement déterminer et reprendre les demandes normales.
Jetons un coup d'œil à un processus de demande sans disjoncteur : l'utilisateur s'appuie sur ServiceA pour fournir des services, et ServiceA s'appuie sur les services fournis par ServiceB. Supposons que ServiceB échoue à ce moment-là, chaque demande sera terminée. réponse retardée de 10 secondes.
Supposons donc que nous ayons N utilisateurs demandant le service de ServiceA. En quelques secondes, les ressources de ServiceA seront consommées en raison de la suspension des requêtes vers ServiceB, rejetant ainsi toute demande ultérieure de l'utilisateur. Pour les utilisateurs, cela signifie que ServiceA et ServiceB ont échoué en même temps, provoquant l'effondrement de l'ensemble du lien de service.
Et que se passe-t-il lorsqu'on installe un disjoncteur sur ServiceA ?
Une fois que le nombre de pannes atteint un certain seuil, le disjoncteur constatera que la demande adressée au ServiceB n'est pas valide. À ce stade, ServiceA n'a pas besoin de continuer à demander au ServiceB, mais renvoie directement la panne ou utilise un autre repli. données de sauvegarde. A ce moment, le disjoncteur est à l'état circuit ouvert.
Après un certain temps, le disjoncteur commencera à demander périodiquement si le ServiceB a été rétabli. À ce moment, le disjoncteur est à l'état à moitié ouvert.
Si le ServiceB a été restauré, le disjoncteur sera placé à l'état off À ce moment, ServiceA appellera ServiceB normalement et renverra le résultat.
Le schéma d'état du disjoncteur est le suivant :
On peut voir que plusieurs points essentiels du disjoncteur sont les suivants :
Timeout : Combien de temps dure la demande avant qu'il ne provoque une panne
Seuil de panne : c'est-à-dire le nombre de pannes qui doivent être atteintes avant que le disjoncteur ne déclenche un circuit ouvert
Délai d'attente de nouvelle tentative : lorsque le disjoncteur est dans l'état de circuit ouvert, combien de temps faut-il pour recommencer la demande, c'est-à-dire entrer dans l'état semi-ouvert
Avec cette connaissance, nous pouvons essayer de créer un disjoncteur :
class CircuitBreaker { constructor(timeout, failureThreshold, retryTimePeriod) { // We start in a closed state hoping that everything is fine this.state = 'CLOSED'; // Number of failures we receive from the depended service before we change the state to 'OPEN' this.failureThreshold = failureThreshold; // Timeout for the API request. this.timeout = timeout; // Time period after which a fresh request be made to the dependent // service to check if service is up. this.retryTimePeriod = retryTimePeriod; this.lastFailureTime = null; this.failureCount = 0; } }
Construire un disjoncteur Machine d'état :
async call(urlToCall) { // Determine the current state of the circuit. this.setState(); switch (this.state) { case 'OPEN': // return cached response if no the circuit is in OPEN state return { data: 'this is stale response' }; // Make the API request if the circuit is not OPEN case 'HALF-OPEN': case 'CLOSED': try { const response = await axios({ url: urlToCall, timeout: this.timeout, method: 'get', }); // Yay!! the API responded fine. Lets reset everything. this.reset(); return response; } catch (err) { // Uh-oh!! the call still failed. Lets update that in our records. this.recordFailure(); throw new Error(err); } default: console.log('This state should never be reached'); return 'unexpected state in the state machine'; } }
Fonctions supplémentaires restantes :
// reset all the parameters to the initial state when circuit is initialized reset() { this.failureCount = 0; this.lastFailureTime = null; this.state = 'CLOSED'; } // Set the current state of our circuit breaker. setState() { if (this.failureCount > this.failureThreshold) { if ((Date.now() - this.lastFailureTime) > this.retryTimePeriod) { this.state = 'HALF-OPEN'; } else { this.state = 'OPEN'; } } else { this.state = 'CLOSED'; } } recordFailure() { this.failureCount += 1; this.lastFailureTime = Date.now(); }
Lors de l'utilisation d'un disjoncteur, il vous suffit d'envelopper la requête dans la méthode Call de l'instance du disjoncteur et de l'appeler :
... const circuitBreaker = new CircuitBreaker(3000, 5, 2000); const response = await circuitBreaker.call('http://0.0.0.0:8000/flakycall');
Red Hat a depuis longtemps créé une implémentation de disjoncteur Node.js mature appelée Opossum, le lien est ici : Opossum. Pour les systèmes distribués, l'utilisation de cette bibliothèque peut considérablement améliorer la tolérance aux pannes de votre service et résoudre fondamentalement le problème de panne de service.
Adresse originale : https://juejin.cn/post/7019217344601948173
Auteur : ES2049 / Looking for Singularity
Pour plus de connaissances liées à la programmation, veuillez visiter : Vidéo de programmation ! !
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!