HowTo: Glassfish im Cluster mit Session-Replication

Aus wiki.shutdown-system.de
Wechseln zu: Navigation, Suche

Da ich es für einen Kunden mal machen musste, dachte ich mir ich dokumentiere das hier :)

Leider läuft in diesem Fall Glassfish auf Windows. :( Aber zu Linux gibt es eigentlich keinen Unterschied was die Konfiguration betrifft :)

Man kann diese Anleitung also auf für Linux einsetzen :)

Der Apache läuft aber in meinem Beispiel auf Linux (Debian).

Inhaltsverzeichnis

kurze Einleitung

  • Was ist Glassfish?

Glassfish ist ein Open-Source-Projekt eines Java-Servers (Enterprise Edition) von Sun.

Der Application Server ist plattformübergreifend (UNIX, Linux, Windows, OS X) und bietet für die Administration ein Webfrontend und ein Consolentool (asadmin).

Große Stärke von Glassfish gegenüber dem Apache Tomcat ist, dass er ein "echter" Applicationserver mit vollen EJB Enterprise Java Beans Umfang bietet.

Die Dinge die hier geschildert und erklärt werden finden an folg. Setup statt:

  • 2 Application Server (im Cluster mit HA und Session Replication) jeweils Windows
  • für Testzwecke und Konfigurationsbeispiele ein Webserver (Debian Lenny - Apache2)
  • Loadbalancing über den Webserver (mit mod_jk - AJP13)


Für diese Anleitung wurde ein Glassfish in Version 2.1.1 verwendet. Des Weiteren kam (durch Kundenwunsch) ein Windows für die Application Server zum Einsatz.

Wie funktioniert Session Replication und welche Form nutzen wir?

Wir benutzen die In-Memory-Replikation:

  • In-Memory-Replikation auf anderen Servern bietet einen Lightweight-Speicher für Sitzungsstatusdaten, ohne dass eine separate Datenbank (z. B. HADB) erforderlich ist
  • bei dieser Form der Replikation wird der Arbeitsspeicher anderer Server zur Hochverfügbarkeitsspeicherung von HTTP-Sitzungsdaten und Daten zu Stateful Session-Beans genutzt
  • Cluster-Serverinstanzen replizieren Sitzungsstatus in einer Ringtopologie
  • jede Sicherungsinstanz speichert die replizierten Daten im Arbeitsspeicher
  • die Replikation von Sitzungsstatusdaten im Arbeitsspeicher anderer Server ermöglicht die Verteilung von Sitzungen
  • für die Verwendung der In-Memory-Replikation muss der Group Management Service (GMS) aktiviert sein (default)

Installation

Für Windows sind nicht viele Dinge nötig. Man muss nicht Java und Glassfish getrennt installieren (geht auch, ist aber doof).

Am einfachsten ist sich das JDK von Sun zu downloaden da da gleich Glassfish integriert ist.

z.B. java_ee_sdk-5_08-jdk-6u17-windows-ml.exe

  • Schritt 1: Installation:
    • Total schwer :) Doppelklick auf java_ee_sdk-5_08-jdk-6u17-windows-ml.exe ;)
    • Als erstes einfach mal mit "Next" weiter machen, Lizenz bestätigen, Installationsverzeichnis festlegen.
    • Nun muss man noch einen User angeben (admin) und ein Passwort.
    • Die Ports sollte man so lassen :) (und sich merken). Sinnvoll ist es hier das "Don't Prompt for Admin User Name and Passwort" zu aktivieren.
    • als nächstes sollte man alles so lassen wie es ist und auf jeden fall noch "Create Windows Service" mit auswählen
    • und schon wird installiert :)
    • Die Registrierung kann man skippen
  • Schritt 2: Nacharbeiten:
    • Leider gibt es ein Problem mit den Umgebungsvariablen von Glassfish, diese muss man dann per Hand hinzufügen:
    • Rechtsklick auf den Arbeitsplatz -> Eigenschaften -> Erweiter -> Umgebungsvariablen

Hier muss die Variable "JAVA_HOME" auf "C:\Sun\SDK\jdk" stehen (oder halt das entsprechende Installationsverzeichnis und dann jdk).

Am besten gleich die Variable einmal für den Administrator anlegen und auch noch als Systemvariable definieren.

Und nun kann man einen Browser auf dem System öffnen, und auf "http://localhost:4848" gehen (4848 ist der default-Port, oder halt den Port der während der Installation vorgeschlagen wurde) und sich mit den entsprechenden Anmeldedaten einloggen.

Alternativ kann man auch gleich über Start -> Programme -> Sun Microsystems -> Java EE 5 SDK -> Admin Console gehen.

Falls es nicht funktioniert kann es sein, dass der Server noch nicht gestartet ist. In diesem Fall dann einfach den Server unter Start -> Programme -> Sun Microsystems -> Java EE 5 SDK -> Start Default Server den Server starten.

