In dem Blogeintrag Loadbalancing mit Apache2 + Tomcat 6 + mod_jk 1.2.X habe ich beschrieben wie ein Loadbalancing mit dem “mod_jk” Module eingerichtet werden kann. Dieser Blogeintrag verfolgt das gleich Ziel, jedoch nicht mit dem “mod_jk” sondern mit dem “mod_proxy” Modul.
Im gegensatz zum “mod_jk” Modul muss das “mod_proxy” Modul nicht von einer externen Quelle heruntergeladen werden, es ist beim apache2 Webserver dabei. Unter Debian muss gegebenenfalls noch folgendes Kommando angesetzt werden.
apt-get install apache-modules
Ein Loadbalancing macht nur Sinn, wenn mindestens zwei Tomcats die gleiche Applikation ausliefern. Der Blogeintrag N Tomcats auf einer Maschine beschreibt wie zwei Tomcats zu konfigurieren sind damit sie parallel auf der selben Maschine laufen.
Gehen wir davon aus das wir eine Webapplikation namens “geo” haben die auf den zwei Tomcats “tomcat1″ und “tomcat2″ laufen. die “server.xml” von tomcat1 hat folgenden Eintrag:
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1" >
und die von tomcat2 dementsprechend:
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat2" >
Ganz wichtig hierbei ist das Attribut “jvmRoute”, in dem der Name des jeweiligen Tomcats gesetzt ist. Auf diesen Namen wird aus dem apache2 Webserver heraus referenziert.
In der Konfigurationsdatei des apache2, meisstens “/etc/apache2/httpd.conf” oder “/etc/apache2/apache.conf”, muss das “mod_proxy” Modul geladen werden. Das kann so aussehen:
LoadModule proxy_module libexec/apache2/mod_proxy.so
LoadModule proxy_connect_module libexec/apache2/mod_proxy_connect.so
LoadModule proxy_ftp_module libexec/apache2/mod_proxy_ftp.so
LoadModule proxy_http_module libexec/apache2/mod_proxy_http.so
LoadModule proxy_ajp_module libexec/apache2/mod_proxy_ajp.so
LoadModule proxy_balancer_module libexec/apache2/mod_proxy_balancer.so
Hier wird ein wenig mehr geladen als nur das reine “mod_proxy” Modul. Die Pfade muessen natuerlich an das entsprechende Betriebssystem angepasst sein.
Nach dem erfolgreichen laden des Moduls kann der Loadbalancer konfiguriert werden.
ProxyPass /geo balancer://apacheBalance stickysession=JSESSIONID
<Proxy balancer://apacheBalance>
BalancerMember ajp://localhost:8009/geo route=tomcat1 loadfactor=50
BalancerMember ajp://localhost:8010/geo route=tomcat2 loadfactor=50
</Proxy>
In der ersten Zeile wird der Webserver angewiesen alle Anfragen mit der URI “geo” an den balancer mit dem Namen “apacheBalance” zu delegieren, der im Abschnitt weiter unten definiert ist. Der Balancer kann beliebig viele “BalancerMember” haben und unterstuetzt nicht nur das ajp Protokoll sondern auch http. Das Attribut “route” im BalancerMember referenziert auf den “jvmRoute” des Tomcats, die wir weiter oben eingestellt haben.
Der “loadfactor” muss ein Wert zwischen 0 und 100 sein und legt die Lastverteilung fest. Wenn beide balancer einen Wert von 50 haben, dann wird die Last gleich verteilt. Wuerde der “tomcat1″ einen loadfactor von 10 haben und der andere einen loadfactor von 90, dann wuerde “tomcat2″ neunmal mehr Last bekommen als “tomcat1″.
Die Applikation ist nun ueber die URL “http://localhost/geo” erreichbar.
Bei der ersten Anfrage leitet der apache2 auf eines der BalancerMember weiter, z.B. tomcat2. Alle weiteren Anfragen von dem gleichen Client werden ebenfalls an den tomcat2 weitergeleitet, sofern eine HttpSession benutzt wird. Um sich zu merken welche Clients zu welchen Tomcat weitegeleitet werden sollen, legt apache2 eine Cookie beim Cleint an. Dieser Cookie besteht aus der SessionId und dem Namen des jeweiligen Tomcats.

Bei allen weiteren Anfragen wird dieser Cookie mitgeschickt und so weis der apache2 immer genau an welchen Tomcat er die Anfrage weiterleiten soll. Dieses Verhalten macht natuerlich nur Sinn wenn die Webapplikation Kundendaten in einer HttpSession vorhaelt. Wenn das nicht der Fall ist, ist es vollkommen egal an welches der beiden Tomcats die nachfolgenden Anfragen weitergeleitet werden.
Und genau hier liegt der Vorteil vom “mod_proxy” Modul gegenueber dem “mod_jk” Modul. Mod_proxy haengt im Cookie nur dann den Namen des Tomcats an die SessionId wenn die HttpSession nicht leer ist.
Ein weiterer Vorteil des Moduls ist der balancer-manager, eine kleine Webanwendung die den aktuellen Status des Balancers zeigt. Um die Applikation einzubinden muss folgender Eintrag in die apache2 Konfigurationsdatei hinzugefuegt werden.
<Location /balancer-manager>
SetHandler balancer-manager
</Location>
Nach der Aenderung muss der apache2 natuerlich neu gestartet werden und dannach ist die Anwendung uber die URL “http://localhost/balancer-manager” erreichbar.

Ueber den Balancer-Manager kann auch zur Laufzeit der loadfactor veraendert werden. Soll einer der beiden Tomcats (tomcat2) aus bestimmten Gruenden vom Netz genommen werden, sollte dieser einen loadfactor von 1 zugewiesen bekommen und der andere einen loadfactor von 99. Damit ist sichergestellt das alle weietern Requests an den Tomcat mit dem loadfactor 99 weitergeleitet werden. Nach einer gewissen Zeit sind auf dem tomcat2 keine HttpSessions mehr offen und er kann problemlos vom Netz genommen werden.
Um den unbefugten Zugriff auf den balancer-manager zu verhindern sollte er durch ein Passwort geschuetzt werden.
<Location /balancer-manager>
SetHandler balancer-manager
AuthType Basic
AuthName "balancer manager "
AuthUserFile /etc/apache2/htpassbalancer
Require valid-user
</Location>
Die Passwortdatei kann mit folgendem Kommando angelegt werdne.
htpasswd -c /etc/apache2/htpassbalancer username