tomcat配置session共享

tomcat官网

打开 tomcat 官网: http://tomcat.apache.org/ , 找到需要配置的tomcat版本的文档,这里以 tomcat7 为例,

1-选择tomcat7文档

找到对应的 Clustering 配置(因为配置session共享,就是配置集群),如下图
2-tomcat官网7的文档首页-cluster

即,配置tomcat7集群的文档地址: http://tomcat.apache.org/tomcat-7.0-doc/cluster-howto.html

配置session共享

1.阅读官方文档

3-tomcat7配置cluster文档

如上图官方的文档中所说,只需配置 <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/> 节点即可

2.修改server.xml配置

但其实在 tomcatconf/server.xml 的配置文件中,已经有此项配置,只是被注释了,只需将注释 打开 即可,如下图

4-tomcat的server.xml文件cluster的配置

3.准备测试环境

此时,准备一个 tomcat ,如上打开 conf/server.xmlCluster 的节点配置,再准备一个简单的 javaWeb应用(打印 sessionId,做验证配置是否成功),放到 tomcatwebapps 目录下

打印 sessionIdjsp 如下

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>session replication</title>
</head>
<body>
    <br/>
    <br/>
    <br/>
    <br/>
    <br/>
    SessionID:<%=session.getId() %>
</body>
</html>

因为是在本地做验证,所以,再将以上配置完成的 tomcat 再复制一份,然后修改 tomcat 的端口,这里我两个 tomcat 的应用端口是 80818082,如下图所示

5-两个tomcat的端口配置图片

tomcatwebapps 目录,如下

6-两个tomcat的web应用

4.测试失败

修改完成配置之后,分别启动 tomcat,打开浏览器测试之后,如下

7-浏览器测试sessionId不一致

测试发现,两个 tomcatsessionId 并不一致?!

另外,还发现了一个问题,就是 来回刷新 浏览器的 两个tomcat的应用 的index.jsp,浏览器显示的 两个 sessionId 在不断的变化 ,但是这个问题跟配置 session共享 无关,是 cookie的作用域 导致的,后续再单独写一篇笔记讲。

5.查漏补缺

此时我们再返回 tomcat 官网配置 Cluster 的文档处,继续阅读,找到其中的 Cluster Basics 标签那,如下图所示,

8-tomcat配置session共享需要完成的步骤

文档中,说要配置 session复制 必须完成以下几步:

  • session 的所有 attributes 必须实现 java.io.Serializable (√)
  • 在 server.xml 的配置文件中,把 Cluster 的注释打开 (√)
  • 如果有自定义的集群 Valve(tomcat过滤器),就需要在 server.xml 的 Cluster 节点下配置 ReplicationValve (x,没有,不用管)
  • 如果集群的 tomcat实例 在同一台机器上,需要确保的你的 Receiver.port 不要有冲突,然后还顺道赞美了他家的 tomcat ,在大部分场景下能够自动检测4000-4100范围内的可用端口来,解决此问题 (√,默认配置就已经支持了)
  • 需要在 web应用 的 web.xml 文件中,配置 <distributable/> 节点 (x,这个没有配)
  • 如果集群用到了 mod_jk,就要在 server.xml 的 Engine 节点配置 jvmRoute 的属性,如<Engine name="Catalina" jvmRoute="node01" > 并且 jvmRoute 属性值与 workers.properties 中的 worker name 匹配 (x,没配,不用管)
  • 集群的所有节点,系统时间要一致,并与 NTP service 同步 (√,同一台机器)
  • 将负载均衡服务器(apache、nginx等),配置为粘性会话模式 (x,暂时没有配负载均衡,不用管)

所以,意思就是,conf/server.xml 中配置了 Cluster 节点外,还需要在 web应用web.xml 文件里面配置 <distributable/> 节点,如下图所示

9-web应用的web.xml文件配置distributable节点

6.重新测试

配置完成之后,重新启动两个 tomcat,重新刷新浏览器的页面,此时如下图所示,sessionId 已经一致,即 session共享 配置成功。

10-浏览器测试sessionId一致

探究

1.Cluster 节点的默认配置是什么?

上文在官网中截取的,配置 Cluster 节点的图,如下所示,

3-tomcat7配置cluster文档

图中最后提到的,The following is the default cluster configuration 如下配置,

		<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="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" />
        </Cluster>

即配置 <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/> 与上面这一大段的配置内容,效果是一样的,但是这样一来,细粒度越小,可以调整的内容也就越多

在上面的这么多配置中,需要注意的是,address="228.0.0.4" 这个地址为 组播地址,属于 ip地址 中的 D类地址

11-Cluster完整默认配置的组播地址

这个地址可以改,但是只能改为另一个组播地址。如果随便填一个非组播地址,tomcat启动的时候会报一个 Not a multicast address 的错误,这个报错来自 javajava.net.MulticastSocket,如下所示,

12-net包报不是一个组播地址的错误

在配置了 Cluster 节点之后,tomcat启动的过程中,会调用 org.apache.catalina.tribes.membership.McastServicestart() 方法,然后在方法中验证 address 的值是否是一个组播地址D类地址,它的第1个字节的前四位固定为 1110,即 ipv4 的地址的下限为 224.0.0.1

13-Inet4Address的isMulticastAddress方法

2.tomcat之间如何进行session复制的通信?

tomcat 文档的最后,有讲到这个问题:

当配置了 Cluster 节点的 tomcat 启动的时候,会创建 Host 对象,并用一个集群对象与之关联。启动过程中,到了解析 Context (即 web应用)的时候,如果 web应用web.xml 配置了 <distributable/> 的节点,则 Cluster 的对象会创建一个 manager 去管理 session复制。之后,Cluster 的对象将启动一个 membership 的服务(多播)和一个 replication 的服务(tcp单播)。下图是关于上述描述的 tomcat源码

14-tomcat源码cluster创建manager管理session复制

Tomcat 之间的 session replication 通信是使用简单的 多播ping 建立的。每个 Tomcat实例 将定期发出 多播ping,在 ping消息 中,会包含 Tomcat实例IPTCP侦听端口 去进行 与其他实例的 session复制。如果 Tomcat实例 在给定的时间范围内没有收到此类ping,则该成员被视为已死。

Tomcat实例 收到 组播ping,该成员就会被添加到集群中,在下一个复制请求时,发送实例将通过集群的成员列表侦听的 ip和端口 信息(单播)建立 TCP Socket连接,进行 session复制

组播传输:在发送者和每一接收者之间实现点对点网络连接,如果一台发送者同时给多个接收者传输相同的数据,也只需要复制一份的相同数据包,它提高了数据的传输效率。

在因特网中的IP组播也是用组播组的概念,每个组都有一个特别分配的地址,要给该组发送的计算机将使用这个地址作为分组的目标地址。在IPv4中,这些地址在D类地址空间中分配,而IPv6也有一部分地址空间保留给组播组。

需要注意的是,主机组播时仅发送一份数据,只有数据在传送路径出现分岔时才将分组复制后继续转发。

15-单播与组播的比较

即,Tomcat 启动时,发送 组播ping 建立集群的成员列表。在下一个 session复制 的请求时,根据集群成员列表的各成员侦听的 ip和端口,逐一建立 socket连接 ,进行 session复制

  • 5
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值