Welche Design-Muster sind die meisten bei der Schaffung von Hochverfügbarkeitsanwendungen genutzt? [geschlossen]

StackOverflow https://stackoverflow.com/questions/814742

Frage

Ebenso gibt es Designmuster, die vermieden werden sollte?

War es hilfreich?

Lösung

Ich gehe davon aus Sie einen Servertyp Anwendung schreiben (können Web-Anwendungen für eine Weile verlassen - es gibt einige gute aus dem Regal-Lösungen, die es helfen kann, können so aussehen auf dem „i dieser großen neuen Servertyp haben ich habe schreiben“, aber ich will es HA Problem).

sein

In einer Server-Implementierung sind die Anforderungen von Kunden in der Regel (in irgendeiner Form oder eine andere) umgewandelt auf ein Ereignis oder Befehlstyp-Muster, und werden dann ausgeführt auf einer oder mehrere Warteschlange.

Also, erstes Problem - muß Ereignisse / Befehle in einer Art und Weise zu speichern, die im Cluster überleben werden (. Dh wenn ein neuer Knoten über als Master nimmt, sieht es auf dem nächsten Befehl, die Ausführung benötigt und beginnt)

Hier kann mit einem einzigen Gewinde Server impl starten (die einfachste -.. Und Konzepte gelten nach wie vor auf Multi-Threaded aber sein seinen eigenen Satz von issues0 bekam Wenn ein Befehl verarbeitet wird irgendeine Art von Transaktionsverarbeitung benötigt

Ein weiteres Anliegen sind Nebenwirkungen zu verwalten und wie Sie Fehler des aktuellen Befehls gehen? Wo es möglich ist, behandeln Nebenwirkungen in einer transaktionalen Weise, so dass sie alles oder nichts sind. dh. wenn der Befehl Zustandsvariablen ändert, aber auf halben Weg durch die Ausführung abstürzt, auf den „vorherigen“ Zustand zurückkehren zu können ist groß. Dies ermöglicht es dem neuen Master-Knoten die abgestürzt Befehl und nur erneut ausführen den Befehl fortzusetzen. Ein guter Weg, wieder bricht eine Nebenwirkung in kleinere Aufgaben, die wiederum auf einem Knoten ausgeführt werden können. dh. Speicher den Hauptantrag Start- und End-Aufgaben, mit vielen kleinen Aufgaben, die nur eine Nebenwirkung pro Aufgabe sagen behandeln.

Dies führt auch andere Fragen, die Ihr Design bewirkt. Diese Zustandsvariablen sind nicht unbedingt Datenbanken Updates. Sie konnten Staat geteilt werden (sagen wir eine endliche Zustandsmaschine für eine interne Komponente), die auch im Cluster verteilt werden muss. So das Muster für die Verwaltung von Änderungen, so dass der Master-Code, um eine einheitliche Version des Staates sehen muss es braucht, und sich verpflichtet, dann diesen Zustand über den Cluster. Verwendung von irgendeiner Form von unveränderlichen (zumindest von dem Master-Faden tut das Update) Datenspeicherung nützlich ist. dh. werden alle Updates effektiv auf neue Kopien gemacht, die mit dem Updates nach der Aktualisierung über den Cluster (oder die Mindestzahl der Mitglieder über den Cluster für die Datenkonsistenz) in Speicherkopien aktualisiert durch eine Art Vermittler oder Fassade, die nur die lokale gehen müssen.

Einige dieser Fragen sind auch für Master-Arbeiter-Systeme.

Auch müssen gutes Fehlermanagement als die Anzahl der Dinge, die auf Zustandsaktualisierung erhöht schief gehen können (wie Sie das Netzwerk jetzt beteiligt haben).

Ich verwende das Zustandsmuster viel. Statt einer Linie Updates für Nebenwirkungen wollen Sie Anfragen / Antworten senden, und das Gespräch spezifische FSMs verwenden, um den Fortschritt zu verfolgen.

Ein weiteres Problem ist die Darstellung von Endpunkten. dh. Client Master-Knoten muss mit dem neuen Master verbinden zu können, und dann für die Ergebnisse zu hören? Oder kündigen Sie einfach alle anstehenden Ergebnisse und lassen die Kunden erneut einreichen? Wenn Sie erlauben ausstehende Anforderungen verarbeitet werden, eine schöne Art und Weise Endpunkte (Clients) zu identifizieren ist erforderlich (dh. Eine Art von Client-ID in einer Lookup).

Auch müssen Bereinigungscode usw. (dh. Nicht möchten, dass Daten für einen Kunden warten immer wieder zu verbinden, warten).

Viele Warteschlange verwendet. Viele Menschen werden daher einige Nachrichten-Bus mit (jms sagen für Java) Ereignisse in einer transaktionalen Weise zu drücken.

Terracotta (wieder für Java) löst eine Menge von dieser für Sie - nur den Speicher aktualisieren - Terrakotta ist Ihre Fassade / Vermittler hier. Sie haben injizieren nur die Aspekte für Ihre.

Terracotta (i für sie nicht funktionieren) - führt das Konzept der „Super-statisch“, so dass Sie diese Cluster breit Singletons erhalten, die cool sind, aber Sie müssen nur bewusst sein, wie diese Tests und Entwicklung Workflow bewirken wird - dh. verwenden viele Zusammensetzung, anstelle der Vererbung von Beton implementations für eine gute Wiederverwendung.

Für Web-Anwendungen - ein guter App-Server mit Session-Variablen-Replikation und eine guten Load Balancer helfen kann. In someways, ist mit diesem über eine REST (oder Ihre Web-Service-Methode der Wahl) eine eine einfache Möglichkeit, einen Multi-Threaded-Service zu schreiben. Aber es wird Auswirkungen auf die Leistung haben. hängt wieder von Ihrer Problemdomäne.

Nachrichten Aufschläge (sagen jms) oft eine lose Kopplung zwischen den verschiedenen Diensten einzuführen verwendet. Mit einem anständigen Message-Server, können Sie eine Menge von msg Routing tun (wieder Apache Kamel oder ähnlich hat eine große Aufgabe), dh. sagen einen klebrigen Verbraucher gegen einen Cluster von jms Produzenten usw., die auch für eine gute Failover ermöglichen kann. JMS-Warteschlange etc kann eine einfache Möglichkeit bietet CMDS in dem Cluster, indept von Master / Slave-zu verteilen. (Wieder es hängt davon ab, ob Sie LOB tun oder einen Server / Produkt von Grund auf neu zu schreiben).

(wenn ich Zeit bekommen später werde ich aufräumen, vielleicht setzen einige ausführlicher in Verlegenheit Rechtschreibung Grammatik usw.)

Andere Tipps

Ein Ansatz zur Erstellung zuverlässige Software ist Crash-only-Software :

  

Absturz-only-Software ist eine Software, die sicher und erholt sich schnell abstürzt. Der einzige Weg, es zu stoppen, ist es zum Absturz zu bringen, und der einzige Weg, um es zu starten ist zu erholen. Ein Crash-only-System besteht aus crash nur Komponenten zusammengesetzt, die mit wiederholbaren Anfragen kommunizieren; Fehler werden durch Absturz und Neustarten die fehlerhafte Komponente und retrying alle Anforderungen, die aus zeitlich gesteuert werden behandelt. Das resultierende System ist oft robuster und zuverlässiger, da Crash Recovery ein Bürger erster Klasse in den Entwicklungsprozess ist, sondern als ein nachträglicher Einfall, und Sie nicht mehr benötigen den zusätzlichen Code (und zugehörigen Schnittstellen und Bugs) für explizite Abschaltung. Die gesamte Software sollte in der Lage sein, sicher zum Absturz zu bringen und erholen sich schnell, aber Crash-only-Software muss diese Qualitäten haben, oder deren Fehlen wird schnell klar.

Ich würde empfehlen, eine Lese von frei! von Michael Nygard. Er enthält eine Reihe von anti-Muster, die Auswirkungen Produktionssysteme und Muster zu helfen, eine fehlerhafte Komponente zu verhindern unten das gesamte System von der Einnahme. Das Buch umfasst drei große Bereiche; Stabilität, Kapazität und allgemeine Gestaltung (für Networking, Sicherheit, Verfügbarkeit und Administration).

wurde Mein bisheriger Arbeitsplatz (zu einer Zeit oder einem anderen) gebissen von so ziemlich jedes einzelnen Fehlerszenario Nygard umreißt (mit Verlust von Einnahmen für jeden resultierenden Ausfall). Die Umsetzung einige der Techniken und Muster, die er schlägt vor, führte zu deutlich stabilen und vorhersehbaren Systemen in (und ja, ist das Buch ein wenig Java centric, aber die Prinzipien sind anwendbar in vielen Kontexten).

Falsch:

  

... und es wird ein Speicherserver sein

Gut:

  

... und es wird eine Farm von (mehreren) Speicher sein   Server mit (mehreren) Loadbalancer vor   von ihnen

  • Setzen Sie Loadbalancer vor allem. Denn jetzt können Sie 4 Backends haben, aber in der Zukunft können Sie 400 von ihnen haben, so weise es ist, um es nur auf der LB zu verwalten, nicht alle Anwendungen, die das Backend verwenden.

  • Verwenden Sie mehrere Cache-Ebenen.

  • Geben Sie für populäre Lösungen auf Beschleunigung thigs up (Memcached zum Beispiel).

  • Wenn Sie vorhaben, ein System zu erneuern, tun Sie es Teil-für-Teil, in mehreren kleinen Schritten. Wenn Sie es in einen großen Schritt (drehen Sie das alte, schalten Sie den neuen aus und bete, dass es funktionieren wird) wird es höchstwahrscheinlich fehlschlagen.

  • Verwenden von DNS-Namen für Sachen, F. E. storage-lb.servicename löst Adressen aller Speicher Loadbalancer. Wenn Sie wollen ein hinzufügen, ändern nur die dns, alle Dienste startet es automatisch mit.

  • Halten Sie es einfach. Je mehr Systeme Sie davon ab, je mehr Ihr Dienst wird daran leiden.

Planung Hochverfügbarkeit (HA) -Systemen ist ein aktiver Forschungs- und Entwicklungsbereich. Wenn Sie bei ACM oder IEEE aussehen, es gibt eine Tonne von Forschungsarbeiten auf Dienstgüten (Verfügbarkeit, Zuverlässigkeit, Skalierbarkeit, etc.) und wie sie zu erreichen (lose Kopplung, Anpassung, etc.). Wenn Sie mehr für praktische Anwendungen suchen, werfen Sie einen Blick auf fehlertolerante Systeme und Middleware, die gebaut wird, Clustering, Gitter zu ermöglichen, oder Cloud-ähnliche Funktionalität.

Replikation und Lastverteilung (auch bekannt als Reverse-Proxy) sind einige der häufigsten Muster von HA-Systemen zu erreichen, und oft können, ohne Code-Änderungen an der zugrunde liegenden Software durchgeführt werden vorausgesetzt, es ist auch nicht eng gekoppelt. Auch viele der jüngsten Cloud-Angebote sind im Wesentlichen durch Replikation und Lastverteilung erreicht, obwohl sie in der Elastizität zu bauen neigen weite Bereiche des Systembedarfs zu behandeln.

Herstellung Softwarekomponenten staatenlos entlastet der Replikation, wie der Staat selbst nicht zusammen mit den Softwarekomponenten repliziert werden muss. Staatenlosigkeit ist einer der wichtigsten Gründe dafür, dass HTTP so gut skaliert, aber es erfordert oft Anwendungen auf ihren eigenen Staat zu addieren (z Sitzungen), die dann repliziert werden muss.

Daher ist es einfacher, lose gekoppelter Systeme hochverfügbar als eng gekoppelte Systeme zu machen. Da die Zuverlässigkeit der Komponenten des Systems die Zuverlässigkeit des Gesamtsystems bestimmen, Komponenten, die unzuverlässig sind, können ersetzt werden müssen (Hardware-Fehler, Software-Fehler, usw.). Unter Berücksichtigung der dynamischen Anpassung zur Laufzeit lässt diese ausgefallenen Komponenten, ohne die Verfügbarkeit des Gesamtsystems ersetzt werden. Los Kopplung ist ein weiterer Grund für die Verwendung von Reliable Messaging Systemen, bei denen der Absender und Empfänger müssen nicht zur gleichen Zeit zur Verfügung stehen, aber das System selbst ist nach wie vor zur Verfügung.

Wie ich es verstehe, Sie suchen nach bestimmten Mustern in Teil Java-Anwendungen einer HA-Architektur zu verwenden. Natürlich gibt es eine zahlreiche Anzahl von Mustern und Best Practices, die verwendet werden können, aber diese sind nicht wirklich „HA-Muster“. Vielmehr sind sie gute Ideen, die in manys Kontexten genutzt werden können.

Ich denke, was ich versuche zu sagen, ist dies: Eine Hochverfügbarkeitsarchitektur besteht aus zahlreichen kleinen Teilen. Wenn wir eine dieser kleinen Teile auswählen und prüfen sie, finden wir wahrscheinlich, dass es keine magische HA auf diese kleine Komponente Attribute. Wenn wir alle anderen Komponenten untersuchen wir die gleiche Sache finden. Es ist, wenn sie auf intelligente Weise Thay die sich eine HA-Anwendung kombiniert sind.

Eine HA-Anwendung ist eine Anwendung, in dem Sie auf das Schlimmste von Anfang an zu planen. Wenn Sie jemals in Bezug auf die denken „Diese Komponente ist so stabil, dass wir keine zusätzliche Redundanz brauchen es:“ Es ist wahrscheinlich kein HA-Architektur. Schließlich ist es einfach, die Problemszenarien zu behandeln, die Sie voraussehen. Es ist das eine, die Sie überrascht, dass das System nach unten bringt.

Trotz alledem gibt es Muster, die besonders nützlich sind in HA Kontexten. Viele von ihnen sind im klassischen Buch dokumentiert "Patterns of Enterprise Application Architecture" von Martin Fowler.

Ich bin die Interpretation " Hochverfügbarkeit " als " Zero-Downtime " `, die als umgesetzt werden kann pro andere SE Frage:

Keine Ausfallzeiten Bereitstellung für Java-Anwendungen

  1. A / B-Schalter: (Rolling Upgrade + Fallback-Mechanismus)
  2. Parallel Deployment - Apache Tomcat: (Für Web-Anwendungen)
  3. Verzögerte Port-Bindung
  4. Erweiterte Port-Bindung

werde ich einige dieser Konzepte verwenden, um mit Design-Muster für High Availability-System von Software-Perspektive zu kommen, die über Komplimente zu erreichen.

Muster zu verwenden:

Proxy / Werk :

Haben Sie ein Proxy-Objekt und Proxy wird entscheiden, wo die Anfragen umgeleitet werden. Angenommen, Sie Version 1 & Version 2 von Software haben. Wenn Kunden mit altem Protokoll verbinden, leiten sie zu Version 1 Software. Neue Kunden können 2 direkt auf Version verbinden. Proxy kann entweder Fabrikmethode oder Abstrakte müssen neue Version der Software zu machen.

Strategie

Sie können aus einer Familie von Algorithmen durch Auswahl eines Algorithmus Algorithmus zur Laufzeit ändern. Wenn Sie Fluggesellschaften Beispiel nehmen, können Sie zwischen DiscountFare und NormalFare Algorithmen während der Non-Peak und Peak-Traffic Monate wechseln.

Decorator :

Sie können während der Laufzeit das Verhalten des Objekts ändern. Fügen Sie eine neue Klasse und dekorieren zusätzliche Verantwortung.

Adapter :

Nützlich, wenn Sie ändern Schnittstelle oder Vertrag zwischen Version 1 und Version 2. Adapter wird an den beiden alten und neuen Client-Anforderungen angemessen reagieren.

Allgemeine Richtlinien:

  1. lose Kopplung zwischen Objekten
  2. Folgen Sie S.O.L.I.D Prinzipien in Ihrer Anwendung

Siehe sourcemaking Website Artikel für über Muster für ein besseres Verständnis.

Was nicht zu verwenden:

Neben Design Patterns, haben Sie einige Vorsichtsmaßnahmen zu ergreifen, ohne Ausfallzeiten für Ihre Anwendung zu erreichen.

  1. Nicht mit Single Point of Failure in Ihrem System.
  2. Verwendung verteilten Caches (z. Terracotta) / locks sparsam.
  3. Entfernen harte Kopplung zwischen den Diensten. Entfernen enge Kopplung zwischen den Diensten unter Verwendung von Messaging-Bus / Frameworks (JMS, ActiveMQ usw.)

Hochverfügbarkeit ist mehr über Hardware-Verfügbarkeit und Redundanz als etwa Codierungskonventionen. Es gibt ein paar Muster, die ich in fast jedem Fall HA verwenden würde: Ich würde wählen Sie die Singletonmuster für meine Datenbankobjekt und verwenden Sie die Fabrikmuster die Singleton zu erstellen. Die Fabrik kann dann die Logik muß Verfügbarkeitsprobleme mit der Datenbank umgehen (das ist, wo die meisten Verfügbarkeitsprobleme passieren). wenn der Meister nach unten Zum Beispiel ist, schließen Sie dann zu einem zweiten Master-für beide lesen und schreiben, bis der Meister zurück ist. Ich weiß nicht, ob dies die meisten gehebelten Muster sind, aber sie sind die Leveraged in meinem Code.

Natürlich könnte diese Logik in einem __construct Verfahren behandelt werden, aber eine Fabrik Muster, das Sie besser kann, um Ihren Code kontrollieren und die Entscheidungslogik, wie Datenbank-Verbindungsprobleme zu behandeln. Eine Fabrik wird Ihnen auch ermöglichen, um besser auf die Singletonmuster zu behandeln.

Ich würde es absolut das Decorator-Muster vermeiden und die Beobachter Muster . Beide schaffen Komplexität in Ihrem Code, dass es schwierig zu halten macht. Ihr sind Fälle, in denen diese die beste Wahl für Ihre Bedürfnisse sind, aber die meiste Zeit sind sie nicht.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top