Apache2 (balanceo y compartición de carga) y Tomcat6 (cluster)

Esquema funcional de balanceo entre 2 apaches y cluster de 4 tomcats, cada servidor provisto de Alta Disponibilidad

En una próxima actualización veremos como prescindir de la HA mediante DRBD y Heartbeat, y del cluster en Tomcat, para conseguir de una forma mucho mas simple y efectiva la alta disponibilidad mediante el balanceo de ambos servicios por parte del router (suponiendo que tenga persistencia de sesiones), y con la ayuda de NFS compartiremos los directorios de trabajo de ambos servicios.

Nos basamos en que Apache y Tomcat ya están instalados en sus correspondientes servidores, y que la configuración relativa a la HA se ha aplicado según se explica en el artículo:
http://luismido.wikidot.com/drbd

En este caso contamos con 8 servidores:

Nodo1, Nodo2, Nodo3 y Nodo4: Apache, Tomcat, DRBD, Heartbeat
Nodo5, Nodo6, Nodo7 y Nodo8: Tomcat, DRBD, Heartbeat

Nodo1: 192.168.0.21
Nodo2: 192.168.0.22
VIP: 192.168.0.88

Nodo3: 192.168.0.23
Nodo4: 192.168.0.24
VIP: 192.168.0.89

Nodo5: 192.168.0.25
Nodo6: 192.168.0.26
VIP: 192.168.0.90

Nodo7: 192.168.0.27
Nodo8: 192.168.0.28
VIP: 192.168.0.91

El balanceo de carga hacia Apache lo hace el router. Al haber 2 servidores Apache, no haría falta que cada uno tuviera su sistema de HA (Nodo2 y Nodo4), siempre y cuando solo estuviera apache, ya que al utilizarlos para ofrecer a la vez Tomcat, este si necesita su sistema de HA ya que si se queda bloqueado, se cae… habría un nodo muerto y no serviría las peticiones que le llegaran.

Tener en cuenta que este sistema es escalable, tanto a nivel de Apache (configurar el balanceo en el router y en el nuevo servidor) como de Tomcat (agregar nuevo sistema de HA y configurar en Apache y Tomcat el nuevo sistema).

Existen dos tipos de cluster que podemos construir en Tomcat:

- cluster vertical (en una sola máquina).
- cluster horizontal (en máquinas independientes).

Aunque en este ejemplo nos basemos en el cluster horizontal vamos a mencionar por encima ambos casos:

Cluster vertical

En este ejemplo consideramos un cluster de 4 nodos, por lo que necesitaremos instalar cuatro instancias de Tomcat las cuales llamaremos: tomcatNodo1, tomcatNodo2, tomcatNodo3 y tomcatNodo4.

Una vez instalados, deberemos realizar una pequeña modificación en el archivo server.xml de cada uno de los nodos. Este archivo se encuentra en la carpeta "conf" de cada uno de los nodos.

Para cada uno de los server.xml deberemos realizar los siguientes cambios:

Cambiar los puertos

<server port="XXXX" shutdown="SHUTDOWN">  

    <connector port="XXXX" protocol="HTTP/1.1" connectiontimeout="20000" redirectport="8443">  

    <connector port="XXXX" protocol="AJP/1.3" redirectport="8443">

Agregar "jvmRoute" para cada caso.

<engine name="Catalina" defaulthost="localhost" jvmroute="tomcatNodoX">

Descomentar el tag "cluster"

<cluster classname="org.apache.catalina.ha.tcp.SimpleTcpCluster">

tomcatNodo1

<!-- Note:  A "Server" is not itself a "Container", so you may not      define subcomponents such as "Valves" at this level.      Documentation at /docs/config/server.html  -->

