Dieser Artikel wurde maschinell übersetzt.

Prognose: bewölkt

Lastenausgleich für private Endpunkte auf Workerthreads

Joseph Fultz

Joseph FultzArbeitete frühzeitig im Januar David Browne, und ich an einer Lösung für Saldo internen Service-Punkte auf Windows Azure Worker Rollen zu laden. Im Allgemeinen werden Dienstendpunkte im Arbeitsprozess Rollen veröffentlicht, damit das System zum Lastenausgleich kümmern kann die Aufrufe über die Instanzen ausgleicht. Jedoch benötigt der Kunde, mit denen wir arbeiteten, Endpunkte, die nicht öffentlich angesprochen wurden. Darüber hinaus wollten die Wartezeit von einigen queuing Operationstyp übernehmen. Wie würde diese Anforderung werden behandelt?

Während ein internes Ereignis bedeutete für uns, um die verschiedenen Technologien und Lösungen zu entdecken ausgedacht David und ich mit zwei verschiedene Ansätze für die Bewältigung der Herausforderung. Für den Artikel dieses Monats werde ich meine Überlegungen zum Entwurf und die Bits von Code, mit dem Prototyp einer dieser Ansätze behandeln.

Möchten Sie nicht versehentlich die endgültige Lösung Engpässen führen, entkräftet wir eine Softwarelösung für die Proxy-Stil. Stattdessen habe ich gewählt, einen Software-Mechanismus, der eine gültige IP-Adresse für die Service-Aufrufe bietet und des aufrufenden Knotens zwischenspeichern, des Endpunkts für eine bestimmte Dauer auf den Endpunktauflösung-Overhead zu reduzieren. Die drei primären Strategien, die ich angesehen wurden:

• Statische Zuweisung: Weisen Sie einen Dienstendpunkt jedes aufrufenden Knotens

• Zentralisierte Steuerung: ein Knoten überwacht und steuert die Zuweisung jedes aufrufenden Knotens

• Gemeinsame Steuerung: ermöglichen Sie einen beliebigen Knoten aus, um anzugeben, ob es für Service-Aufrufe verfügbar ist

Jede dieser Möglichkeiten bringt eine Reihe von Vorteilen und eine Reihe von Nachteilen mit sich.

Statische Zuweisung hat den Vorteil, einfach zu implementieren. Wenn die Zuordnung von Arbeitseinheiten zwischen dem Aufrufer und dem Arbeitnehmer gleich sind, dann möglicherweise eine realisierbare Ansatz für Lastenausgleich, da die Load-balancing-Lösung für die Web-Rolle durch Erweiterung der Aufrufe über die Rolle der Arbeitnehmer ausgeglichen ist.

Die zwei wichtigsten Nachteile sind, dass keine hohen Verfügbarkeit für den Dienst adressieren, noch eine Diskrepanz in Last zwischen dem Aufrufer und dem Dienstknoten adressieren. Wenn ich versuche, die statische Zuordnung Lösung zur Lösung der Probleme abzuändern, startet die Lösung nahezu assuredly zentralisierten oder kooperativen Steuerelement hinbewegen.

Zentrale Kontrolle

Eine typische Lastenausgleich, die empfängt Gesundheitsinformationen und Salden von Service-Requests, die auf der Grundlage solcher Informationen nutzt die zentrale Kontrolle. Er sammelt Informationen über den Knoten, was er zu den Zuordnungen weiß, die Sie vorgenommen hat und keine Heartbeat-Informationen und leitet die Anforderungen an die virtuelle IP-(VIP) zu einem bestimmten Knoten.

In diesem Szenario hauptsächlich am mittleren Anfasspunkt tun würde identisch, es sei denn, es würde nicht fungieren als Proxy für die Anforderung, sondern vielmehr des aufrufenden Knotens fragt den zentralen Controller erhalten Sie eine gute Adresse, den Anruf zu tätigen, und der Controller weist eine Adresse anhand der ihm bekannt sind (Siehe Abbildung 1). Des aufrufenden Knotens wird den Endpunkt zwischengespeichert und für eine vorbestimmte Quantum, das nach Ablauf der Auflösungsprozess wiederholt wird verwendet werden.

