Java应用服务器之tomcat会话复制集群配置的示例详解

网友投稿 267 2022-11-30


Java应用服务器之tomcat会话复制集群配置的示例详解

会话是识别用户,跟踪用户访问行为的一个手段,通过cookie(存在客户端)或session(存在服务端)来判断本次请求是那个客户端发送过来;常用的会话保持有绑定会话,就是前边我们聊的在代理上通过算法或通过给客户端响应首部加cookie这种方式来保持同一cookie或同一ip地址的请求始终发送到同一后端server进行响应;但是这样的会话绑定的方式存在一个问题,就是当后端某一server宕机,那么之前上面的所有会话信息将消失,那么后续的客户端来请求,代理是否要把请求调度到后端宕机的server呢?如果说调度上去呢,那么用户之前的会话信息又没有了,如果说不调度呢,那么用户将不能够得到服务;所以对于这种情况我们需要把会话都同步到后端所有server上,即便某一台或几台后端server宕机了,不会导致用户的会话信息丢失,同样服务也是可用的;这种冗余的方式保存会话信息,使得用户的会话信息能够在任何一台后端server上都会有;这也意味着只要有用户来请求,前端调度器可以任意把请求调度到后端的某一台server上,然后服务端把本次请求的用户会话信息通过广播的方式,通知给其他后端server,这样一来这个客户端后续来请求,不管调度到后端那一台server上,因为后端server上都有这个客户端之前请求的会话信息,所以不管到那一台都能够识别;对于tomcat来讲,它内部就有一个组件支持这样的功能,它可以基于多播通信的方式,把会话信息同步给后端其他节点,这个组件就是cluster;

示例:使用tomcat cluster组件来定义tomcat的会话复制集群

环境说明

名称

ip地址

端口

代理Nginx

192.168.0.41

80

应用服务tomcatA

192.168.0.42

8080

应用服务tomcatB

192.168.0.43

8080

准备测试页面,以及配置tomcatA

提示:以上是myapp里的内容以及文件目录结构

提示:以上配置表示部署一个/myapp的应用,它的文件路径在/webapps/myapp,并且在engine上配置了 jvmRoute=“tomcatA”;

提示:cluster配置需要注意上面打红框的位置,在官方配置文档中,后面的

完整的server.xml配置

type="org.apache.catalina.UserDatabase"

description="User database that can be updated and saved"

factory="org.apache.catalina.users.MemoryUserDatabaseFactory"

pathname="conf/tomcat-users.xml" />

connectionTimeout="20000"

redirectPort="8443" />

resourceName="UserDatabase"/>

unpackWARs="true" autoDeploy="true">

prefix="localhost_access_log." suffix=".txt"

pattern="%h %l %u %t "%r" %s %b" />

channelSendOptions="8">

expireSessionsOnShutdown="false"

notifyListenersOnReplication="true"/>

address="228.0.0.4"

port="45564"

frequency="500"

dropTime="3000"/>

address="192.168.0.42"

port="4000"

autoBind="100"

selectorTimeout="5000"

maxThreads="6"/>

filter=""/>

tempDir="/tmp/war-temp/"

deployDir="/tmp/war-deploy/"

watchDir="/tmp/war-listen/"

watchEnabled="false"/>

nUSljOqV

给我们定义的应用修改器web.xml 在其中加上元素

提示:对于web.xml配置文件,我们可以从/etc/tomcat/中复制一份到自己的应用目录结构里,然后在非注释掉位置加上元素即可

对于tomcatB来说,我们也需要准备好同样的文件,为了区分,我们把index.jsp修改成tomcatB ,在配置文件中我们需要修改接收器的监听地址,以及jvmRoute的值,其他的都可以不变

到此tomcat会话复制集群就配置好了;其实从上面的配置文件可以看大,tomcat的会话复制集群就是利用多播地址通信,一个请求不管到集群那个基点,它都会通过多播通信,把会话信息以组播的方式发送给其他成员;这里建议把接收器的地址专门用张网卡配置好地址;接下来我们启动下tomcatA,tomcatB,然后看看日志是否初始集群成功,并接收到集群成员接收器的地址;

