example cluster java tomcat cluster-computing session-replication

java - tomcat 8 cluster example



La agrupación/replicación de sesión de Tomcat no se replica correctamente (5)

Estoy configurando la agrupación / replicación en Tomcat 7 en mi máquina local, para evaluar su uso con mi entorno / base de código.

Preparar

Tengo dos servidores tomcat idénticos en directorios hermanos que se ejecutan en diferentes puertos. Tengo httpd escuchando en otros dos puertos y conectándome a las dos instancias de Tomcat como VirtualHosts. Puedo acceder e interactuar con ambos entornos en los puertos configurados; Todo está funcionando como se esperaba.

Los servidores tomcat han habilitado la agrupación en clústeres de esta manera, en server.xml:

<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="auto" port="4001" autoBind="100" 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>

y agregué la etiqueta distribuible al principio de web.xml:

<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 /> (lots more...) </web-app>

Que esta funcionando

Cuando los servidores se inician, se registran.

Sep 16, 2013 1:44:23 PM org.apache.catalina.ha.tcp.SimpleTcpCluster startInternal INFO: Cluster is about to start Sep 16, 2013 1:44:23 PM org.apache.catalina.tribes.transport.ReceiverBase getBind FINE: Starting replication listener on address:10.0.0.100 Sep 16, 2013 1:44:23 PM org.apache.catalina.tribes.transport.ReceiverBase bind INFO: Receiver Server Socket bound to:/10.0.0.100:4001 Sep 16, 2013 1:44:23 PM org.apache.catalina.tribes.membership.McastServiceImpl setupSocket INFO: Setting cluster mcast soTimeout to 500 Sep 16, 2013 1:44:23 PM org.apache.catalina.tribes.membership.McastServiceImpl waitForMembers INFO: Sleeping for 1000 milliseconds to establish cluster membership, start level:4 Sep 16, 2013 1:44:24 PM org.apache.catalina.tribes.membership.McastServiceImpl waitForMembers INFO: Done sleeping, membership established, start level:4 Sep 16, 2013 1:44:24 PM org.apache.catalina.tribes.membership.McastServiceImpl waitForMembers INFO: Sleeping for 1000 milliseconds to establish cluster membership, start level:8 Sep 16, 2013 1:44:25 PM org.apache.catalina.tribes.membership.McastServiceImpl waitForMembers INFO: Done sleeping, membership established, start level:8

Cuando el segundo servidor se inicia, el primero registra

