Heim  >  Artikel  >  Web-Frontend  >  Eine eingehende Analyse des Leistungsschaltermechanismus in Node.js

Eine eingehende Analyse des Leistungsschaltermechanismus in Node.js

青灯夜游
青灯夜游nach vorne
2021-10-18 09:53:552039Durchsuche

Dieser Artikel führt Sie durch den Schutzschaltermechanismus in Node.js. Ich hoffe, er wird Ihnen hilfreich sein!

Eine eingehende Analyse des Leistungsschaltermechanismus in Node.js

Probleme, die durch die Weiterentwicklung der Architektur verursacht werden

Wenn wir die traditionelle CS-Architektur verwenden, blockiert der Server Anfragen aufgrund von Fehlern und anderen Gründen, was dazu führen kann, dass die Anfrage des Clients nicht mehr reagiert, was wiederum zu einer Vielzahl von Benutzern führt bis „Dienst konnte nicht in Anspruch genommen werden“. Die möglichen Auswirkungen dieser Situation sind begrenzt und können abgeschätzt werden.

In einem Microservice-System ist Ihr Server jedoch möglicherweise auf mehrere andere Microservices angewiesen, und diese Microservices können wiederum auf weitere Microservices angewiesen sein. In diesem Fall kann ein bestimmter Dienst innerhalb von Sekunden zu einer nachgelagerten Überlastung führen Der kaskadierende Ressourcenverbrauch hat katastrophale Folgen für die gesamte Verbindung, wir nennen es „Service-Zusammenbruch“. [Empfohlenes Lernen: „nodejs-Tutorial“]

Eine eingehende Analyse des Leistungsschaltermechanismus in Node.js

Eine eingehende Analyse des Leistungsschaltermechanismus in Node.js

Mehrere Möglichkeiten, das Problem zu lösen

  • Sicherungsmodus: Wie der Name schon sagt, genau wie bei einem Haushaltsstromkreis, wenn die Spannung einer Leitung zu hoch ist zu hoch, wird die Sicherung durchbrennen, um einen Brand zu verhindern. Wenn in einem System, das den Leistungsschaltermodus verwendet, festgestellt wird, dass der Upstream-Dienstaufruf langsam ist oder eine große Anzahl von Zeitüberschreitungen vorliegt, wird der Dienstaufruf direkt beendet, Informationen werden direkt zurückgegeben und Ressourcen werden freigegeben schnell. Der Anruf wird erst wieder aufgenommen, wenn sich der Upstream-Dienst verbessert.

  • Isolationsmodus: Teilen Sie Aufrufe für verschiedene Ressourcen oder Dienste in mehrere verschiedene Anforderungspools auf. Die Erschöpfung der Ressourcen in einem Pool hat keine Auswirkungen auf Anforderungen für andere Ressourcen, wodurch verhindert wird, dass ein einzelner Fehlerpunkt alle Ressourcen verbraucht. Dies ist ein sehr traditionelles Disaster-Recovery-Design.
  • Strombegrenzungsmodus: Sicherung und Isolierung sind beides Nachbearbeitungsmethoden, die die Wahrscheinlichkeit von Problemen verringern können, bevor sie auftreten. Der aktuelle Begrenzungsmodus kann einen maximalen QPS-Schwellenwert für Anfragen für bestimmte Dienste festlegen. Anfragen, die den Schwellenwert überschreiten, werden direkt zurückgegeben und belegen keine Ressourcen mehr für die Verarbeitung. Der Strombegrenzungsmodus kann jedoch das Problem des Zusammenbruchs von Diensten nicht lösen, da der Zusammenbruch häufig nicht durch die große Anzahl von Anforderungen, sondern durch die Verstärkung mehrerer Kaskadenschichten verursacht wird.

Der Mechanismus und die Implementierung des Leistungsschalters

Die Existenz des Leistungsschalters ist gleichbedeutend damit, uns eine Schutzschicht zu bieten. Wenn Dienste und Ressourcen aufgerufen werden, die nicht stabil sind oder wahrscheinlich ausfallen, kann der Leistungsschalter diese überwachen Fehler und Fehlschlagen der Anfrage nach Erreichen eines bestimmten Schwellenwerts, um einen übermäßigen Ressourcenverbrauch zu verhindern. Darüber hinaus verfügt der Leistungsschalter über die Funktion, den Betriebszustand automatisch zu erkennen und wiederherzustellen. Wenn der vorgelagerte Betrieb wieder normal ist, kann der Leistungsschalter die normalen Anforderungen automatisch ermitteln und wieder aufnehmen.