提示:这里注意一点如果tomcat启动特别慢,就是8005端口要等很久才起来,可以尝试安装rng-tools,并启动rngd,这样可以加快tomcat启动

提示:如果在tomcatA的日志中能够看到tomcatB的接收器地址和端口,那么就表示tomcatA已经识别到tomcatB,并把tomcatB当作集群成员加入到集群;同样在tomcatB的日志中能够看到tomcatA的接收器地址和端口,表示tomcatB已经识别tomcatA并把它加入到集群;

配置nginx负载均衡后端两台tomcat server

提示:这里需要主要反代时需要把反代的URI和后面proxy_pass后面的URI相同,否则代理后,会话复制集群不会生效;

验证:检查nginx的配置文件语法,启动nginx访问192.168.0.41/myapp看看有什么变化

提示:可以看到访问192.168.0.41/myapp时sessionid始终没有发生变化,变化的只有后面的jvmRoute的值和页面的值;这说明我们访问nginx时,nginx也基于自己的轮询算法把请求调度到后端去了,第一次访问时,后端server会响应一个set-cookie的首部,把当前访问的页面的session信息响应给客户端,第二次访问客户端就会把上一次访问相应的cookie带上去访问,这时后端server接受到客户端发送过来的cookie,然后就在自己内存里找对应的session信息;由于后端server是把session信息基于多播通信的方式共享给集群其他节点,所以第二次不管调度到那台server上,对应server都会有该客户端第一次访问服务端的session信息;所以我们第二次访问时,sessionid还是第一次访问服务器的sessionid,后面的tomcatB表示由tomcatB这个jvmRoute处理的这次请求;

总结

完整的server.xml配置

type="org.apache.catalina.UserDatabase"

description="User database that can be updated and saved"

factory="org.apache.catalina.users.MemoryUserDatabaseFactory"

pathname="conf/tomcat-users.xml" />

connectionTimeout="20000"

redirectPort="8443" />

resourceName="UserDatabase"/>

unpackWARs="true" autoDeploy="true">

prefix="localhost_access_log." suffix=".txt"

pattern="%h %l %u %t "%r" %s %b" />

channelSendOptions="8">

expireSessionsOnShutdown="false"

notifyListenersOnReplication="true"/>

address="228.0.0.4"

port="45564"

frequency="500"

dropTime="3000"/>

address="192.168.0.42"

port="4000"

autoBind="100"

selectorTimeout="5000"

maxThreads="6"/>

filter=""/>

tempDir="/tmp/war-temp/"

deployDir="/tmp/war-deploy/"

watchDir="/tmp/war-listen/"

watchEnabled="false"/>

nUSljOqV

给我们定义的应用修改器web.xml 在其中加上元素

提示:对于web.xml配置文件,我们可以从/etc/tomcat/中复制一份到自己的应用目录结构里,然后在非注释掉位置加上元素即可

对于tomcatB来说,我们也需要准备好同样的文件,为了区分,我们把index.jsp修改成tomcatB ,在配置文件中我们需要修改接收器的监听地址,以及jvmRoute的值,其他的都可以不变

到此tomcat会话复制集群就配置好了;其实从上面的配置文件可以看大,tomcat的会话复制集群就是利用多播地址通信,一个请求不管到集群那个基点,它都会通过多播通信,把会话信息以组播的方式发送给其他成员;这里建议把接收器的地址专门用张网卡配置好地址;接下来我们启动下tomcatA,tomcatB,然后看看日志是否初始集群成功,并接收到集群成员接收器的地址;

提示:这里注意一点如果tomcat启动特别慢,就是8005端口要等很久才起来,可以尝试安装rng-tools,并启动rngd,这样可以加快tomcat启动