Sep 16, 2013 2:17:30 PM org.apache.catalina.tribes.group.interceptors.TcpFailureDetector messageReceived FINE: Received a failure detector packet:ClusterData[src=org.apache.catalina.tribes.membership.MemberImpl[tcp://{10, 0, 0, 100}:4000,{10, 0, 0, 100},4000, alive=112208, securePort=-1, UDP Port=-1, id={118 6 107 -67 88 98 72 95 -73 41 4 -108 58 -5 -127 -41 }, payload={}, command={}, domain={}, ]; id={25 110 120 -2 -25 6 78 -97 -84 -34 2 -11 49 -62 -8 -56 }; sent=2013-09-16 14:17:30.139] Sep 16, 2013 2:17:30 PM org.apache.catalina.tribes.transport.nio.NioReplicationTask remoteEof FINE: Channel closed on the remote end, disconnecting Sep 16, 2013 2:17:30 PM org.apache.catalina.tribes.membership.McastServiceImpl memberDataReceived FINE: Mcast add member org.apache.catalina.tribes.membership.MemberImpl[tcp://{10, 0, 0, 100}:4001,{10, 0, 0, 100},4001, alive=1010, securePort=-1, UDP Port=-1, id={82 -45 -109 -56 -110 -5 78 -10 -103 61 -40 -59 -36 -79 104 120 }, payload={}, command={}, domain={}, ] Sep 16, 2013 2:17:30 PM org.apache.catalina.ha.tcp.SimpleTcpCluster memberAdded INFO: Replication member added:org.apache.catalina.tribes.membership.MemberImpl[tcp://{10, 0, 0, 100}:4001,{10, 0, 0, 100},4001, alive=1011, securePort=-1, UDP Port=-1, id={82 -45 -109 -56 -110 -5 78 -10 -103 61 -40 -59 -36 -79 104 120 }, payload={}, command={}, domain={}, ]

y cuando uno se apaga, el otro se registra.

Sep 16, 2013 2:28:05 PM org.apache.catalina.tribes.membership.McastServiceImpl memberDataReceived FINE: Member has shutdown:org.apache.catalina.tribes.membership.MemberImpl[tcp://{10, 0, 0, 100}:4001,{10, 0, 0, 100},4001, alive=422279, securePort=-1, UDP Port=-1, id={54 43 17 -9 13 -11 72 -63 -107 -78 -8 65 -21 -77 115 88 }, payload={}, command={66 65 66 89 45 65 76 69 88 ...(9)}, domain={}, ] Sep 16, 2013 2:28:05 PM org.apache.catalina.tribes.group.interceptors.TcpFailureDetector memberDisappeared INFO: Verification complete. Member disappeared[org.apache.catalina.tribes.membership.MemberImpl[tcp://{10, 0, 0, 100}:4001,{10, 0, 0, 100},4001, alive=422279, securePort=-1, UDP Port=-1, id={54 43 17 -9 13 -11 72 -63 -107 -78 -8 65 -21 -77 115 88 }, payload={}, command={66 65 66 89 45 65 76 69 88 ...(9)}, domain={}, ]] Sep 16, 2013 2:28:05 PM org.apache.catalina.ha.tcp.SimpleTcpCluster memberDisappeared INFO: Received member disappeared:org.apache.catalina.tribes.membership.MemberImpl[tcp://{10, 0, 0, 100}:4001,{10, 0, 0, 100},4001, alive=422279, securePort=-1, UDP Port=-1, id={54 43 17 -9 13 -11 72 -63 -107 -78 -8 65 -21 -77 115 88 }, payload={}, command={66 65 66 89 45 65 76 69 88 ...(9)}, domain={}, ]

así que sé que están conscientes el uno del otro.

Finalmente, cuando uso el MBean Cluster / Operations en jconsole para intentar establecer la propiedad "foo" en "barra", jconsole reporta el "método invocado con éxito" y los registros del servidor

Sep 16, 2013 2:30:18 PM org.apache.catalina.ha.tcp.SimpleTcpCluster setProperty WARNING: Dynamic setProperty(foo,value) has been disabled, please use explicit properties for the element you are trying to identify

No estoy muy preocupado por ese error; Se incluye principalmente para demostrar que setProperty crea una declaración de registro.

Que no esta funcionando

Por lo que sé, no se está replicando información de sesión en mi aplicación.

El administrador de tomcat solo lista las sesiones iniciadas en el servidor que está monitoreando, y no la otra en el clúster.

Tengo la impresión de que siempre que la aplicación llame a HttpSession.setAttribute, ese atributo se debe replicar en los otros nodos del clúster, y espero que se registre algún registro de eso. Mi aplicación incluye esta línea:

public static void saveBillingInfo(IPageContext pageContext, BillingInfo billingInfo) { pageContext.getSession().setAttribute("billingInfo", billingInfo); //etc... }

donde BillingInfo es una clase serializable que contiene solo un campo, un HashMap de información sobre la información de facturación.

No se escriben declaraciones de registro cuando esta o cualquier otra línea se procesa, y no veo ninguna evidencia de que la información de la sesión realmente se esté compartiendo.

Cualquier sugerencia u otras preguntas son bienvenidas.


De acuerdo con los documentos de Tomcat, debes hacer uno de estos dos (NO ambos):

  1. Especifique en web.xml <distributable/> para habilitar la agrupación en clústeres y use el <Manager> predeterminado especificado en el server.xml o ...

  2. Agregue un <Manager> en el nivel de aplicación dentro de context.xml


Nuestra solución fue agregar la etiqueta <distributable/> al archivo WEB-INF/web.xml bajo el elemento <web-app> . No estoy seguro de por qué esto funcionó para nosotros y no para el OP.

Por cierto, la solución de Jason también funcionó para nosotros.


Si desea habilitar la agrupación en clúster para una aplicación implementada específica, puede usar el siguiente ejemplo

server.xml

<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="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="auto" port="4000" autoBind="100" 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"/>

<Manager className="org.apache.catalina.ha.session.DeltaManager" expireSessionsOnShutdown="false" notifyListenersOnReplication="true"/> <Resource auth="Container" driverClassName="oracle.jdbc.OracleDriver" factory="com.atomikos.tomcat.EnhancedTomcatAtomikosBeanFactory" minPoolSize="4" maxPoolSize="50" name="jdbc/myoracle/myconect" password="sdfhsfghsgfsfg" type="com.atomikos.jdbc.nonxa.AtomikosNonXADataSourceBean" uniqueResourceName="uniresource" url="jdbc:oracle:thin:@10.10.10.10.:1521:abc" user="user"/> </Context>


Tuvimos este problema idéntico Aunque no está documentado en ninguna parte, lo que lo resolvió fue simplemente mover la etiqueta <Manager> de server.xml al global context.xml (sacándola del grupo <Server> ... <Cluster> ... y hacia el grupo <Context>). Tan pronto como hicimos esto, todo "mágicamente" comenzó a funcionar. Esto solo se aplicó a Tomcat 7 ... Tomcat 6 funcionó perfectamente con la configuración que describió anteriormente (y como se describe en la documentación).

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

Ahora simplemente elimine la etiqueta <Manager> de su grupo de Cluster en server.xml y listo.


en server.xml solo agrega:

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

y, en su context.xml:

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

funcionó para mí, estoy usando Tomcat 7 y Tomcat 8