jueves, 21 de junio de 2012

Tomcat Cluster - HA

Hola!

En este post veremos como configurar dos Tomcats en diferentes servidores para hacerlos funcionar Cluster con sesiones replicadas.

Para este ejemplo usamos los servidores:

Server01 -> IP: 10.1.1.101
Server02 -> IP: 10.1.1.102

Para empezar descargaremos la última versión de Tomcat disponible,:
http://apache.rediris.es/tomcat/tomcat-7/v7.0.28/bin/apache-tomcat-7.0.28.tar.gz

Descargamos y descomprimimos el software en cada uno de los servidores en el destino que queramos, yo lo he puesto en /opt/www.

[root@SERVER01 ~]# mkdir /opt/www
[root@SERVER01 ~]# wget http://apache.rediris.es/tomcat/tomcat-7/v7.0.28/bin/apache-tomcat-7.0.28.tar.gz
[root@SERVER01 ~]# tar zxvf apache-tomcat-7.0.28.tar.gz




Configuración Server01

[root@SERVER01 ~]# vim /opt/www/apache-tomcat-7.0.28/conf/server.xml


Añadimos esta parte dentro de la etiqueta Host.

<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
         channelSendOptions="8">


          <Manager className="org.apache.catalina.ha.session.DeltaManager"
                   expireSessionsOnShutdown="false"
                   notifyListenersOnReplication="true"/>


          <Channel className="org.apache.catalina.tribes.group.GroupChannel">
               <Membership className="org.apache.catalina.tribes.membership.McastService"
                           address="228.0.0.4"
                           port="45564"
                           frequency="500"
                           dropTime="3000"/>
                 <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
                           address="10.1.1.101"
                           port="4000"
                           selectorTimeout="5000"
                           maxThreads="6"/>
            <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
            <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
            </Sender>
            <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
            <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
            </Channel>
          <Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=""/>
          <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>
          <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
                    tempDir="/tmp/war-temp/"
                    deployDir="/tmp/war-deploy/"
                    watchDir="/tmp/war-listen/"
                    watchEnabled="false"/>
          <ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>
          <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>

Configuración Server02


[root@SERVER02 ~]# vim /opt/www/apache-tomcat-7.0.28/conf/server.xml



Añadimos esta parte dentro de la etiqueta Host.

<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
         channelSendOptions="8">


          <Manager className="org.apache.catalina.ha.session.DeltaManager"
                   expireSessionsOnShutdown="false"
                   notifyListenersOnReplication="true"/>


          <Channel className="org.apache.catalina.tribes.group.GroupChannel">
               <Membership className="org.apache.catalina.tribes.membership.McastService"
                           address="228.0.0.4"
                           port="45564"
                           frequency="500"
                           dropTime="3000"/>
                 <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
                           address="10.1.1.102"
                           port="4000"
                           selectorTimeout="5000"
                           maxThreads="6"/>
            <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
            <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
            </Sender>
            <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
            <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
            </Channel>
          <Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=""/>
          <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>
          <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
                    tempDir="/tmp/war-temp/"
                    deployDir="/tmp/war-deploy/"
                    watchDir="/tmp/war-listen/"
                    watchEnabled="false"/>
          <ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>
          <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>

*Nota:

 <Membership /> es donde se especifica el miembro para conectar con los otros miembros del cluster, estos datos tienen que ser los mismos en todos los miembros del cluster.

 <Receiver /> aquí es donde se ponen los datos del servidor que quiere ser miembro del cluster, en cada servidor se tendrá que configurar su ip.

Arrancamos los servicios.

[root@SERVER01 ~]# /opt/www/apache-tomcat-7.0.28/bin/startup.sh

[root@SERVER02 ~]# /opt/www/apache-tomcat-7.0.28/bin/startup.sh

[root@SERVER01 ~]# tail -200f /opt/www/apache-tomcat-7.0.28/logs/catalina.out