提示:如果在tomcatA的日志中能够看到tomcatB的接收器地址和端口,那么就表示tomcatA已经识别到tomcatB,并把tomcatB当作集群成员加入到集群;同样在tomcatB的日志中能够看到tomcatA的接收器地址和端口,表示tomcatB已经识别tomcatA并把它加入到集群;

配置nginx负载均衡后端两台tomcat server

提示:这里需要主要反代时需要把反代的URI和后面proxy_pass后面的URI相同,否则代理后,会话复制集群不会生效;

验证:检查nginx的配置文件语法,启动nginx访问192.168.0.41/myapp看看有什么变化

提示:可以看到访问192.168.0.41/myapp时sessionid始终没有发生变化,变化的只有后面的jvmRoute的值和页面的值;这说明我们访问nginx时,nginx也基于自己的轮询算法把请求调度到后端去了,第一次访问时,后端server会响应一个set-cookie的首部,把当前访问的页面的session信息响应给客户端,第二次访问客户端就会把上一次访问相应的cookie带上去访问,这时后端server接受到客户端发送过来的cookie,然后就在自己内存里找对应的session信息;由于后端server是把session信息基于多播通信的方式共享给集群其他节点,所以第二次不管调度到那台server上,对应server都会有该客户端第一次访问服务端的session信息;所以我们第二次访问时,sessionid还是第一次访问服务器的sessionid,后面的tomcatB表示由tomcatB这个jvmRoute处理的这次请求;

总结

type="org.apache.catalina.UserDatabase"

description="User database that can be updated and saved"

factory="org.apache.catalina.users.MemoryUserDatabaseFactory"

pathname="conf/tomcat-users.xml" />

connectionTimeout="20000"

redirectPort="8443" />

resourceName="UserDatabase"/>

unpackWARs="true" autoDeploy="true">

prefix="localhost_access_log." suffix=".txt"

pattern="%h %l %u %t "%r" %s %b" />

channelSendOptions="8">

expireSessionsOnShutdown="false"

notifyListenersOnReplication="true"/>

address="228.0.0.4"

port="45564"

frequency="500"

dropTime="3000"/>

address="192.168.0.42"

port="4000"

autoBind="100"

selectorTimeout="5000"

maxThreads="6"/>

filter=""/>

tempDir="/tmp/war-temp/"

deployDir="/tmp/war-deploy/"

watchDir="/tmp/war-listen/"

watchEnabled="false"/>

nUSljOqV

给我们定义的应用修改器web.xml 在其中加上元素

提示:对于web.xml配置文件,我们可以从/etc/tomcat/中复制一份到自己的应用目录结构里,然后在非注释掉位置加上元素即可

对于tomcatB来说,我们也需要准备好同样的文件,为了区分,我们把index.jsp修改成tomcatB ,在配置文件中我们需要修改接收器的监听地址,以及jvmRoute的值,其他的都可以不变

到此tomcat会话复制集群就配置好了;其实从上面的配置文件可以看大,tomcat的会话复制集群就是利用多播地址通信,一个请求不管到集群那个基点,它都会通过多播通信,把会话信息以组播的方式发送给其他成员;这里建议把接收器的地址专门用张网卡配置好地址;接下来我们启动下tomcatA,tomcatB,然后看看日志是否初始集群成功,并接收到集群成员接收器的地址;

提示:这里注意一点如果tomcat启动特别慢,就是8005端口要等很久才起来,可以尝试安装rng-tools,并启动rngd,这样可以加快tomcat启动

提示:如果在tomcatA的日志中能够看到tomcatB的接收器地址和端口,那么就表示tomcatA已经识别到tomcatB,并把tomcatB当作集群成员加入到集群;同样在tomcatB的日志中能够看到tomcatA的接收器地址和端口,表示tomcatB已经识别tomcatA并把它加入到集群;

配置nginx负载均衡后端两台tomcat server

提示:这里需要主要反代时需要把反代的URI和后面proxy_pass后面的URI相同,否则代理后,会话复制集群不会生效;

