J2EE-Clustering, Teil 1

Unternehmen entscheiden sich für Java 2, Enterprise Edition (J2EE), um ihre geschäftskritischen Anwendungen über das Web bereitzustellen. Innerhalb des J2EE-Frameworks bieten Cluster geschäftskritische Services, um minimale Ausfallzeiten und maximale Skalierbarkeit zu gewährleisten. Ein Cluster ist eine Gruppe von Anwendungsservern, auf denen Ihre J2EE-Anwendung transparent ausgeführt wird, als wäre sie eine einzelne Entität. Zum Skalieren sollten Sie zusätzliche Computer in den Cluster aufnehmen. Stellen Sie zur Minimierung von Ausfallzeiten sicher, dass alle Komponenten des Clusters redundant sind.

In diesem Artikel erhalten Sie ein grundlegendes Verständnis für Clustering, Clustering-Methoden und wichtige Cluster-Services. Da sich die Clustering-Ansätze in der Branche unterscheiden, werden wir die Vor- und Nachteile der einzelnen Ansätze untersuchen. Darüber hinaus werden die wichtigen clusterbezogenen Funktionen erläutert, nach denen auf einem Anwendungsserver gesucht werden muss.

Um unser neu erworbenes Clustering-Wissen auf die reale Welt anzuwenden, werden wir sehen, wie HP Bluestone Total-e-Server 7.2.1, Sybase Enterprise Application Server 3.6, SilverStream Application Server 3.7 und BEA WebLogic Server 6.0 jeweils Cluster implementieren.

In Teil 2 dieser Serie werden wir Programmier- und Failover-Strategien für Cluster behandeln sowie unsere vier Anwendungsserverprodukte testen, um zu sehen, wie sie skaliert und fehlgeschlagen sind.

Cluster definiert

Anbieter von J2EE-Anwendungsservern definieren einen Cluster als eine Gruppe von Computern, die zusammenarbeiten, um Unternehmensdienste transparent bereitzustellen (Unterstützung für JNDI-, EJB-, JSP-, HttpSession- und Komponenten-Failover usw.). Sie lassen die Definition absichtlich vage, da jeder Anbieter das Clustering anders implementiert. An einem Ende des Spektrums ruhen Anbieter, die einen Dispatcher vor eine Gruppe unabhängiger Maschinen stellen, von denen keine Kenntnis von den anderen Maschinen im Cluster hat. In diesem Schema empfängt der Dispatcher eine erste Anforderung von einem Benutzer und antwortet mit einem HTTP-Umleitungsheader, um den Client an einen bestimmten Mitgliedsserver des Clusters zu binden. Am anderen Ende des Spektrums befinden sich Anbieter, die einen Zusammenschluss eng integrierter Maschinen implementieren.wobei jede Maschine die anderen Maschinen um sie herum zusammen mit den Objekten auf diesen Maschinen vollständig kennt.

Cluster können neben Maschinen auch redundante und Failover-fähige Funktionen umfassen:

  • Load Balancer: Einzelne Einstiegspunkte in den Cluster und Verkehrsleiter zu einzelnen Web- oder Anwendungsservern
  • Webserver
  • Gateway-Router: Beenden Sie Punkte aus einem internen Netzwerk
  • Multilayer-Switches: Paket- und Rahmenfilter, um sicherzustellen, dass jeder Computer im Cluster nur Informationen empfängt, die für diesen Computer relevant sind
  • Firewalls: Cluster-Protektoren vor Hackern durch Filtern des Zugriffs auf Portebene auf den Cluster und das interne Netzwerk
  • SAN-Switches (Storage Area Networking): Verbinden Sie die Anwendungsserver, Webserver und Datenbanken mit einem Backend-Speichermedium. Verwalten der physischen Festplatte, auf die Daten geschrieben werden sollen; und Failover
  • Datenbanken

Unabhängig davon, wie sie implementiert sind, bieten alle Cluster zwei Hauptvorteile: Skalierbarkeit und Hochverfügbarkeit (HA).

Skalierbarkeit

Skalierbarkeit bezieht sich auf die Fähigkeit einer Anwendung, eine zunehmende Anzahl von Benutzern zu unterstützen. Mit Clustern können Sie zusätzliche Kapazität bereitstellen, indem Sie zusätzliche Server hinzufügen und so die Skalierbarkeit sicherstellen.

Hohe Verfügbarkeit