Centralized Control

Abbildung 1 Zentrale Kontrolle

Die Intelligenz, die alle liegt in der zentralen Steuerung, und es muss alle erforderlichen Informationen zu ermitteln, zu welchem Knoten zuweisen Aufrufe benötigt verfolgen. Dies könnte so einfach wie das Round-Robin oder auf vollständige Datenerfassung und Analyse des Zustands dauern. Es könnte auch kompliziert durch die verschiedenen Dienstendpunkte mit unterschiedliche Kriterien zum Bestimmen der Verfügbarkeit, was bedeutet, dass der zentrale Controller hat alles wissen über Service-Implementierungen in dem Arbeitspool zugeordnet sein.

Die größte Detractor von dieser Implementierung besteht darin, dass, wenn der zentrale Controller ausgefallen ist, dann das System heruntergefahren ist. Dies bedeutet, dass eine vollständig separate Lösung für hohe Verfügbarkeit des zentralen Controllers lösen implementiert werden muss.

In einigen automatischen und Matrixsysteme Worker Knoten wählt einen primären Domänencontroller und wenn der Takt verloren geht, wählen sie einfach eine neue. Während dies ein guter Entwurf, ist weil es die zentrale Steuerung und die kooperative Steuerelement kombiniert, auch hinzugefügt deutlich die Implementierung des Mechanismus für die Lastverteilung.

Kooperative-Steuerelement

Jede Person, die Verwaltung an eine Person tun durchlaufen wird, dass etwas weiß kann ein Hindernis bei echten erste tatsächlich jemand Ihre Arbeit sein. Ihm direkt gefragt, ob er Zeit, dies zu tun hat, erweist sich als sehr viel ratsamer, und angesichts des er ist eine gute Richter Aufwand, die beste Möglichkeit, um festzustellen, ob er tatsächlich Mal um die Arbeit zu erledigen hat. Dies ist das Modell, das ich gefolgt.

Die Idee besteht darin, dass alle aufrufenden Knoten mit der derzeit zugewiesenen Dienstendpunkt beginnt und gefragt werden, ob es noch verfügbar ist (Siehe Abbildung 2). Andernfalls wird der Knoten wird weiterhin (round Robin durch den verfügbaren Speicher) bis eine positiv reagiert (finden Sie unter Abbildung 3). Danach wird derselbe Ablauf Cachemechanismus wie oben beschrieben verwendet, um den Endpunkt Auflösung Verwaltungsaufwand zu reduzieren.

Cooperative Control

Abbildung 2 Kooperative-Steuerelement

Balancing to Another Node

Abbildung 3 auf einen anderen Knoten Netzwerklastenausgleich

Der Vorteil dieses Entwurfs ist, dass HA vorgesehen gekümmert ist und sollte es High-Fidelity zwischen den Knoten Ermitteln der Verfügbarkeit und der Arbeitnehmer tatsächlich Fähigkeit zur Service-Aufrufer. Alle Service-Knoten sollten die Intelligenz in seiner Implementierung, dass es Dinge, die speziell für den Dienst bekannt, die verfügbar sind oder nicht abgebremst baked verfügen. Dies ist Intelligence jenseits der CPU und ähnliches und Dinge wie z. B. Verfügbarkeit von downstream-Systemen, die vom Knoten zugegriffen werden kann. Folglich ist der Knoten ein negatives, Fehler oder ein Timeout gibt, des aufrufenden Knotens fragt den nächsten verfügbaren Service-Knoten und, falls verfügbar, macht seine Service-Aufrufe, die diesem Endpunkt.

Die große Detractor von dieser Lösung ist, dass es erfordert, dass die Implementierung auf beiden Seiten des Zauns ein Availability-Service und eine aufrufende Protokoll zwischen dem Aufrufer und die Endpunkte, die Verfügbarkeit von Endpunkt zu ermitteln.