<server port="8015" shutdown="SHUTDOWN">

  <!--APR library loader. Documentation at /docs/apr.html -->

  <listener classname="org.apache.catalina.core.AprLifecycleListener" sslengine="on">

  <!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->

  <listener classname="org.apache.catalina.core.JasperListener">

  <!-- JMX Support for the Tomcat server. Documentation at /docs/non-existent.html -->

  <listener classname="org.apache.catalina.mbeans.ServerLifecycleListener">

  <listener classname="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener">

  <!-- Global JNDI resources        Documentation at /docs/jndi-resources-howto.html   -->

  <globalnamingresources>

    <!-- Editable user database that can also be used by          UserDatabaseRealm to authenticate users     -->

    <resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" pathname="conf/tomcat-users.xml">

  </globalnamingresources>

  <!-- A "Service" is a collection of one or more "Connectors" that share        a single "Container" Note:  A "Service" is not itself a "Container",         so you may not define subcomponents such as "Valves" at this level.        Documentation at /docs/config/service.html    -->

  <service name="Catalina">

    <!-- A "Connector" represents an endpoint by which requests are received          and responses are returned. Documentation at :          Java HTTP Connector: /docs/config/http.html (blocking &amp; non-blocking)          Java AJP  Connector: /docs/config/ajp.html          APR (HTTP/AJP) Connector: /docs/apr.html          Define a non-SSL HTTP/1.1 Connector on port 8080     -->

    <connector port="8081" protocol="HTTP/1.1" maxthreads="150" connectiontimeout="20000" redirectport="8443">

    <!-- Define a SSL HTTP/1.1 Connector on port 8443          This connector uses the JSSE configuration, when using APR, the           connector should be using the OpenSSL style configuration          described in the APR documentation -->

    <!--     <connector port="8443" protocol="HTTP/1.1" sslenabled="true" maxthreads="150" scheme="https" secure="true" clientauth="false" sslprotocol="TLS">

    -->

    <!-- Define an AJP 1.3 Connector on port 8009 -->

    <connector port="8109" protocol="AJP/1.3" redirectport="8443">

    <!-- An Engine represents the entry point (within Catalina) that processes          every request.  The Engine implementation for Tomcat stand alone          analyzes the HTTP headers included with the request, and passes them          on to the appropriate Host (virtual host).          Documentation at /docs/config/engine.html -->

    <!-- You should set jvmRoute to support load-balancing via AJP ie : -->

    <engine name="Standalone" defaulthost="localhost" jvmroute="tomcatNodo1">         

    <engine name="Catalina" defaulthost="localhost">

      <!--For clustering, please take a look at documentation at:           /docs/cluster-howto.html  (simple how to)           /docs/config/cluster.html (reference documentation) -->

      <cluster classname="org.apache.catalina.ha.tcp.SimpleTcpCluster">

      <!-- The request dumper valve dumps useful debugging information about            the request and response data received and sent by Tomcat.            Documentation at: /docs/config/valve.html -->

      <!--       <valve classname="org.apache.catalina.valves.RequestDumperValve">

      -->

      <!-- This Realm uses the UserDatabase configured in the global JNDI            resources under the key "UserDatabase".  Any edits            that are performed against this UserDatabase are immediately            available for use by the Realm.  -->

      <realm classname="org.apache.catalina.realm.UserDatabaseRealm" resourcename="UserDatabase">

      <!-- Define the default virtual host            Note: XML Schema validation will not work with Xerces 2.2.        -->

      <host name="localhost" appbase="webapps" unpackwars="true" autodeploy="true" xmlvalidation="false" xmlnamespaceaware="false">

        <!-- SingleSignOn valve, share authentication between web applications              Documentation at: /docs/config/valve.html -->

        <!--         <valve classname="org.apache.catalina.authenticator.SingleSignOn">

        -->

        <!-- Access log processes all example.              Documentation at: /docs/config/valve.html -->

        <!--         <valve classname="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log." suffix=".txt" pattern="common" resolvehosts="false">

        -->

      </host>

    </engine>

  </service>

</server>

tomcatNodo2

<!-- Note:  A "Server" is not itself a "Container", so you may not      define subcomponents such as "Valves" at this level.      Documentation at /docs/config/server.html  -->

<server port="8205" shutdown="SHUTDOWN">

  <!--APR library loader. Documentation at /docs/apr.html -->

  <listener classname="org.apache.catalina.core.AprLifecycleListener" sslengine="on">

  <!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->

  <listener classname="org.apache.catalina.core.JasperListener">

  <!-- JMX Support for the Tomcat server. Documentation at /docs/non-existent.html -->

  <listener classname="org.apache.catalina.mbeans.ServerLifecycleListener">

  <listener classname="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener">

  <!-- Global JNDI resources        Documentation at /docs/jndi-resources-howto.html   -->

  <globalnamingresources>

    <!-- Editable user database that can also be used by          UserDatabaseRealm to authenticate users     -->

    <resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" pathname="conf/tomcat-users.xml">

  </globalnamingresources>

  <!-- A "Service" is a collection of one or more "Connectors" that share        a single "Container" Note:  A "Service" is not itself a "Container",         so you may not define subcomponents such as "Valves" at this level.        Documentation at /docs/config/service.html    -->

  <service name="Catalina">

    <!-- A "Connector" represents an endpoint by which requests are received          and responses are returned. Documentation at :          Java HTTP Connector: /docs/config/http.html (blocking &amp; non-blocking)          Java AJP  Connector: /docs/config/ajp.html          APR (HTTP/AJP) Connector: /docs/apr.html          Define a non-SSL HTTP/1.1 Connector on port 8080     -->

    <connector port="8082" protocol="HTTP/1.1" maxthreads="150" connectiontimeout="20000" redirectport="8443">

    <!-- Define a SSL HTTP/1.1 Connector on port 8443          This connector uses the JSSE configuration, when using APR, the           connector should be using the OpenSSL style configuration          described in the APR documentation -->

    <!--     <connector port="8443" protocol="HTTP/1.1" sslenabled="true" maxthreads="150" scheme="https" secure="true" clientauth="false" sslprotocol="TLS">

    -->

    <!-- Define an AJP 1.3 Connector on port 8009 -->

    <connector port="8209" protocol="AJP/1.3" redirectport="8443">

    <!-- An Engine represents the entry point (within Catalina) that processes          every request.  The Engine implementation for Tomcat stand alone          analyzes the HTTP headers included with the request, and passes them          on to the appropriate Host (virtual host).          Documentation at /docs/config/engine.html -->

    <!-- You should set jvmRoute to support load-balancing via AJP ie : --> 

    <engine name="Standalone" defaulthost="localhost" jvmroute="tomcatNodo2">         

    <engine name="Catalina" defaulthost="localhost">

      <!--For clustering, please take a look at documentation at:           /docs/cluster-howto.html  (simple how to)           /docs/config/cluster.html (reference documentation) -->

      <cluster classname="org.apache.catalina.ha.tcp.SimpleTcpCluster">

      <!-- The request dumper valve dumps useful debugging information about            the request and response data received and sent by Tomcat.            Documentation at: /docs/config/valve.html -->

      <!--       <valve classname="org.apache.catalina.valves.RequestDumperValve">

      -->

      <!-- This Realm uses the UserDatabase configured in the global JNDI            resources under the key "UserDatabase".  Any edits            that are performed against this UserDatabase are immediately            available for use by the Realm.  -->

      <realm classname="org.apache.catalina.realm.UserDatabaseRealm" resourcename="UserDatabase">

      <!-- Define the default virtual host            Note: XML Schema validation will not work with Xerces 2.2.        -->

      <host name="localhost" appbase="webapps" unpackwars="true" autodeploy="true" xmlvalidation="false" xmlnamespaceaware="false">

        <!-- SingleSignOn valve, share authentication between web applications              Documentation at: /docs/config/valve.html -->

        <!--         <valve classname="org.apache.catalina.authenticator.SingleSignOn">

        -->

        <!-- Access log processes all example.              Documentation at: /docs/config/valve.html -->

        <!--         <valve classname="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log." suffix=".txt" pattern="common" resolvehosts="false">

        -->

      </host>

    </engine>

  </service>