INFO: Receiver Server Socket bound to:/10.1.1.101:4000
15-mar-2012 13:29:21 org.apache.catalina.tribes.membership.McastServiceImpl setupSocket
INFO: Setting cluster mcast soTimeout to 500
15-mar-2012 13:29:21 org.apache.catalina.tribes.membership.McastServiceImpl waitForMembers
INFO: Sleeping for 1000 milliseconds to establish cluster membership, start level:4
15-mar-2012 13:29:21 org.apache.catalina.ha.tcp.SimpleTcpCluster memberAdded
INFO: Replication member added:org.apache.catalina.tribes.membership.MemberImpl[tcp://{10, 1, 1, 102}:4000,{10, 1, 1, 102},
4000, alive=19531, securePort=-1, UDP Port=-1, id={-9 10 29 -58 25 -70 74 -56 -70 0 -6 -40 -89 69 62 -111 }, payload={}, command=
{}, domain={}, ]
15-mar-2012 13:29:22 org.apache.catalina.tribes.membership.McastServiceImpl waitForMembers
INFO: Done sleeping, membership established, start level:4
15-mar-2012 13:29:22 org.apache.catalina.tribes.membership.McastServiceImpl waitForMembers
INFO: Sleeping for 1000 milliseconds to establish cluster membership, start level:8
15-mar-2012 13:29:22 org.apache.catalina.tribes.io.BufferPool getBufferPool
INFO: Created a buffer pool with max size:104857600 bytes of type:org.apache.catalina.tribes.io.BufferPool15Impl
15-mar-2012 13:29:23 org.apache.catalina.tribes.membership.McastServiceImpl waitForMembers
INFO: Done sleeping, membership established, start level:8
15-mar-2012 13:29:23 org.apache.catalina.ha.deploy.FarmWarDeployer start
INFO: Cluster FarmWarDeployer started.

*Nota: Como se puede ver en el log, al arrancar los dos Tomcats los miembros se encuentran y se forma el cluster.

Configuración Aplicación.

Ahora lo único que falta es desplegar la aplicación que queramos configurar en alta disponibilidad, antes de desplegarla en cada uno de los tomcats, deberemos añadir la propiedad  <distributable /> en el web.xml de la aplicación.

[root@SERVER01 ~]# vim /opt/www/apache-tomcat/webapps/app1/WEB-INF/web.xml



<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
      version="3.0">
    <distributable />

Pruebas de sesión.

En las pruebas que se hacen en este ejemplo, hay un servidor web por delante que es el que le pasa las peticiones a los tomcat, por ejemplo un servidor web Apache pasando las conexiones con mod_jk. Si uno de los dos tomcat se cae Apache se da cuenta y solo le pasa el tráfico al que está vivo, cuando el servidor que se ha caído vuelve a responder, Apache vuelve a pasarle peticiones.

Ahora ya podemos desplegar la aplicación y empezar a hacer las pruebas de replicación de sesión.
Para las pruebas y para monitorizar las aplicaciones, recomiendo usar probe, es una aplicación que monitoriza en tiempo real los recursos del servidor Tomcat y las aplicaciones.
https://code.google.com/p/psi-probe/

En la pantalla principal vemos las aplicaciones desplegadas y las sesiones, nuestra aplicación en cluster es la "ap", que como vemos en la parte de la derecha en CLUSTERED está en YES.

Server01











Server02












Si pinchamos sobre "SESS" de la aplicación en cluster veremos que las sesiones coinciden en los dos servidores.

Server01












Server02

















Ahora solo falta que probemos nosotros mismos, si apagamos por ejemplo el tomcat del server01, veremos que en el server02 están los clientes funcionando, cuando levantamos el tomcat del server01, automáticamente las sesiones se replican y vuelven a existir.

1 comentario:

  1. Borgata Hotel Casino & Spa - Mashantucket, CT
    Enjoy nightly entertainment, a 부산광역 출장안마 world-class spa, world-class entertainment, 이천 출장마사지 and world-class casino dining at Borgata Hotel 상주 출장샵 Casino & Spa in 오산 출장샵 Mashantucket, CT. 춘천 출장안마

    ResponderEliminar