Während des starten öffnet sich ein CMD-Fenster wo auch nochmal alle wichtigen Infos drin stehen (Adminport, HTTP-Port, HTTPS-Port usw.)

Die Installation muss man auf beiden Nodes durchführen wo man Glassfish laufen lassen will. In diesem Beispiel also auf node1 und node2.

Konfiguration

Cluster Support

Per default wird eine Domain angelegt, die "domain1".

Diese kann man gleich verwenden.

Vorbereitungen

Um diese Domain Clusterfähig zu machen, loggt man sich auf den Port 4848 (Adminport) per Browser ein und klickt auf "Application Server" im linken Frame. Nun kann man bei "General Information" "Add Cluster Support" wählen. Dadurch wird die Domain Clusterfähig gemacht. Im Anschluss muss Glassfish restartet werden.

Kurze Beschreibung: Eine Domain enthält eine Node-Agent. Dieser wiederum eine Instanz. Innerhalb der Instanz laufen die Applikationen.

Des Weiteren ist es praktischer wenn man die Nodes z.B. über "node1" und "node2" ansprechen kann. Also einen entsprechenden Eintrag in die hosts-Datei vom Windows vornehmen.

Besonderheiten beim Cluster Support

  • Systemeinstellungen und Templates werden durch den Cluster Support hinzugefügt
  • man kann die Clusterfunktion nutzen, nebenbei aber auch noch einzelne Instanzen "standalone" laufen lassen
  • Man sollte die JVM-Einstellungen auch entsprechend anpassen (Heap-Size, JMX, AJP-Port...)
  • deployte Applikationen können auch im nachhinein Clusterfähig gemacht/migriert werden

Zudem müssen Applikationen folg. enthalten:

  • web.xml muss das <distributable/> Tag enthalten
  • es muss eine web-inf/sun-web.xml existieren mit z.B. folg. Inhalt:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sun-web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 9.0 
Servlet 2.5//EN" "http://www.sun.com/software/appserver/dtds/sun-web-app_2_5-0.dtd">  


<sun-web-app>
  <session-config>
    <session-manager persistence-type="replicated">
      <manager-properties>
        <property name="persistenceFrequency" value="web-method"/>
      </manager-properties>
      <store-properties>
        <property name="persistenceScope" value="session"/>
      </store-properties>
    </session-manager>
    <session-properties/>
    <cookie-properties/>
  </session-config>
  • persistence-type="replicated" wird benötigt um die "memory replication" zu nutzen
  • value="web-method" besagt, dass nach jedem Request die Session repliziert werden soll
  • value="session" mit persistenceScope sagt, dass die gesamte Session repliziert werden soll


Cluster und Node-Agents anlegen

Am besten ist es Cluster und Nodes-Agents per CLI anzulegen mit asadmin.

Node-Agent auf Node1 anlegen

C:\Users\Administrator>asadmin create-node-agent --host node1 --port 4848 node-agent1
Please enter the admin user name>admin
Please enter the admin password>
Command create-node-agent executed successfully.
C:\Users\Administrator>

Somit haben wir einen Node-Agent mit dem Namen "node-agent1" angelegt.


Cluster auf Node1 anlegen

C:\Users\Administrator>asadmin create-cluster --host node1 --port 4848 glassfish-cluster
Please enter the admin user name>admin
Please enter the admin password>
Command create-cluster executed successfully.
C:\Users\Administrator>

Nun haben wir ein Cluster mit dem Namen "glassfish-cluster" angelegt.

Damit man auch die Clusterfunktion richtig nutzen kann, muss man unter "Cluster -> glassfish-cluster" den Heartbeat aktivieren. Der Port kann auf dem Defaultwert ruhig bleiben. Erfahrungen haben gezeigt, dass 224.0.0.1 die beste Multicastadresse ist. Warum? Weiss ich selbst noch nicht :)

Instanz anlegen und dem Node-Agent und dem Cluster zuweisen

C:\Users\Administrator>asadmin create-instance --host node1 --port 4848 --nodeagent node-agent1 --cluster glassfish-cluster glassfish-instance1
Please enter the admin user name>admin
Please enter the admin password>
Command create-instance executed successfully.
C:\Users\Administrator>

Nun haben wir eine Instanz mit dem Namen "glassfish-instance1" angelegt und gleich dem neuen Node-Agent und dem Cluster zugeordnet.

Cluster neu starten

Damit die ganze Sache auch funktioniert, muss man noch das Cluster neu starten, wie auch den Node-Agent. Die Instanz kann nur laufen wenn auch der Node-Agent läuft.

Domains listen und stoppen

C:\Users\Administrator>asadmin list-domains
domain1 running
Command list-domains executed successfully.