</server>

tomcatNodo3

<!-- Note:  A "Server" is not itself a "Container", so you may not      define subcomponents such as "Valves" at this level.      Documentation at /docs/config/server.html  -->

<server port="8305" shutdown="SHUTDOWN">

  <!--APR library loader. Documentation at /docs/apr.html -->

  <listener classname="org.apache.catalina.core.AprLifecycleListener" sslengine="on">

  <!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->

  <listener classname="org.apache.catalina.core.JasperListener">

  <!-- JMX Support for the Tomcat server. Documentation at /docs/non-existent.html -->

  <listener classname="org.apache.catalina.mbeans.ServerLifecycleListener">

  <listener classname="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener">

  <!-- Global JNDI resources        Documentation at /docs/jndi-resources-howto.html   -->

  <globalnamingresources>

    <!-- Editable user database that can also be used by          UserDatabaseRealm to authenticate users     -->

    <resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" pathname="conf/tomcat-users.xml">

  </globalnamingresources>

  <!-- A "Service" is a collection of one or more "Connectors" that share        a single "Container" Note:  A "Service" is not itself a "Container",         so you may not define subcomponents such as "Valves" at this level.        Documentation at /docs/config/service.html    -->

  <service name="Catalina">

    <!-- A "Connector" represents an endpoint by which requests are received          and responses are returned. Documentation at :          Java HTTP Connector: /docs/config/http.html (blocking &amp; non-blocking)          Java AJP  Connector: /docs/config/ajp.html          APR (HTTP/AJP) Connector: /docs/apr.html          Define a non-SSL HTTP/1.1 Connector on port 8080     -->

    <connector port="8083" protocol="HTTP/1.1" maxthreads="150" connectiontimeout="20000" redirectport="8443">

    <!-- Define a SSL HTTP/1.1 Connector on port 8443          This connector uses the JSSE configuration, when using APR, the           connector should be using the OpenSSL style configuration          described in the APR documentation -->

    <!--     <connector port="8443" protocol="HTTP/1.1" sslenabled="true" maxthreads="150" scheme="https" secure="true" clientauth="false" sslprotocol="TLS">

    -->

    <!-- Define an AJP 1.3 Connector on port 8009 -->

    <connector port="8309" protocol="AJP/1.3" redirectport="8443">

    <!-- An Engine represents the entry point (within Catalina) that processes          every request.  The Engine implementation for Tomcat stand alone          analyzes the HTTP headers included with the request, and passes them          on to the appropriate Host (virtual host).          Documentation at /docs/config/engine.html -->

    <!-- You should set jvmRoute to support load-balancing via AJP ie : --> 

    <engine name="Standalone" defaulthost="localhost" jvmroute="tomcatNodo3">         

    <engine name="Catalina" defaulthost="localhost">

      <!--For clustering, please take a look at documentation at:           /docs/cluster-howto.html  (simple how to)           /docs/config/cluster.html (reference documentation) -->

      <cluster classname="org.apache.catalina.ha.tcp.SimpleTcpCluster">

      <!-- The request dumper valve dumps useful debugging information about            the request and response data received and sent by Tomcat.            Documentation at: /docs/config/valve.html -->

      <!--       <valve classname="org.apache.catalina.valves.RequestDumperValve">

      -->

      <!-- This Realm uses the UserDatabase configured in the global JNDI            resources under the key "UserDatabase".  Any edits            that are performed against this UserDatabase are immediately            available for use by the Realm.  -->

      <realm classname="org.apache.catalina.realm.UserDatabaseRealm" resourcename="UserDatabase">

      <!-- Define the default virtual host            Note: XML Schema validation will not work with Xerces 2.2.        -->

      <host name="localhost" appbase="webapps" unpackwars="true" autodeploy="true" xmlvalidation="false" xmlnamespaceaware="false">

        <!-- SingleSignOn valve, share authentication between web applications              Documentation at: /docs/config/valve.html -->

        <!--         <valve classname="org.apache.catalina.authenticator.SingleSignOn">

        -->

        <!-- Access log processes all example.              Documentation at: /docs/config/valve.html -->

        <!--         <valve classname="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log." suffix=".txt" pattern="common" resolvehosts="false">

        -->

      </host>

    </engine>

  </service>