Sehen wir uns einen Anforderungsprozess ohne Leistungsschalter an: Der Benutzer verlässt sich auf ServiceA, um Dienste bereitzustellen, und ServiceA verlässt sich auf die von ServiceB bereitgestellten Dienste. Angenommen, dass ServiceB zu diesem Zeitpunkt fehlschlägt um 10 Sekunden verzögerte Reaktion.

Eine eingehende Analyse des Leistungsschaltermechanismus in Node.js

Angenommen, wir haben N Benutzer, die den Dienst von ServiceA anfordern. Innerhalb weniger Sekunden werden die Ressourcen von ServiceA aufgrund der Aussetzung von Anfragen an ServiceB verbraucht, wodurch alle nachfolgenden Anfragen des Benutzers abgelehnt werden. Für Benutzer bedeutet dies, dass sowohl ServiceA als auch ServiceB gleichzeitig ausgefallen sind, wodurch die gesamte Dienstverknüpfung zusammengebrochen ist.

Und was passiert, wenn wir einen Leistungsschalter auf ServiceA installieren?

  • Nachdem die Anzahl der Ausfälle einen bestimmten Schwellenwert erreicht, stellt der Leistungsschalter fest, dass die Anforderung an ServiceB ungültig ist. Zu diesem Zeitpunkt muss ServiceA ServiceB nicht weiter anfordern, sondern gibt den Fehler direkt zurück oder verwendet einen anderen Fallback Sicherungsdaten. Zu diesem Zeitpunkt befindet sich der Leistungsschalter im Zustand „offener Stromkreis“.

  • Nach einer gewissen Zeit beginnt der Leistungsschalter regelmäßig abzufragen, ob ServiceB wiederhergestellt wurde. Zu diesem Zeitpunkt befindet sich der Leistungsschalter im
  • halboffenen

    -Zustand.

  • Wenn ServiceB wiederhergestellt wurde, wird der Leistungsschalter in den
  • Aus-Zustand versetzt. Zu diesem Zeitpunkt ruft ServiceA ServiceB normal auf und gibt das Ergebnis zurück.

Das Statusdiagramm des Leistungsschalters sieht wie folgt aus: Eine eingehende Analyse des Leistungsschaltermechanismus in Node.js

Es ist ersichtlich, dass mehrere Kernpunkte des Leistungsschalters wie folgt sind: Eine eingehende Analyse des Leistungsschaltermechanismus in Node.js

Timeout: Wie lange die Anforderung dauert bevor es zu einem Ausfall kommt
  • Fehlerschwelle: Das heißt, die Anzahl der Ausfälle, die erreicht werden müssen, bevor der Leistungsschalter einen offenen Stromkreis auslöst
  • Zeitüberschreitung bei Wiederholungsversuchen: Wie lange dauert es, bis der Leistungsschalter im offenen Stromkreiszustand ist, um mit dem erneuten Versuch der Anforderung zu beginnen, d ein Leistungsschalter:

    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;
      }
    }
  • Konstruieren Sie eine Leistungsschalter-Zustandsmaschine:
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';
    }
  }

Ergänzende verbleibende Funktionen:

// 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();
  }

Bei Verwendung eines Leistungsschalters müssen Sie die Anforderung nur in die Call-Methode der Leistungsschalterinstanz einschließen und sie aufrufen:

...
const circuitBreaker = new CircuitBreaker(3000, 5, 2000);

const response = await circuitBreaker.call('http://0.0.0.0:8000/flakycall');

Ausgereifte Node.js-Leistungsschalterbibliothek

Red Hat hat seit langem eine ausgereifte Node.js-Leistungsschalterimplementierung namens

Opossum

erstellt. Der Link ist hier:

Opossum

. Bei verteilten Systemen kann die Verwendung dieser Bibliothek die Fehlertoleranz Ihres Dienstes erheblich verbessern und das Problem des Dienstausfalls grundlegend lösen. Originaladresse: https://juejin.cn/post/7019217344601948173

Autor: ES2049 / Looking for Singularity

Weitere Programmierkenntnisse finden Sie unter:

Programmiervideo

! !

Das obige ist der detaillierte Inhalt vonEine eingehende Analyse des Leistungsschaltermechanismus in Node.js. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:juejin.cn. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen