tomcat配置session共享

tomcat官网

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

tomcat配置session共享_第1张图片

找到对应的 Clustering 配置(因为配置session共享,就是配置集群),如下图
tomcat配置session共享_第2张图片

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

配置session共享

1.阅读官方文档

tomcat配置session共享_第3张图片

如上图官方的文档中所说,只需配置 节点即可

2.修改server.xml配置

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

tomcat配置session共享_第4张图片

3.准备测试环境

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

打印 sessionIdjsp 如下

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




session replication


    




SessionID:<%=session.getId() %>

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

tomcat配置session共享_第5张图片

tomcatwebapps 目录,如下

tomcat配置session共享_第6张图片

4.测试失败

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

tomcat配置session共享_第7张图片

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

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

5.查漏补缺

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

tomcat配置session共享_第8张图片

文档中,说要配置 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 文件中,配置 节点 (x,这个没有配)
  • 如果集群用到了 mod_jk,就要在 server.xml 的 Engine 节点配置 jvmRoute 的属性,如 并且 jvmRoute 属性值与 workers.properties 中的 worker name 匹配 (x,没配,不用管)
  • 集群的所有节点,系统时间要一致,并与 NTP service 同步 (√,同一台机器)
  • 将负载均衡服务器(apache、nginx等),配置为粘性会话模式 (x,暂时没有配负载均衡,不用管)

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

tomcat配置session共享_第9张图片

6.重新测试

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

tomcat配置session共享_第10张图片

探究

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

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

tomcat配置session共享_第11张图片

图中最后提到的,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>

即配置 与上面这一大段的配置内容,效果是一样的,但是这样一来,细粒度越小,可以调整的内容也就越多

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

tomcat配置session共享_第12张图片

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

tomcat配置session共享_第13张图片

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

tomcat配置session共享_第14张图片

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

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

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

tomcat配置session共享_第15张图片

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

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

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

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

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

tomcat配置session共享_第16张图片

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

你可能感兴趣的:(tomcat)