HA kann in einem Wort zusammengefasst werden: Redundanz. Ein Cluster verwendet viele Computer, um Anforderungen zu bearbeiten. Wenn ein Computer in einem Cluster ausfällt, kann daher ein anderer Computer transparent übernehmen.

Ein Cluster stellt HA nur auf der Ebene des Anwendungsservers bereit. Damit ein Web-System echte HA aufweist, muss es wie Noahs Arche sein, mindestens zwei von allem zu enthalten, einschließlich Webservern, Gateway-Routern, Switching-Infrastrukturen usw. (Weitere Informationen zu HA finden Sie in der HA-Checkliste.)

Clustertypen

J2EE-Cluster gibt es normalerweise in zwei Varianten: Shared Nothing und Shared Disk. In einem Cluster ohne gemeinsame Nutzung verfügt jeder Anwendungsserver über ein eigenes Dateisystem mit einer eigenen Kopie der im Cluster ausgeführten Anwendungen. Anwendungsaktualisierungen und -erweiterungen erfordern Aktualisierungen auf jedem Knoten im Cluster. Mit diesem Setup werden große Cluster zu Albträumen bei der Wartung, wenn Code-Pushs und Updates veröffentlicht werden.

Im Gegensatz dazu verwendet ein Cluster mit gemeinsam genutzten Festplatten ein einzelnes Speichergerät, mit dem alle Anwendungsserver die im Cluster ausgeführten Anwendungen abrufen. Aktualisierungen und Verbesserungen erfolgen in einem einzigen Dateisystem, und alle Computer im Cluster können auf die Änderungen zugreifen. Bis vor kurzem war ein Nachteil dieses Ansatzes die einzige Fehlerquelle. SAN bietet jedoch eine einzige logische Schnittstelle zu einem redundanten Speichermedium, um Failover, Failback und Skalierbarkeit bereitzustellen. (Weitere Informationen zu SAN finden Sie in der Seitenleiste der Speicherinfrastruktur.)

Beim Vergleich der Cluster-Implementierungen von J2EE-Anwendungsservern ist Folgendes zu berücksichtigen:

  • Cluster-Implementierung
  • Cluster- und Komponenten-Failover-Dienste
  • HttpSession-Failover
  • Einzelne Fehlerquellen in einer Clustertopologie
  • Flexibles Topologielayout
  • Instandhaltung

Später werden wir uns ansehen, wie sich vier beliebte Anwendungsserver in verschiedenen Bereichen vergleichen lassen. Aber zuerst wollen wir jedes Element genauer untersuchen.

Cluster-Implementierung

J2EE-Anwendungsserver implementieren Clustering um die Implementierung von JNDI (Java Naming and Directory Interface). Obwohl JNDI der Kerndienst ist, auf den sich J2EE-Anwendungen verlassen, ist die Implementierung in einem Cluster schwierig, da nicht mehrere Objekte an einen einzelnen Namen gebunden werden können. In Bezug auf die JNDI-Implementierung jedes Anwendungsservers gibt es drei allgemeine Clustering-Methoden:

  • Unabhängig
  • Zentralisiert
  • Global geteilt

Unabhängiger JNDI-Baum

HP Bluestone Total-e-Server und SilverStream Application Server verwenden für jeden Anwendungsserver einen unabhängigen JNDI-Baum. Mitgliedsserver in einem unabhängigen JNDI-Baumcluster kennen oder kümmern sich nicht um die Existenz anderer Server im Cluster. Daher wird das Failover entweder nicht unterstützt oder über Vermittlungsdienste bereitgestellt, die HTTP- oder EJB-Anforderungen umleiten. Diese Vermittlungsdienste sind so konfiguriert, dass sie wissen, wo sich die einzelnen Komponenten im Cluster befinden und wie sie bei einem Ausfall zu einer alternativen Komponente gelangen.

Ein Vorteil des unabhängigen JNDI-Baumclusters: kürzere Clusterkonvergenz und einfache Skalierung. Die Clusterkonvergenz misst die Zeit, die der Cluster benötigt, um alle Computer im Cluster und die zugehörigen Objekte vollständig zu erkennen. Konvergenz ist jedoch in einem unabhängigen JNDI-Baumcluster kein Problem, da der Cluster Konvergenz erreicht, sobald zwei Computer gestartet werden. Ein weiterer Vorteil des unabhängigen JNDI-Baumclusters: Für die Skalierung müssen nur zusätzliche Server hinzugefügt werden.