Der Prototyp

Im Beispiel werden die folgenden Schritte ausführen:

  • Einrichten eines Standardmechanismus zum Bestimmen der Verfügbarkeit
  • Der Aufrufer wird einen verfügbaren Knoten für einen kurzen Zeitraum zwischengespeichert.
  • Ich werde möglicherweise einen Knoten für ein Quantum Satz zu deaktivieren, was als alle Aufrufe werden zu einem einzigen Knoten balanced angezeigt werden soll
  • Nachdem der Knoten wieder verfügbar ist, sollte der Aufrufer auf den vorherigen Knoten zurückgeben können

Einige Vorsichtsmaßnahmen: Erstens keine Arbeit an Verfügbarkeit, auf intelligente Weise zu ermitteln, gegeben habe nicht ausführen ich bin nur die Ausgleichsmechanismus einrichten und die Intelligenz hinter der Entscheidung nicht sorgen. Darüber hinaus, ich bin nicht behandeln von Fehlern und Timeouts, aber jene würden auf die gleiche Weise wie das Abrufen von eines negativen Ergebnis aus der Abfrage Verfügbarkeit behandelt werden. Schließlich ich bin einfach alle Worker-Funktionen in der Bereitstellung grabbing, jedoch in einer Implementierung eines true intelligenteres alle verfügbaren Dienstendpunkte bestimmen möglicherweise gewünscht, z. B. einen Mechanismus für die Registrierung oder einfach versucht, den Dienst auf jedem Endpunkt erreicht und erfolgreiche Anrufe als mögliche Endpunkte kennzeichnen. Der Code geht so weit, bitten Sie für einen bestimmten privaten Endpunkt und wenn, unterscheidet sich pro Dienst, die als Unterscheidungsmerkmal verwendet werden konnte.

Das erste, was zu tun ist dazu Abrufen der Liste der IP-Adressen aus den Worker-Rollen in der Bereitstellung ist. Um dieses Ziel zu erreichen, habe ich die Rollen konfigurieren. Für die Arbeitnehmer Rollen ich öffnen Sie das Konfigurationsfenster und eine interne Dienstendpunkte hinzufügen, wie im Abbildung 4.

Abbildung 4 einer internen Dienstendpunkt der Worker-Rolle hinzufügen

Ich habe auch die Worker-Rollen in der Bereitstellung als PrivateServices bezeichnet. Mithilfe der API des RoleEnvironment-Objekts sowie die Bezeichnung ist es einfach, um Knoten abzurufen:

