Tomcat实现集群的Session会话共享(内存共享方式)

本文详细介绍如何通过配置Tomcat的server.xml和web.xml文件实现集群环境下的Session共享,包括Cluster节点设置、Manager和Channel配置,以及必要的web.xml修改。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Tomcat实现集群的Session会话共享

  Tomcat有提供自己实现会话共享的方式,这里也是主要介绍Tomcat提供了的实现。Tomcat官方提供的实现主要是中间件层的改动,不需要对项目已有的代码改动。对于实现Session共享官方文档的介绍已经很清晰了。

一、配置server.xml文件

   server.xml文件的修改主要是增加Cluster节点,基本按照官方的配置,在Host节点中添加下面的配置。

<!-- 如果使用群集,应用的web.xml要加上distributable标签 -->
<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" />
			<!-- 在群集中 本服务器用于接收来自其他服务器分发的信息 例如同步会话 -->
			<!-- 若在同一台机器上运行两个Tomcat实例 需要修改这个端口 具体数值无要求 不重复即可 -->
			<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" />
				
	</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.ClusterSessionListener" />
</Cluster>
<!-- 结束配置群集 -->

   Tomcat需要session共享,需要注意的是,session中的属性必须实现java.io.Serializable

二、配置web.xml

  主要是在需要集群的项目中,配置web.xml,主要是添加一个元素节点<distributable/>即可。如下web.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
  version="3.1"
  metadata-complete="true">

  <display-name>Welcome to Tomcat</display-name>
  <description>
     Welcome to Tomcat
  </description>
  <!--要实现session复制,分布式web容器应用 -->
  <distributable/>
</web-app>

三、配置实例

  简单的实践一下,没有去写个新项目,直接使用了Tomcat的ROOT项目,在index.jsp文件中写了一段获取session的的JSP代码,如下:

<div id="middle" class="curved container">
	   <b>使用的是mod_proxy的方式实现负载均衡,HTTP协议!</b>
               Tomcat2</br>
			   <% String sessionStr=session.getId();%>
			   <% //默认每一次刷新都会加1
			      Object obj = session.getAttribute("globalValue");//默认的不断加1的值
				  Integer globalValue = 0;
			      if(obj == null){
					  globalValue = 1;
					  session.setAttribute("globalValue",globalValue);
				  }else{//如果会话中已经存在则进行加1
					 globalValue = (Integer)obj;
					 globalValue = globalValue + 1;
					 session.setAttribute("globalValue",globalValue);
				  }
			   %>
	      当前的sessionId:<b><%=sessionStr %></b> <br>
	      Session中的globalValue(每刷新一次会自动加1):<b><%=globalValue %></b> <br>
 </div>

  还有一点,ROOT项目的index.jsp中默认是禁用了session的,需要在page指令允许当前jsp使用session,如下所示:

<%@ page session="true" pageEncoding="UTF-8" contentType="text/html; charset=UTF-8" %>

  这里使用的是三个Tomcat一起实现session共享,所以以上的配置在每个tomcat中都需要配置,分别是Tomcat0、Tomcat1、Tomcat2;启动每一个tomcat,访问各个Tomcat的地址,可以看到它们之间的Session是相同的,sessionid都是:BC494768E884D01126B5102A643D541E,此外在session中存储的globalValue会每次都加1。

  Tomcat0的访问截图,globalValue=1
在这里插入图片描述
  Tomcat1的访问截图,globalValue=2
在这里插入图片描述
  Tomcat2的访问截图,globalValue=3
在这里插入图片描述
  测试的项目使用的是Tomcat自带的ROOT项目,在Tomcat和这个ROOT项目中配置了session共享的配置;3个Tomcat的服务器中的ROOT项目的session实现了会话共享,因为如上的三次访问分别访问了Tomcat0,Tomcat1,Tomcat2,它们的sessionId都是一样的,而且存储在Session中的globalValue的值时每访问一次都只加1,表明globalValue在3个Tomcat的ROOT项目中是共享的,才能实现这样的效果。

四、总结

  实现session共享,官方也提供几种实现session共享方式,无非是将session存在数据库和将session存在内存中。而这篇主要是Tomcat自带的内存session共享的方式,是一种All To All的方式,比较耗费资源。对于小集群来说还是不错的,如果是大集群将会不合适了。Tomcat服务器之间的session复制或者说共享是有两种传递方式,组播的方式和单播的方式,一般推荐组播的方式,但是有时候某些机器不支持组播则只能采用单播。

遇到的问题:

  Tomcat提供的session共享是基于组播实现的,当我尝试使用物理机和虚拟机的tomcat建立集群时,出现了tomcat的session无法共享的问题。他们之间的网络是互通的,不知是否是端口或者防火墙的策略问题。

五、参考的资料

  官方集群配置组播的方式

  官方集群配置单播的方式

  单播、组播和广播的概念

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值