Es gibt jedoch mehrere Schwächen. Erstens liegt das Failover normalerweise in der Verantwortung des Entwicklers. Das heißt, da der JNDI-Baum jedes Anwendungsservers unabhängig ist, werden die über JNDI abgerufenen Remote-Proxys an den Server angeheftet, auf dem die Suche durchgeführt wurde. Wenn in diesem Szenario ein Methodenaufruf an eine EJB fehlschlägt, muss der Entwickler zusätzlichen Code schreiben, um eine Verbindung zu einem Dispatcher herzustellen, die Adresse eines anderen aktiven Servers abzurufen, eine weitere JNDI-Suche durchzuführen und die fehlgeschlagene Methode erneut aufzurufen. Bluestone implementiert eine kompliziertere Form des unabhängigen JNDI-Baums, indem jede Anforderung über einen EJB-Proxy-Service oder Proxy LBB (Load Balance Broker) geleitet wird. Der EJB-Proxy-Service stellt sicher, dass jede EJB-Anforderung an eine aktive UBS-Instanz gesendet wird. Dieses Schema erhöht die Latenzzeit für jede Anforderung, ermöglicht jedoch ein automatisches Failover zwischen Methodenaufrufen.

Zentralisierter JNDI-Baum

Sybase Enterprise Application Server implementiert einen zentralen JNDI-Baumcluster. Bei diesem Setup verwenden zentralisierte JNDI-Baumcluster den CosNaming-Dienst von CORBA für JNDI. Nameserver enthalten den zentralisierten JNDI-Baum für den Cluster und verfolgen, welche Server aktiv sind. Beim Start bindet jeder Server im Cluster seine Objekte in seinen JNDI-Baum sowie in alle Nameserver.

Das Abrufen eines Verweises auf eine EJB in einem zentralen JNDI-Baumcluster erfolgt in zwei Schritten. Zunächst sucht der Client ein Heimobjekt von einem Nameserver, der eine interoperable Objektreferenz (IOR) zurückgibt. Eine IOR zeigt auf mehrere aktive Computer im Cluster, die das Home-Objekt haben. Zweitens wählt der Client den ersten Serverstandort in der IOR aus und erhält das Heim und die Fernbedienung. Wenn zwischen dem Aufruf der EJB-Methode ein Fehler auftritt, implementiert der CORBA-Stub die Logik, um ein anderes Heim oder eine andere Fernbedienung von einem alternativen Server abzurufen, der in der vom Nameserver zurückgegebenen IOR aufgeführt ist.

Die Nameserver selbst weisen eine Schwäche des zentralisierten JNDI-Baumclusters auf. Insbesondere wenn Sie einen Cluster mit 50 Computern haben, von denen fünf Nameserver sind, wird der Cluster unbrauchbar, wenn alle fünf Nameserver ausfallen. Die anderen 45 Computer könnten zwar betriebsbereit sein, aber der Cluster wird keinen einzelnen EJB-Client bedienen, solange die Namensserver nicht verfügbar sind.

Ein weiteres Problem ergibt sich aus der Online-Aktivierung eines zusätzlichen Nameservers im Falle eines vollständigen Ausfalls der ursprünglichen Nameserver des Clusters. In diesem Fall erfordert ein neuer zentraler Nameserver, dass jeder aktive Computer im Cluster seine Objekte in den JNDI-Baum des neuen Nameservers einbindet. Obwohl es möglich ist, Anforderungen zu empfangen, während der Bindungsprozess stattfindet, wird dies nicht empfohlen, da der Bindungsprozess die Wiederherstellungszeit des Clusters verlängert. Darüber hinaus repräsentiert jede JNDI-Suche von einer Anwendung oder einem Applet wirklich zwei Netzwerkaufrufe. Der erste Aufruf ruft die IOR für ein Objekt vom Nameserver ab, während der zweite das vom Client gewünschte Objekt von einem in der IOR angegebenen Server abruft.

Schließlich leiden zentralisierte JNDI-Baumcluster unter einer längeren Zeit bis zur Konvergenz, wenn der Cluster größer wird. Das heißt, wenn Sie Ihren Cluster skalieren, müssen Sie weitere Nameserver hinzufügen. Beachten Sie, dass das allgemein akzeptierte Verhältnis von Nameserver-Computern zu Gesamt-Cluster-Computern 1:10 beträgt, wobei mindestens zwei Nameserver erforderlich sind. Wenn Sie also einen 10-Computer-Cluster mit zwei Nameservern haben, beträgt die Gesamtzahl der Bindungen zwischen einem Server und einem Nameserver 20. In einem 40-Computer-Cluster mit vier Nameservern gibt es 160 Bindungen. Jede Bindung stellt einen Prozess dar, bei dem ein Mitgliedsserver alle seine Objekte in den JNDI-Baum eines Nameservers bindet. In diesem Sinne weist der zentralisierte JNDI-Baumcluster die schlechteste Konvergenzzeit unter allen JNDI-Clusterimplementierungen auf.