验证:检查nginx的配置文件语法,启动nginx访问192.168.0.41/myapp看看有什么变化

提示:可以看到访问192.168.0.41/myapp时sessionid始终没有发生变化,变化的只有后面的jvmRoute的值和页面的值;这说明我们访问nginx时,nginx也基于自己的轮询算法把请求调度到后端去了,第一次访问时,后端server会响应一个set-cookie的首部,把当前访问的页面的session信息响应给客户端,第二次访问客户端就会把上一次访问相应的cookie带上去访问,这时后端server接受到客户端发送过来的cookie,然后就在自己内存里找对应的session信息;由于后端server是把session信息基于多播通信的方式共享给集群其他节点,所以第二次不管调度到那台server上,对应server都会有该客户端第一次访问服务端的session信息;所以我们第二次访问时,sessionid还是第一次访问服务器的sessionid,后面的tomcatB表示由tomcatB这个jvmRoute处理的这次请求;

总结

connectionTimeout="20000"

redirectPort="8443" />

resourceName="UserDatabase"/>

resourceName="UserDatabase"/>

unpackWARs="true" autoDeploy="true">

prefix="localhost_access_log." suffix=".txt"

pattern="%h %l %u %t "%r" %s %b" />

channelSendOptions="8">

expireSessionsOnShutdown="false"

notifyListenersOnReplication="true"/>

address="228.0.0.4"

port="45564"

frequency="500"

dropTime="3000"/>

address="192.168.0.42"

port="4000"

autoBind="100"

selectorTimeout="5000"

maxThreads="6"/>

filter=""/>

tempDir="/tmp/war-temp/"

deployDir="/tmp/war-deploy/"

watchDir="/tmp/war-listen/"

watchEnabled="false"/>

nUSljOqV

unpackWARs="true" autoDeploy="true">

prefix="localhost_access_log." suffix=".txt"

pattern="%h %l %u %t "%r" %s %b" />

channelSendOptions="8">

expireSessionsOnShutdown="false"

notifyListenersOnReplication="true"/>

address="228.0.0.4"

port="45564"

frequency="500"

dropTime="3000"/>

address="192.168.0.42"

port="4000"

autoBind="100"

selectorTimeout="5000"

maxThreads="6"/>

filter=""/>

tempDir="/tmp/war-temp/"

deployDir="/tmp/war-deploy/"

watchDir="/tmp/war-listen/"

watchEnabled="false"/>

nUSljOqV

prefix="localhost_access_log." suffix=".txt"

pattern="%h %l %u %t "%r" %s %b" />

channelSendOptions="8">

expireSessionsOnShutdown="false"

notifyListenersOnReplication="true"/>

address="228.0.0.4"

port="45564"

frequency="500"

dropTime="3000"/>

address="192.168.0.42"

port="4000"

autoBind="100"

selectorTimeout="5000"

maxThreads="6"/>

filter=""/>

tempDir="/tmp/war-temp/"

deployDir="/tmp/war-deploy/"

watchDir="/tmp/war-listen/"

watchEnabled="false"/>

nUSljOqV

channelSendOptions="8">

expireSessionsOnShutdown="false"

notifyListenersOnReplication="true"/>

address="228.0.0.4"

port="45564"

frequency="500"

dropTime="3000"/>

address="192.168.0.42"

port="4000"

autoBind="100"

selectorTimeout="5000"

maxThreads="6"/>

filter=""/>

tempDir="/tmp/war-temp/"

deployDir="/tmp/war-deploy/"

watchDir="/tmp/war-listen/"

watchEnabled="false"/>

expireSessionsOnShutdown="false"

notifyListenersOnReplication="true"/>

address="228.0.0.4"

port="45564"

frequency="500"

dropTime="3000"/>

address="192.168.0.42"

port="4000"

autoBind="100"

selectorTimeout="5000"

maxThreads="6"/>