if (_CurrentUriString == null) {
  System.Collections.ObjectModel.ReadOnlyCollection<RoleInstance> 
    ServiceInstances = null;
  System.Collections.ObjectModel.ReadOnlyCollection<RoleInstance> 
    WebInstances = null;

  ServiceInstances = 
    RoleEnvironment.Roles["PrivateServices"].Instances;
  WebInstances = 
    RoleEnvironment.Roles["ServiceBalancingWeb"].Instances;

Ich werde den Startknoten für die Überprüfung der Verfügbarkeit mit der Ordnungszahl des Knotens übereinstimmen. Wenn weitere Web-Rollen als Arbeitnehmer Rollen sind, wird eine mod-Funktion entsprechend einem Startknoten verwendet. Mit den Instanzen in der Hand und einem Startknoten Verfügbarkeit testen, ich kann starten Sie durchlaufen, und Testen Sie die Endpunkte (finden Sie unter Abbildung 5).

Abbildung 5 Tests von Endpunkten

while (!found && !Abort) {
  string testuri = 
    ServiceInstances[idxSvcInstance].InstanceEndpoints[
    "EndPointServices"].IPEndpoint.ToString();
  found = CheckAvailability(testuri);
  if (found) { 
    ServiceUriString = testuri; 
  }
  else {
    idxSvcInstance++;
    if (idxSvcInstance >= ServiceInstances.Count) { 
      idxSvcInstance = 0; 
    }
    loopCounter++;
    if (loopCounter == ServiceInstances.Count) { 
      Abort = true; 
    }
  }
}

Beachten Sie, dass ein Aufruf einer Funktion mit dem Namen CheckAvailability vorhanden ist (Siehe Abbildung 6). Innerhalb dieser Funktion erstellt eine Bindung, die keine für den Sicherheitsmodus verwenden, da der Endpunkt ausschließlich intern verwendet wird. I instanziieren den Service-Client und ein vernünftiges Timeout festgelegt und der Rückgabewert des Aufrufs.

Abbildung 6 CheckAvailability

static public bool CheckAvailability(string uri) {
  bool retval = true;
  Binding binding = new NetTcpBinding(SecurityMode.None);
  EndPointServicesRef.EndPointServicesClient endpointsvc = 
    new EndPointServicesRef.EndPointServicesClient(binding, 
    new EndpointAddress(@"net.tcp://" + uri));
  endpointsvc.InnerChannel.OperationTimeout = 
    new System.TimeSpan(0,0,0,0, 5000);

  try {
    retval = endpointsvc.IsAvailable();
  }
  catch (Exception ex) {
    // Todo: handle exception
    retval = false;
  }
  return retval;
}

Tritt ein Fehler während des Aufrufs, ich einfach false zurück und die Schleife, fahren Sie mit dem nächsten Knoten, und überprüfen Sie Ihre Verfügbarkeit zu ermöglichen. Beachten Sie jedoch, dass um die Instanznummer des Web-Rolle zu bestimmen, die der Code momentan ausgeführt wird unter ich die Instanz-ID analysiert haben Um dies zu erreichen überhaupt musste ich öffnen Sie eine beliebige interne (konnte noch externe) Endpunkt. Wenn ich hadn't, es wouldn't die ID zu erhöhen und die Analyse wäre nutzlos, da jeder Knoten nur aussehen würde.

So erstellen Sie eine Liste von Knoten eine andere Möglichkeit wäre zum Durchlaufen aller Knoten, die ordinale Position des aktuellen Knotens ausführen in der Liste zu identifizieren oder nur diese durch das letzte Oktett der IP-bestellen. Die letzteren beiden Verfahren wäre ein wenig mehr unfehlbar, aber bei diesem besonderen Beispiel verwendet die Instanz-ID

Eine weitere Einschränkung besteht darin, dass die Struktur der ID zwischen der tatsächlichen Bereitstellung und Entwicklung-Fabric, und zwingen, die mich zur Verarbeitung in den Code analysieren unterscheidet sich wie folgt:

string[] IdArray = 
  RoleEnvironment.CurrentRoleInstance.Id.Split('.');
int idxWebInstance = 0;
if (!int.TryParse((IdArray[IdArray.Length - 1]), 
  out idxWebInstance)) {
  IdArray = RoleEnvironment.CurrentRoleInstance.Id.Split('_');
  idxWebInstance = int.Parse((IdArray[IdArray.Length - 1]));
}

Dies sollte eine gute Endpunkt IP-Adresse, die zwischengespeichert werden können in einer statischen Variablen zurück. Ich dann festlegen einen Zeitgeber. Beim Auslösen des Ereignisses Zeit werde ich den Endpunkt auf null festlegen, verursacht den Code erneut suchen für einen gültigen Endpunkt für Dienste verwenden:

System.Timers.Timer invalidateTimer = 
  new System.Timers.Timer(5000);
invalidateTimer.Elapsed += (sender, e) => 
  _CurrentUriString = null;
invalidateTimer.Start();

Hier habe ich eine kurze Dauer von 5 Sekunden, weil ich sicherstellen, dass in einem kurzen Testausführung ich mindestens eine Web-Rolle an einen anderen Endpunkt Bounce kann nachdem ich ein Service-Nodes deaktivieren möchten.

Die Demoversion auszuführen

Nun werde ich die Standardseite und seiner Codebehind einfach den Knoten angezeigt, den nachweislich eine Affinität, zu ändern. Ich werde auch eine Schaltfläche zum Deaktivieren Sie einen Knoten hinzufügen. Beide Teile des Codes sind ziemlich einfach. Beispielsweise deaktiviert die Schaltfläche deaktivieren den Dienstendpunkt, der die Webseite, zu der die Anforderung balanced ruft, zugeordnet. Daher kann es zu wenig ein sonderbaren UI-Verhalten für diese Probe führen.

Ich werde auf die Benutzeroberfläche einer Bezeichnung und eine Befehlsschaltfläche hinzufügen. Die Bezeichnung werde ich die ID des zugeordneten Endpunkt ausdrucken und die Schaltfläche kann ich einen Knoten deaktivieren, damit ich sehen kann alle Web-Rollen, die einen einzelnen Endpunkt zugeordnet sind, bis der Knoten wieder online geschaltet wird. In der CodeBehind-kann ich ein wenig Code hinzufügen, das Laden der Seite um den Endpunkt zu erhalten (Siehe Abbildung 7).

Abbildung 7 Demo-Seitencode

protected void Page_Load(object sender, EventArgs e) {
  string UriString = EndpointManager.GetEndPoint();
  LastUri=UriString;
            
  Binding binding = new NetTcpBinding(SecurityMode.None);
            
  EndPointServicesRef.EndPointServicesClient endpointsvc = 
    new EndPointServicesRef.EndPointServicesClient(binding, 
    new EndpointAddress(@"net.tcp://" + UriString));
  lblMessage.Text = "WebInstacne ID: " + 
    RoleEnvironment.CurrentRoleInstance.Id.ToString() + 
    " is Calling Service @ " + UriString + " & IsAvailable = " + 
    endpointsvc.IsAvailable().ToString();
  cmdDisable.Enabled=true;
}

Da ich wirklich bin nur versuchen, veranschaulichen die kooperative Netzwerklastenausgleich, ich noch nicht implementiert einen anderen Service-Methode oder Schnittstelle, so dass ich einfach, die IsAvailable-Methode wiederzuverwenden, um den Punkt zu veranschaulichen.

Abbildung 8 zeigt die Prototyp-Anwendung in Aktion. Zunächst können Sie die ID (diese wird aus der Entwicklung Fabric), die IP-Adresse und gibt an, ob es verfügbar ist. Aktualisieren der Seite bewirkt, dass die Anforderung zum ausgleichen, also der Endpunkt wird außerdem unterschiedlich. Wenn ich die deaktivieren-Schaltfläche klicken, rufen ein kleiner Teil der Code ausgeführt wird, legen Sie DisableNode für den aktuellen Endpunkt:

protected void cmdDisable_Click(object sender, EventArgs e) {
  Binding binding = new NetTcpBinding(SecurityMode.None);
  EndPointServicesRef.EndPointServicesClient endpointsvc = 
    new EndPointServicesRef.EndPointServicesClient(binding, 
    new EndpointAddress(@"net.tcp://" + LastUri));
  endpointsvc.DisableNode();
}

die Demoversion auszuführen

Abbildung 8 die Demoversion auszuführen

Die DisableNode-Methode legt einfach den booleschen Wert fest und richtet dann einen Timer, um ihn wieder zu aktivieren. Der Zeitgeber wird festgelegt, ein bisschen länger als Ablauf für die zwischengespeicherten Endpunkt, um die Veranschaulichung des Testlaufs erleichtern:

public void DisableNode() {
  AvailabilityState.Enabled = false;
  AvailabilityState.Available = false;

  System.Timers.Timer invalidateTimer = 
    new System.Timers.Timer(20000);
  invalidateTimer.Elapsed += (sender, e) => EnableNode();
  invalidateTimer.Start();
}

Mit dem Knoten deaktiviert ist sollten die nachfolgenden Anforderungen von verschiedenen Webservern alle mit dem gleichen Worker-Endpunkt abstimmen.

Darüber hinaus das Beispiel

Dies ist offensichtlich ein triviales Beispiel veranschaulicht den Punkt, aber ich zu beachten, eine tatsächliche Implementierung hervorheben möchten. Ich möchte auch ganz zu schweigen von David-Implementierung, um das Problem zu lösen, da er eine Domäne Probleme behandelt, die ich nicht der Fall war.

Es war Mein Ziel für dieses Beispiel, dass der aufrufende Knoten Lösungscode Endpunkt als Teil des Startvorgangs Rolle ausführen würde. Es würde den Endpunkt in einen statischen Member oder eine tatsächliche Cacheaktualisierung basierend auf Cache Ablauf zwischenspeichern. Allerdings kann als Teil der Service-Implementierung ermöglicht differenzierte Kontrolle im Vergleich zu der Einheit wird auf der Ebene des UZ kombiniert werden und Port-Kombinationsfeld. Je das eigentliche Problem wird behoben und der Entwurf des Gewebes Service kann ich einen Stil gegenüber den anderen auswählen.

Um diese Ausführung in einer Produktionsumgebung zu erhalten, sind hier einige Dinge berücksichtigen, und möglicherweise beheben:

  • Die Intelligenz für die Entscheidung, der Verfügbarkeit. Dies bedeutet nicht, dass nur die Dinge, die möglicherweise (CPU, Datenträger, Back-End-Verbindungsstatus usw.), untersucht aber auch die Schwellenwerte, die so kippen Sie das Bit zwischen nicht verfügbar sein, oder nicht verwendet werden soll.
  • Logik für den Fall behandeln, dass alle nicht verfügbar zurück.
  • Entscheidungen über das Quantum, das den Endpunkt zwischengespeichert.
  • Einige zusätzlichen Methoden in der EndpointManager Einstellungen ändern, Entfernen von Knoten aus dem Pool und allgemeinen Runtime-Wartung.
  • Alle typischen Ausnahmebehandlung und Diagnose in der Regel in einer Dienstimplementierung enthalten.

Ich weiß, dass diese Dinge wahrscheinlich, ohne zu sagen wechseln, aber ich gerne stick mit einer Richtlinie "Keine Guessing."

In kurze Zusammenfassung von David Ansatzes eingerichtet er einer Matrix zwischen Fehler und Domänen zu aktualisieren versuchen, stellen Sie sicher, dass die Verfügbarkeit der Aufrufer die Endpunkt-Verfügbarkeit mit Bevorzugung von Endpunkten in der gleichen Domäne übereinstimmt. Ich glaube, dass dies eine gute Idee ist. Kombinieren Meine Implementierung durch seinen würde sicherstellen, dass Ihre Website durch eine Worker-Rolle, die nach der gleichen Vereinbarung zum Servicelevel möglichst bedient wird, aber in dem Fall, dass keine verfügbar sind, Sie die Möglichkeit müssten, auf einen anderen Knoten zu verteilen.

Schlussbemerkung

Ich hoffe, dass die Plattform Windows Azure weiterentwickelt wird, um Lastenausgleich für private Endpunkte als Ausgangspunkt für die Konfiguration zu ermöglichen. Bis dahin, wenn es etwas ist, müssen Sie (raw-Sockets werden fast immer will ein Maß an Schutz durch interne wird), dann können eine Code-Lösung wahrscheinlich die einfachste Methode zum wechseln. Durch Segmentieren Endpunkt Auflösung Aufrufe Weg von der tatsächlichen Service-Anrufe und nehmen sie Teil des Starts der sollte es den Mehrwert schaffen Code sauber und getrennt von den Foundation-Code beibehalten. Folglich sobald ein solches KE so konfigurieren Sie verfügbar wird, sollten die Dienste weiterhin arbeiten, während Sie den Netzwerklastenausgleich Code deaktivieren.

Joseph Fultz ist als Architekt im Microsoft Technology Center in Dallas, wo er mit Enterprise-Kunden und ISVs entwerfen und Erstellen von Prototypen für Software-Lösungen zur Erfüllung von geschäftlichen und Markt gerecht werden arbeitet. Er ist bei Veranstaltungen wie Tech · gesprochen.ED und ähnliche interne Schulungen und Veranstaltungen.