</server>

tomcatNodo4

<!-- Note:  A "Server" is not itself a "Container", so you may not      define subcomponents such as "Valves" at this level.      Documentation at /docs/config/server.html  -->

<server port="8405" shutdown="SHUTDOWN">

  <!--APR library loader. Documentation at /docs/apr.html -->

  <listener classname="org.apache.catalina.core.AprLifecycleListener" sslengine="on">

  <!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->

  <listener classname="org.apache.catalina.core.JasperListener">

  <!-- JMX Support for the Tomcat server. Documentation at /docs/non-existent.html -->

  <listener classname="org.apache.catalina.mbeans.ServerLifecycleListener">

  <listener classname="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener">

  <!-- Global JNDI resources        Documentation at /docs/jndi-resources-howto.html   -->

  <globalnamingresources>

    <!-- Editable user database that can also be used by          UserDatabaseRealm to authenticate users     -->

    <resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" pathname="conf/tomcat-users.xml">

  </globalnamingresources>

  <!-- A "Service" is a collection of one or more "Connectors" that share        a single "Container" Note:  A "Service" is not itself a "Container",         so you may not define subcomponents such as "Valves" at this level.        Documentation at /docs/config/service.html    -->

  <service name="Catalina">

    <!-- A "Connector" represents an endpoint by which requests are received          and responses are returned. Documentation at :          Java HTTP Connector: /docs/config/http.html (blocking &amp; non-blocking)          Java AJP  Connector: /docs/config/ajp.html          APR (HTTP/AJP) Connector: /docs/apr.html          Define a non-SSL HTTP/1.1 Connector on port 8080     -->

    <connector port="8084" protocol="HTTP/1.1" maxthreads="150" connectiontimeout="20000" redirectport="8443">

    <!-- Define a SSL HTTP/1.1 Connector on port 8443          This connector uses the JSSE configuration, when using APR, the           connector should be using the OpenSSL style configuration          described in the APR documentation -->

    <!--     <connector port="8443" protocol="HTTP/1.1" sslenabled="true" maxthreads="150" scheme="https" secure="true" clientauth="false" sslprotocol="TLS">

    -->

    <!-- Define an AJP 1.3 Connector on port 8009 -->

    <connector port="8409" protocol="AJP/1.3" redirectport="8443">

    <!-- An Engine represents the entry point (within Catalina) that processes          every request.  The Engine implementation for Tomcat stand alone          analyzes the HTTP headers included with the request, and passes them          on to the appropriate Host (virtual host).          Documentation at /docs/config/engine.html -->

    <!-- You should set jvmRoute to support load-balancing via AJP ie : --> 

    <engine name="Standalone" defaulthost="localhost" jvmroute="tomcatNodo4">         

    <engine name="Catalina" defaulthost="localhost">

      <!--For clustering, please take a look at documentation at:           /docs/cluster-howto.html  (simple how to)           /docs/config/cluster.html (reference documentation) -->

      <cluster classname="org.apache.catalina.ha.tcp.SimpleTcpCluster">

      <!-- The request dumper valve dumps useful debugging information about            the request and response data received and sent by Tomcat.            Documentation at: /docs/config/valve.html -->

      <!--       <valve classname="org.apache.catalina.valves.RequestDumperValve">

      -->

      <!-- This Realm uses the UserDatabase configured in the global JNDI            resources under the key "UserDatabase".  Any edits            that are performed against this UserDatabase are immediately            available for use by the Realm.  -->

      <realm classname="org.apache.catalina.realm.UserDatabaseRealm" resourcename="UserDatabase">

      <!-- Define the default virtual host            Note: XML Schema validation will not work with Xerces 2.2.        -->

      <host name="localhost" appbase="webapps" unpackwars="true" autodeploy="true" xmlvalidation="false" xmlnamespaceaware="false">

        <!-- SingleSignOn valve, share authentication between web applications              Documentation at: /docs/config/valve.html -->

        <!--         <valve classname="org.apache.catalina.authenticator.SingleSignOn">

        -->

        <!-- Access log processes all example.              Documentation at: /docs/config/valve.html -->

        <!--         <valve classname="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log." suffix=".txt" pattern="common" resolvehosts="false">

        -->

      </host>

    </engine>

  </service>

</server>

Con estos cambios ya tenemos configurado nuestro cluster vertical.

Cluster horizontal

La configuración de un cluster horizontal es más fácil ya que no es necesario realizar cambios a los puertos.

Para cada uno de los archivos server.xml se debe realizar los siguientes cambios:

Agregar "jvmRoute" para cada caso (igual que para el cluster vertical)

<engine name="Catalina" defaulthost="localhost" jvmroute="tomcatNodoX">

Descomentar el tag "cluster" (igual que para el cluster vertical)

<cluster classname="org.apache.catalina.ha.tcp.SimpleTcpCluster">

Configuración del cluster con Apache

Una vez configurado el tipo de cluster, vamos a construir una pequeña aplicación de ejemplo.

El primer paso será definir en el web.xml de la aplicación el tag "<distributable />" para activar el intercambio de la sesión a través de la instancia del cluster.

<?xml version="1.0" encoding="ISO-8859-1"?>

<web-app xmlns="http://java.sun.com/xml/ns/javaee" xsi="http://www.w3.org/2001/XMLSchema-instance" schemalocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">

  <distributable />  

</web-app>

Ahora necesitaremos integrar el servidor web Apache con Tomcat mediante el modulo mod_jk:

LoadModule jk_module modules/mod_jk-1.2.26-httpd-2.2.4.so

JkWorkersFile "/ruta/hacia/workers.properties"

JkLogFile "/var/logs/apache2/mod_jk.log"

JkLogLevel error

JkMount /cluster loadbalancer

JkMount /cluster/* loadbalancer

El contenido del archivo workers.properties depende del tipo de cluster.

En el caso del cluster vertical:

workers.tomcat_home=/tomcatNodo1

workers.java_home=$JAVA_HOME

ps=/

worker.list=tomcatNodo1,tomcatNodo2,tomcatNodo3,tomcatNodo4,loadbalancer

worker.tomcatNodo1.port=8109

worker.tomcatNodo1.host=localhost

worker.tomcatNodo1.type=ajp13

worker.tomcatNodo1.lbfactor=1

worker.tomcatNodo2.port=8209

worker.tomcatNodo2.host=localhost

worker.tomcatNodo2.type=ajp13

worker.tomcatNodo2.lbfactor=1

worker.tomcatNodo3.port=8309

worker.tomcatNodo3.host=localhost

worker.tomcatNodo3.type=ajp13

worker.tomcatNodo3.lbfactor=1

worker.tomcatNodo3.port=8409

worker.tomcatNodo3.host=localhost

worker.tomcatNodo3.type=ajp13

worker.tomcatNodo3.lbfactor=1

worker.loadbalancer.type=lb

worker.loadbalancer.balanced_workers=tomcatNodo1,tomcatNodo2,tomcatNodo3,tomcatNodo4

worker.loadbalancer.sticky_session=1

En el caso del cluster horizontal, se debe definir el host para cada uno de los nodos del cluster:

workers.tomcat_home=/tomcatNodo1

workers.java_home=$JAVA_HOME

ps=/

worker.list=tomcatNodo1,tomcatNodo2,tomcatNodo3,tomcatNodo4,loadbalancer

worker.tomcatNodo1.port=8009

worker.tomcatNodo1.host=192.168.0.88

worker.tomcatNodo1.type=ajp13

worker.tomcatNodo1.lbfactor=1

worker.tomcatNodo2.port=8009

worker.tomcatNodo2.host=192.168.0.89

worker.tomcatNodo2.type=ajp13

worker.tomcatNodo2.lbfactor=1

worker.tomcatNodo3.port=8009

worker.tomcatNodo3.host=192.168.0.90

worker.tomcatNodo3.type=ajp13

worker.tomcatNodo3.lbfactor=1

worker.tomcatNodo4.port=8009

worker.tomcatNodo4.host=192.168.0.91

worker.tomcatNodo4.type=ajp13

worker.tomcatNodo4.lbfactor=1

worker.loadbalancer.type=lb

worker.loadbalancer.balanced_workers=tomcatNodo1,tomcatNodo2,tomcatNodo3,tomcatNodo4

worker.loadbalancer.sticky_session=1

Uno de los atributos más importantes es "Ibfactor", el cual define el factor para el balanceo de carga, restringiendo el numero de "request" a enviar a una instancia particular de Tomcat.

Por último, crearemos unas páginas JSP para cada uno de los nodos, con los cuales validaremos que el cluster este funcionado correctamente.

tomcatNodo1

<%   session.setAttribute("dukechile","dukechile"); %>

<html>

<head>

<title>DukeChile - Culster</title>

</head>

<body>

<table width="100%" border="0" cellspacing="0" cellpadding="0">

  <tr bgcolor="#CCCCCC">

    <td width="13%">Tomcat Nodo 1</td>

    <td width="87%"> </td>

  </tr>

  <tr>

    <td>Session ID :</td>

    <td><%=session.getId()%></td>

  </tr>

</table>

</body>

</html>

tomcatNodo2

<%   session.setAttribute("dukechile","dukechile"); %>

<html>

<head>

<title>DukeChile - Culster</title>

</head>

<body>

<table width="100%" border="0" cellspacing="0" cellpadding="0">

  <tr bgcolor="#CCCCCC">

    <td width="13%">Tomcat Nodo 2</td>

    <td width="87%"> </td>

  </tr>

  <tr>

    <td>Session ID :</td>

    <td><%=session.getId()%></td>

  </tr>

</table>

</body>

</html>

tomcatNodo3

<%   session.setAttribute("dukechile","dukechile"); %>

<html>

<head>

<title>DukeChile - Culster</title>

</head>

<body>

<table width="100%" border="0" cellspacing="0" cellpadding="0">

  <tr bgcolor="#CCCCCC">

    <td width="13%">Tomcat Nodo 3</td>

    <td width="87%"> </td>

  </tr>

  <tr>

    <td>Session ID :</td>

    <td><%=session.getId()%></td>

  </tr>

</table>

</body>

</html>

tomcatNodo4

<%   session.setAttribute("dukechile","dukechile"); %>

<html>

<head>

<title>DukeChile - Culster</title>

</head>

<body>

<table width="100%" border="0" cellspacing="0" cellpadding="0">

  <tr bgcolor="#CCCCCC">

    <td width="13%">Tomcat Nodo 4</td>

    <td width="87%"> </td>

  </tr>

  <tr>

    <td>Session ID :</td>

    <td><%=session.getId()%></td>

  </tr>

</table>

</body>

</html>

Por último, se debe reiniciar el Apache y luego iniciar cada una de las instancias del Tomcat.

Una vez los nodos estén iniciados, ejecutaremos la página cluster.jsp y validaremos el ID de la sesión asignada además del nombre del nodo que atendió la petición.

Recargamos nuevamente la pagina, y validamos que el ID de la sesión siga siendo la misma, con esto, validamos que el cluster este funcionado correctamente.

Ref: http://dukechile.blogspot.com/2008/06/tutorial-de-tomcat-en-cluster.html

NOTA: http://es.wikibooks.org/wiki/Cluster_Tomcat_HOWTO
En este artículo se menciona como compartir mediante NFS la carpeta en la que se guardan las sesiones de los servidores tomcat.

« Linux

Si no se indica lo contrario, el contenido de esta página se ofrece bajo Creative Commons Attribution-ShareAlike 3.0 License