In questo articolo propongo un quick tutorial di 3 passi per configurare un Server Web Apache come bilanciatore di carico http su una coppia di Server Tomcat. La soluzione adottata si basa sull’utilizzo del connettore mod_jk di Apache Software Foundation. Per garantire la persistenza sulla stessa SessionID, il load balancer viene configurato in modalità sticky_session=TRUE. Questa impostazione è molto utile nel caso di applicazioni web che necessitano di sessioni autenticate. Di seguito una visione ad alto livello dell’architettura.
Stack applicativo
– Operative System: CentOS 6.x 64bit
– Apache Web Server: 2.2.15
– Tomcat Server: 6
– Mod JK connector: 1.2.37
– JDK: 1.6
STEP 1. Configurazione Tomcat Server01 – IP 10.10.1.100
# Define the jvmRoute for Tomcat 01 instance $ vi Tomcat_home/conf/server.xml:
<Server port="8005" shutdown="SHUTDOWN"> ... <Service name="Catalina"> ... <!-- Define an AJP 1.3 Connector on port 8009 --> <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> ... <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat01"> ... </Engine> </Service> </Server>
Pagina jsp di test per verificare il balancer.
$ vi tomcat_home/webapps/test-balancer/index.jsp
<html> <body> <%@ page import="java.net.InetAddress" %> <h1><font color="red">Session serviced by NODE_01</font></h1> <table align="center" border="1"> <tr> <td> Session ID </td> <td> <%= session.getId() %></td> </td> <% session.setAttribute("abc","abc");%> </tr> <tr> <td> Created on </td> <td> <%= session.getCreationTime() %> </td> </tr> <tr> <td> Hostname: </td> <td> <% InetAddress ia = InetAddress.getLocalHost(); out.println(ia.getHostName()); %> </td> </tr> </table> </body> </html>
STEP 2. Configurazione Tomcat Server-02 – IP 10.10.1.200
Le configurazioni sono le stesse fatte per l’istanza Tomcat 01. Fare attenzione alla definizione della proprietà jvmRoute.
# Define the jvmRoute for Tomcat 02 instance $ vi Tomcat_home/conf/server.xml:
<Server port="8005" shutdown="SHUTDOWN"> ... <Service name="Catalina"> ... <!-- Define an AJP 1.3 Connector on port 8009 --> <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> ... <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat02"> ... </Engine> </Service> </Server>
Pagina jsp di test per verificare il balancer.
$ vi tomcat_home/webapps/test-balancer/index.jsp
<html> <body> <%@ page import="java.net.InetAddress" %> <h1><font color="red">Session serviced by NODE_02</font></h1> <table align="center" border="1"> ....
STEP 3. Configurazione Apache Web Server e mod_jk – IP 10.10.1.50
# Setup Apache and some required libraries required to compile the mod_jk source code. $ yum install httpd httpd-devel apr apr-devel apr-util apr-util-devel gcc gcc-c++ make autoconf openssh*
# Download mod_jk source $ wget http://apache.fis.uniroma2.it/tomcat/tomcat-connectors/jk/tomcat-connectors-1.2.37-src.tar.gz
# Compile source and install the mod_jk $ tar xzvf tomcat−connectors−1.2.32−src.tar.gz $ cd tomcat−connectors−1.2.32−src/native $ ./configure --with-apxs=/usr/sbin/apxs ] $ make $ make install
# Configure mod_jk properties and VirtualHost definition $ nano /etc/httpd/conf.d/mod_jk.conf
LoadModule jk_module "/usr/lib64/httpd/modules/mod_jk.so" JkWorkersFile "/etc/httpd/conf.d/worker.properties" JkLogFile "/var/log/httpd/mod_jk.log" JkLogLevel emerg NameVirtualHost *:80 <VirtualHost *:80> ServerName mysite.com JkMount /* bal1 RewriteEngine On </VirtualHost>
#Configure the balancer workers $ nano /etc/httpd/conf.d/worker.properties
worker.list = bal1,stat1 worker.bal1.type=lb worker.bal1.sticky_session=1 worker.bal1.balance_workers=tomcat01,tomcat02 worker.stat1.type=status worker.tomcat01.type=ajp13 worker.tomcat01.host=tomcat-host01 worker.tomcat01.port=8009 worker.tomcat01.lbfactor=10 worker.tomcat02.type=ajp13 worker.tomcat02.host=tomcat-host02 worker.tomcat02.port=8009 worker.tomcat02.lbfactor=10
Configurazione record dns nel file /etc/host. Questa impostazione va fatta sulle 3 macchine lato server. Per effettuare invece il test del balancer via browser, è sufficiente aggiungere solo la prima entry sulla macchina client.
vi /etc/hosts 10.10.1.50 mysite.com 10.10.1.100 tomcat-host01 10.10.1.200 tomcat-host02
Per il test del balancer aprire un browser e puntare alla url http://mysite.com/test-balancer/index.jsp. Il server dovrebbe risponde con una pagina che stampa la Session ID aperta, un timestamp e l’hostname del server su cui è atterrata la richiesta.
Il balancer Apache bilancia le request in modalità random. Svuotare la cache del browser e aggiornare la pagina. Eseguendo più volte queste operazioni, la richiesta dovrebbe atterrare sul server dove è in esecuzione la seconda istanza del Tomcat visualizzando una pagina come questa.
Complimenti per la semplicità del tutorial
Grazie Davide,
cerco di mettere online procedure che uso quotidianamente in ambito lavorativo. Di solito butto giù solo qualche appunto su semplici file di testo…
😉
Ciao riesumo il post, perchè comunque molto attuale e ti faccio una domanda: teoricamente in regime di Loadbalancing, anche le webapps, quindi compresa quella che ti indica la sessione, dovrebbeero essere condivise tra i 2 tomcat; ovvero la folder webapps, dovrebbe essere comune ai 2 tomcat. Quindi userei una sola pagina di test. Di conseguenza, se non errro, dovrei eseguendo più volte il test, atterrare talvolta sul primo tomcat talvolta sul secondo evidenziato quindi dalla riga dell’hostname.
Corretto?
Ciao Fabrizio,
la tua osservazione è assolutamente giusta.
Dal punto di vista implementativo, le due istanze di Tomcat utilizzano la stessa webapp. E’ sufficiente quindi nello step 2, fare un copia e incolla della pagina JSP riportata per esteso nello step 1. Dopodichè sarà compito di InetAddress recuperare il nome dell’host su cui atterrano le richieste e stamparlo sulla pagina a runtime.
Grazie per il commento.