Settembre 18, 2019

Tomcat load balancing con Apache Web Server e mod_jk

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.

 apache-load-balancer-mod-jk-00

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.

apache-load-balancer-mod-jk-01

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.

apache-load-balancer-mod-jk-02

 

Related posts

4 Comments

    1. Giuseppe Urso

      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…
      😉

  1. Fabrizio

    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?

    Reply
    1. Giuseppe

      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.

Leave a Reply

Your email address will not be published.