多个tomcat之间的session复制

用tomcat做负载集群时, 经常会用到session复制(Session Replication), 很多例子会告诉我们要配置apache或者其他的Web Server. 而事实上, 单纯从session复制的角度讲, 是不需要Web Server的.

 

tomcat的session复制分为两种, 一种是全局试的(all-to-all), 这意味着一个node(tomcat实例)的session发生变化之后, 它会将这些变更复制到其他所有集群组的成员;另一种是局部试的, 它会用到BackupManager, BackupManager能实现只复制给一个Buckup Node, 并且这个Node会部署相同的Web应用, 但是这种方式并没用经过很多的测试(来自官方说明..).

 

tomcat的session复制是基于IP组播(multicast)来完成的, 详细的IP组播介绍可以参考这里.

简单的说就是需要进行集群的tomcat通过配置统一的组播IP和端口来确定一个集群组, 当一个node的session发生变更的时候, 它会向IP组播发送变更的数据, IP组播会将数据分发给所有组里的其他成员(node).

 

配置如下(这里所有的tomcat都在不同的物理主机, 如果在同一台主机上需要改tomcat的tcpListenPort)

 

Xml代码   收藏代码
  1. <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"  
  2.                  channelSendOptions="8">  
  3.   
  4.           <Manager className="org.apache.catalina.ha.session.DeltaManager"  
  5.                    expireSessionsOnShutdown="false"  
  6.                    notifyListenersOnReplication="true"/>  
  7.   
  8.           <Channel className="org.apache.catalina.tribes.group.GroupChannel">  
  9.             <Membership className="org.apache.catalina.tribes.membership.McastService"  
  10.                         address="228.0.0.4"  
  11.                         port="45564"  
  12.                         frequency="500"  
  13.                         dropTime="3000"/>  
  14.             <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"  
  15.                       address="auto"  
  16.                       port="4000"  
  17.                       autoBind="100"  
  18.                       selectorTimeout="5000"  
  19.                       maxThreads="6"/>  
  20.   
  21.             <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">  
  22.               <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>  
  23.             </Sender>  
  24.             <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>  
  25.             <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>  
  26.           </Channel>  
  27.   
  28.           <Valve className="org.apache.catalina.ha.tcp.ReplicationValve"  
  29.                  filter=""/>  
  30.           <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>  
  31.   
  32.           <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"  
  33.                     tempDir="/tmp/war-temp/"  
  34.                     deployDir="/tmp/war-deploy/"  
  35.                     watchDir="/tmp/war-listen/"  
  36.                     watchEnabled="false"/>  
  37.   
  38.           <ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>  
  39.           <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>  
  40.         </Cluster>  

 

然后新建一个web应用, 我们这里叫TomcatClusterDemo, web context与名称一致.

新建一个jsp, 这个jsp复制向session里创建/更新属性, 并将session里的所有属性显示在网页上. 

当然, 为了验证我们的session是同步的, 我们还将session ID显示了出来, 代码如下:

 

 

Jsp代码   收藏代码
  1.   <%@ page contentType="text/html; charset=UTF-8" %>  
  2. <%@ page import="java.util.*" %>  
  3. <html><head><title>Tomcat Cluster Demo</title></head>  
  4. <body>  
  5. Server Info:  
  6. <%  
  7. out.println(request.getLocalAddr() + " : " + request.getLocalPort()+"<br>");%>  
  8. <%  
  9.   out.println("<br> ID " + session.getId()+"<br>");  
  10.     
  11.   String dataName = request.getParameter("dataName");  
  12.   if (dataName != null && dataName.length() > 0) {  
  13.      String dataValue = request.getParameter("dataValue");  
  14.      session.setAttribute(dataName, dataValue);  
  15.      System.out.println("application:" + application.getAttribute(dataName));  
  16.      application.setAttribute(dataName, dataValue);  
  17.   }  
  18.   out.print("<b>Session List</b>");  
  19.   Enumeration<String> e = session.getAttributeNames();  
  20.   while (e.hasMoreElements()) {  
  21.      String name = e.nextElement();  
  22.      String value = session.getAttribute(name).toString();  
  23.      out.println( name + " = " + value+"<br>");  
  24.          System.out.println( name + " = " + value);  
  25.    }  
  26. %>  
  27.   <form action="test.jsp" method="POST">  
  28.     Name:<input type=text size=20 name="dataName">  
  29.      <br>  
  30.     Value:<input type=text size=20 name="dataValue">  
  31.      <br>  
  32.     <input type=submit>  
  33.    </form>  
  34. </body>  
  35. </html>  

 

同时, 在web.xml里增加<distributable/>描述

 

 

Xml代码   收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <web-app id="WebApp_ID" version="2.5" 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_2_5.xsd">  
  3.     <display-name>TomcatClusterDemo</display-name>  
  4.     <distributable/>  
  5.     <welcome-file-list>  
  6.         <welcome-file>index.html</welcome-file>  
  7.         <welcome-file>index.htm</welcome-file>  
  8.         <welcome-file>index.jsp</welcome-file>  
  9.         <welcome-file>default.html</welcome-file>  
  10.         <welcome-file>default.htm</welcome-file>  
  11.         <welcome-file>test.jsp</welcome-file>  
  12.     </welcome-file-list>  
  13. </web-app>  
 

现在将TomcatClusterDemo部署到两个tomcat上(直接将war包或者部署文件拷贝到webapps下, 或者通过Tomcat Web Application Manager部署), 依次启动两个tomcat.

 

先访问第一台tomcat(下面的9.119.84.68)的test.jsp, 并添加几个session.

然后访问第二台tomcat(下面的9.119.84.88)的test.jsp, 为了告诉tomcat我们要用那个session访问, 我们需要在URL后面加上 ;jsessionid=SESSION_ID 

SESSION_ID可以从第一个test.jsp页面上获得.

 

看看效果, 两个在不同server上的tomcat实现了session复制!

 


 

 

 


转载自:http://nanquan.iteye.com/blog/1533906

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页