Gemeinsamer globaler JNDI-Baum

Schließlich implementiert BEA WebLogic einen gemeinsam genutzten globalen JNDI-Baum. Bei diesem Ansatz meldet ein Server im Cluster beim Start seine Existenz und seinen JNDI-Baum den anderen Servern im Cluster über IP-Multicast (Internet Protocol). Jeder Clustercomputer bindet seine Objekte in den gemeinsam genutzten globalen JNDI-Baum sowie in seinen eigenen lokalen JNDI-Baum.

Durch einen globalen und lokalen JNDI-Baum auf jedem Mitgliedsserver können die generierten Home- und Remote-Stubs ein Failover durchführen und schnelle JNDI-Suchvorgänge in Bearbeitung durchführen. Der gemeinsam genutzte globale JNDI-Baum wird von allen Computern im Cluster gemeinsam genutzt, sodass jeder Mitgliedscomputer die genaue Position aller Objekte im Cluster ermitteln kann. Wenn ein Objekt auf mehr als einem Server im Cluster verfügbar ist, wird ein spezielles Home-Objekt in den gemeinsam genutzten globalen JNDI-Baum eingebunden. Dieses spezielle Zuhause kennt den Standort aller EJB-Objekte, denen es zugeordnet ist, und generiert entfernte Objekte, die auch den Standort aller EJB-Objekte kennen, denen es zugeordnet ist.

Die Hauptnachteile des gemeinsamen globalen Ansatzes: der große anfängliche Netzwerkverkehr, der beim Start der Server generiert wird, und die lange Konvergenzzeit des Clusters. Im Gegensatz dazu stellt sich in einem unabhängigen JNDI-Baumcluster die Konvergenz als kein Problem heraus, da kein JNDI-Informationsaustausch stattfindet. Ein gemeinsam genutzter globaler oder zentralisierter Cluster benötigt jedoch Zeit, damit alle Computer des Clusters den gemeinsam genutzten globalen oder zentralisierten JNDI-Baum erstellen können. Da gemeinsam genutzte globale Cluster Multicast zum Übertragen von JNDI-Informationen verwenden, ist die zum Erstellen des gemeinsam genutzten globalen JNDI-Baums erforderliche Zeit in Bezug auf die Anzahl der nachfolgenden hinzugefügten Server linear.

Die Hauptvorteile von Shared Global im Vergleich zu zentralisierten JNDI-Baumclustern liegen in der einfachen Skalierung und höheren Verfügbarkeit. Mit Shared Global müssen Sie nicht mit den CPUs und dem RAM eines dedizierten Nameservers herumspielen oder die Anzahl der Nameserver im Cluster anpassen. Um die Anwendung zu skalieren, fügen Sie einfach weitere Maschinen hinzu. Wenn ein Computer im Cluster ausfällt, funktioniert der Cluster weiterhin ordnungsgemäß. Schließlich erfordert jede Remote-Suche einen einzelnen Netzwerkanruf im Vergleich zu den beiden Netzwerkanrufen, die im zentralen JNDI-Baumcluster erforderlich sind.

All dies sollte mit einem Körnchen Salz aufgenommen werden, da JSPs, Servlets, EJBs und JavaBeans, die auf dem Anwendungsserver ausgeführt werden, den Vorteil nutzen können, dass sie sich auf dem EJB-Server befinden. Sie verwenden immer eine in Bearbeitung befindliche JNDI-Suche. Beachten Sie, dass zwischen den unabhängigen, zentralisierten oder gemeinsam genutzten globalen Cluster-Implementierungen nur geringe Unterschiede bestehen, wenn Sie nur serverseitige Anwendungen ausführen. Tatsächlich landet jede HTTP-Anforderung auf einem Anwendungsserver, der eine in Bearbeitung befindliche JNDI-Suche durchführt, um alle in Ihrer serverseitigen Anwendung verwendeten Objekte zurückzugeben.

Als Nächstes wenden wir uns der zweiten wichtigen Überlegung zum J2EE-Anwendungsserver zu: Cluster- und Failover-Dienste.

Cluster- und Failover-Dienste