filter=""/>

tempDir="/tmp/war-temp/"

deployDir="/tmp/war-deploy/"

watchDir="/tmp/war-listen/"

watchEnabled="false"/>

address="228.0.0.4"

port="45564"

frequency="500"

dropTime="3000"/>

address="192.168.0.42"

port="4000"

autoBind="100"

selectorTimeout="5000"

maxThreads="6"/>

filter=""/>

tempDir="/tmp/war-temp/"

deployDir="/tmp/war-deploy/"

watchDir="/tmp/war-listen/"

watchEnabled="false"/>

address="192.168.0.42"

port="4000"

autoBind="100"

selectorTimeout="5000"

maxThreads="6"/>

filter=""/>

tempDir="/tmp/war-temp/"

deployDir="/tmp/war-deploy/"

watchDir="/tmp/war-listen/"

watchEnabled="false"/>

filter=""/>

tempDir="/tmp/war-temp/"

deployDir="/tmp/war-deploy/"

watchDir="/tmp/war-listen/"

watchEnabled="false"/>

tempDir="/tmp/war-temp/"

deployDir="/tmp/war-deploy/"

watchDir="/tmp/war-listen/"

watchEnabled="false"/>

给我们定义的应用修改器web.xml 在其中加上元素

提示:对于web.xml配置文件,我们可以从/etc/tomcat/中复制一份到自己的应用目录结构里,然后在非注释掉位置加上元素即可

对于tomcatB来说,我们也需要准备好同样的文件,为了区分,我们把index.jsp修改成tomcatB ,在配置文件中我们需要修改接收器的监听地址,以及jvmRoute的值,其他的都可以不变

到此tomcat会话复制集群就配置好了;其实从上面的配置文件可以看大,tomcat的会话复制集群就是利用多播地址通信,一个请求不管到集群那个基点,它都会通过多播通信,把会话信息以组播的方式发送给其他成员;这里建议把接收器的地址专门用张网卡配置好地址;接下来我们启动下tomcatA,tomcatB,然后看看日志是否初始集群成功,并接收到集群成员接收器的地址;

提示:这里注意一点如果tomcat启动特别慢,就是8005端口要等很久才起来,可以尝试安装rng-tools,并启动rngd,这样可以加快tomcat启动

提示:如果在tomcatA的日志中能够看到tomcatB的接收器地址和端口,那么就表示tomcatA已经识别到tomcatB,并把tomcatB当作集群成员加入到集群;同样在tomcatB的日志中能够看到tomcatA的接收器地址和端口,表示tomcatB已经识别tomcatA并把它加入到集群;

配置nginx负载均衡后端两台tomcat server

提示:这里需要主要反代时需要把反代的URI和后面proxy_pass后面的URI相同,否则代理后,会话复制集群不会生效;

验证:检查nginx的配置文件语法,启动nginx访问192.168.0.41/myapp看看有什么变化

提示:可以看到访问192.168.0.41/myapp时sessionid始终没有发生变化,变化的只有后面的jvmRoute的值和页面的值;这说明我们访问nginx时,nginx也基于自己的轮询算法把请求调度到后端去了,第一次访问时,后端server会响应一个set-cookie的首部,把当前访问的页面的session信息响应给客户端,第二次访问客户端就会把上一次访问相应的cookie带上去访问,这时后端server接受到客户端发送过来的cookie,然后就在自己内存里找对应的session信息;由于后端server是把session信息基于多播通信的方式共享给集群其他节点,所以第二次不管调度到那台server上,对应server都会有该客户端第一次访问服务端的session信息;所以我们第二次访问时,sessionid还是第一次访问服务器的sessionid,后面的tomcatB表示由tomcatB这个jvmRoute处理的这次请求;

总结


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Spring中异步注解@Async的使用、原理及使用时可能导致的问题及解决方法
下一篇:Spring中的singleton和prototype的实现
相关文章

 发表评论

暂时没有评论,来抢沙发吧~