C:\Users\Administrator>asadmin stop-domain
Domain domain1 stopped.

Domain starten

C:\Users\Administrator>asadmin start-domain

Node-Agents auflisten und starten (Instanzen überprüfen)

C:\Users\Administrator>asadmin list-node-agents
node-agent1 not running
Command list-node-agents executed successfully.
C:\Users\Administrator>asadmin start-node-agent --syncinstances=true node-agent1
Please enter the admin user name>admin
Please enter the admin password>
Please enter the master password [Enter to accept the default]:>

Nun läuft auch die Instanz. Überprüfen kann man das mit:

C:\Users\Administrator>asadmin list-instances
glassfish-instance1 running
Command list-instances executed successfully.
C:\Users\Administrator>

Node2 zum Cluster hinzufügen

Grundvoraussetzung ist die Installation von Glassfish wie oben beschrieben. Mehr erstmal nicht.

Nun öffnet man auch hier eine CMD um "asadmin" zu verwenden und um einen neuen Node-Agent zum Cluster hinzuzufügen:

C:\Users\Administrator>asadmin create-node-agent --host node1 --port 4848 node-agent2
Please enter the admin user name>admin
Please enter the admin password>
Command create-node-agent executed successfully.

Nun haben wir node-agent2 zu unserem Cluster "glassfish-cluster" auf node1 hinzugefügt.

C:\Users\Administrator>asadmin create-instance --host node1 --port 4848 --nodeagent node-agent2 --cluster glassfish-cluster glassfish-instance2
Please enter the admin user name>admin
Please enter the admin password>
Command create-instance executed successfully.

Hier haben wir dem node-agent2 auf node1 eine Instanz gegeben mit dem Namen "glassfish-instance2".

C:\Users\Administrator>asadmin start-node-agent --syncinstances=true node-agent2
Please enter the admin user name>admin
Please enter the admin password>
Please enter the master password [Enter to accept the default]:>
Command start-node-agent executed successfully.
C:\Users\Administrator>

Jetzt kann man auch schon eine Applikation deployen.

Durch das anlegen des Clusters wurde nun automatisch eine Config generiert. Diese findet man unter "Configurations -> glassfish-cluster-config".

Darin sucht man sich den Punkt "System Properties". In der Variable "HTTP_LISTENER_PORT" findet man nun den Port auf dem Glassfish "lauscht". Man kann nun also mit http://<gassfish-host>:<HTTP_LISTENER_PORT>/ auf den Server zugreifen (funktioniert natürlich auf beiden Nodes. Die Applikation wir automatisch schon auf Node1 und Node2 deployed.

Hier haben wir "node-agent2" gestartet und die Instanzen syncronisiert.

Vorbereitung auf Node1 der JVM-Option für AJP

Als erstes müssen wir in der Adminoberfläche JK aktivieren:

  • "Configuration -> glassfish-cluster-config -> JVM Options"

Hier fügen wir folg. Einträge hinzu:

-Dcom.sun.enterprise.web.connector.enableJK=${AJP_PORT} <- damit aktivieren wir JK
-DjvmRoute=${AJP_INSTANCE_NAME} <- hiermit setzen wir die JVM-Route (aus diesem Grund müssen wir auch die später die Instanz bei mod_jk angeben)

Durch "${VARIABLE}" halten wir die Variablen flexibel und können diese Eigenschaften für das Cluster nutzen.

Als nächstes müssen wir noch den AJP-Port und den AJP-Namen für das JVM-Routing festlegen. Dies findet auf der Ebene der Instanzen statt:

  • "Cluster -> glassfish-cluster -> Instances -> glassfish-instance1 -> Properties"

Hier fügen wir folg. Einträge hinzu:

AJP_PORT 8901 <- setzt den AJP-Port auf 8901
AJP_INSTANCE_NAME glassfish-instance1 <- setzt den AJP-Namen für das JVM-Routing

Das gleiche muss man auch für glassfish-instance2 machen (AJP_INSTANCE_NAME auf glassfish-instance2 setzen).

Im Anschluß muss man vermutlich die Domain und node-agents neu starten.

neue Java-Module hinzufügen damit AJP nutzbar ist

Man benötigt noch folg. Modul (am besten aus dem Tomcat-Package):

  • commons-logging.jar
  • commons-modeler.jar
  • tomcat-ajp.jar

Die jar-Files muss man nach Sun\SDK\lib\ kopieren. Auf node2 auch!!!

Apachekonfiguration (mod_jk AJP)

Für die Sessionreplication benötigen wir mod_jk. Dieses Modul also bitte laden.

Unter /etc/apache2/conf.d wird eine jk.conf erzeugt (bei Debian).

Diese sollte so aussehen:

<IfModule mod_jk.c>
#-----------------------------------------------
# Where to find the workers.properties file
#-----------------------------------------------
#
JkWorkersFile /etc/apache2/workers.properties
JkShmFile /var/run/apache2/jk_prod.shm
JkOptions +ForwardURICompatUnparsed
JkLogFile "| /usr/sbin/rotatelogs /var/log/apache2/mod_jk_prod.log_%Y%m%d-%H%M%S 86400"
JkLogLevel debug
JkExtractSSL On
</IfModule>

Hier noch die /etc/apache2/workers.properties:

worker.list=jk-manager
worker.jk-manager.type=status

# Restricted status worker
worker.list=jk-status
worker.jk-status.type=status
worker.template.type=ajp13

worker.list=glassfish-balancer
worker.glassfish-balancer.type=lb
worker.glassfish-balancer.method=R
worker.glassfish-balancer.recover_time=10

worker.glassfish-balancer.balance_workers=glassfish-instance1
worker.glassfish-instance1.host=192.168.1.100
worker.glassfish-instance1.port=8901
worker.glassfish-instance1.reference=worker.template
worker.glassfish-instance1.activation=a

worker.glassfish-balancer.balance_workers=glassfish-instance2
worker.glassfish-instance2.host=192.168.1.200
worker.glassfish-instance2.port=8901
worker.glassfish-instance2.reference=worker.template
worker.glassfish-instance2.activation=a

WICHTIG: balance_workers muss den Namen der jeweiligen Instanz haben!

In der Apache-vHostkonfiguration sieht das dann so aus:

JkLogFile "| /usr/sbin/rotatelogs /var/log/apache2/mod_jk.log_%Y%m%d-%H%M%S 86400"
JkLogLevel info
JkMount /|*     glassfish-balancer
JkMount /jk-manager|* jk-manager
JkMount /jk-status jk-status


Apachekonfiguration (mod_proxy)

Dies ist die Alternative zu mod_jk.

Erforderlich z.B. wenn man die Verbindungen vom Apache und Applicationserver verschlüsselt haben will.

Dazu müsste man AJP über stunnel verschlüsseln. Dies ist nicht unbdeding die beste Lösung da wir dadurch eine Störungsursache mehr haben könnten. Deshalb kann man auch per mod_proxy einfach direkt per SSL verschlüsseln indem man auf den HTTPS-Port von den Applicationserver zugreift.

Dazu sollten folg. Apache-Module geladen sein:

proxy_balancer
proxy
proxy_connect
proxy_http

Die Konfiguration sieht dann im entsprechenden vHost so aus:

<Proxy balancer://cluster>
        BalancerMember https://192.168.1.100:38181 route=glassfish-instance1
        BalancerMember https://192.168.1.200:38181 route=glassfish-instance2
</Proxy>

ProxyPass /pfadderanwendung balancer://cluster/pfadderanwendung stickysession=JSESSIONID

<Location /balancer-manager>
    SetHandler balancer-manager
    Order deny,allow
    Deny from All
    Allow from 192.168.1.0/24
</Location>
<Proxy *>
  Order allow,deny
  Allow from all
</Proxy>

Als erstes wird das Cluster definiert und gleich danach per ProxyPass die Anwendung verteilt.

Der balancer-manger ist sehr nützlich. Damit kann man die einzelne Member aus dem Loadbalancing aktivieren oder deaktivieren.

Tests

Besonderheiten

64 Bit

Für 64 Bit muss man wohl ein extra Kapitel schreiben. :)

Es klappt auf jedenfall nicht da man noch sunpkcs11.jar nach /jre/lib/ext/ kopieren muss (man sollte das 32 Bit jdk vorher kopiert haben und von da sunpkcs11.jar nehmen).

Java kann man auf Windows nicht mit -d64 in den 64 Bit-Modus versetzten. Man benötigt das 64 Bit JDK.

verhindern, dass sich Glassfish bei LogOut beendet

Defaultmäßig nimmt die JVM signale vom Windows entgegen wenn man sich ausloggen will oder den Server restartet. Das bedeutet, dass sich Glassfish immer herunterfährt wenn man sich ausloggt. Diese Funktion kann man aber durch ein JVM-Feature ausschalten:

  • Öffnen von <GF_HOME>\domains\domain1\config\domain.xml und suchen des Abschnittes mit den ganzen <jvm-options>paar JVM options</jvm-options>.
  • Folg. Zeile hinzufügen:
 <jvm-options>-Xrs</jvm-options>
  • Speichern und schliessen.
  • Glassfish restarten

BUG:

Bei einigen Windows 2003 Server-Installationen scheint dies nicht richtig zu funktionieren.

In diesem Fall sollte man die jvm-option in <GF_HOME>\lib\processLauncher.xml eintragen:

 <process name="as9-server">
    ...
    <sysproperty key="-Xrs"/>
    ...


Meine Werkzeuge