tomcat集群和session保持

tomcat是一个servlet和jsp容器,可以解析java程序,所以web网站后台需要解析java的一些动态网页代码时,就需要在后台使用tomcat服务来处理。这里使用nginx,httpd和haproxy代理服务器分别加上tomcat节点做集群,然后使用两种方式来保持集群的session。

集群

1.实验环境

  • 代理服务器为172.16.200.102,centos6.9
  • 节点服务器1为172.16.200.103,centos6.9
  • 节点服务器2为172.16.200.104,centos6.9

2.节点服务器安装tomcat:
tomcat 是基于java虚拟机运行的,所以要安装tomcat就要先安装java环境,这里安装java-1.8.0-openjdk-devel.x86_64,其他的组件就有依赖关系一起安装了

[root@localhost ~]# yum -y install java-1.8.0-openjdk-devel

安装完成后需要设置java的环境变量

[root@localhost ~]# which java    #查看java程序位置
/usr/bin/java
[root@localhost ~]# vim /etc/profile.d/java.sh
export JAVA_HOME=/usr/bin/java
export PATH=$JAVA_HOME:$PATH
[root@localhost ~]# . /etc/profile.d/java.sh    
[root@localhost ~]# echo $PATH
/usr/bin/java:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

安装tomcat

[root@localhost ~]#  yum -y install tomcat  tomcat-lib tomcat-admi
n-webapps tomcat-docs-webapp tomcat-webapps

安装完成后,我们就可以去冷部署一个测试程序了(tomcat和httpd不同,不能直接将动态程序放到web的默认路径下就可以使用,因为java代码都是类文件,可能还依赖于类库中的其他文件,需要使用类加载加载完成后才会运行。就是每个程序都是单独管理的,所以tomcat的每个应用程序目录都有固定的格式,所以我们需要先将目录创建出来):

[root@localhost tomcat]# mkdir -p /usr/share/tomcat/webapps/te
st/{class,lib,WEB-INF}
[root@localhost tomcat]# vim /usr/share/tomcat/webapps/test/in
dex.jsp    #创建一个主页文件,加入以下测试内容
<%@ page language="java" %>
                    <html>
                        <head><title>TomcatA</title></head>
                        <body>
                            <h1><font color="red">TomcatA.magedu.com</font></h1>
                            <table align="centre" border="1">
                                <tr>
                                    <td>Session ID</td>
                                <% session.setAttribute("magedu.com","magedu.com"); %>
                                    <td><%= session.getId() %></td>
                                </tr>
                                <tr>
                                    <td>Created on</td>
                                    <td><%= session.getCreationTime() %></td>
                                </tr>
                            </table>
                        </body>
                    </html>

然后去启动tomcat

[root@localhost tomcat]# systemctl start tomcat

启动完成后用浏览器访问这个程序的测试页,在浏览器中输入http://172.16.200.103:8080,因为tomcat默认监听的地址为8080端口
在节点2服务器上同样执行上述步骤,不过测试页面改为蓝色的,这样方便分辨两台节点服务器:

<%@ page language="java" %>
                    <html>
                        <head><title>TomcatB</title></head>
                            <body>
                            <h1><font color="blue">TomcatB.magedu.com</font></h1>
                            <table align="centre" border="1">
                                <tr>
                                    <td>Session ID</td>
                                <% session.setAttribute("magedu.com","magedu.com"); %>
                                    <td><%= session.getId() %></td>
                                </tr>
                                <tr>
                                    <td>Created on</td>
                                    <td><%= session.getCreationTime() %></td>
                                </tr>
                            </table>
                            </body>
                    </html> 

3.代理服务器配置
在172.16.200.102服务器中:
(1)我们先使用haproxy作为前端代理服务器

[root@localhost nginx]# yum -y install haproxy
[root@localhost nginx]# vim /etc/haproxy/haproxy.cfg
# 我们先在尾行模式中将frontend之后的行注释掉,将光标放到frontend  main *:5000行处,进入尾行模式,输入  .,$s/^[^#]/#&/  将没有#号的行之前加上#号,然后加入以下内容
frontend  tom    #定义前端
        bind *:80
        default_backend webapp    #默认后端服务器

backend webapp
        balance roundrobin    #使用轮询算法
        #
        server app1 172.16.200.103:8080 check  #定义两个节点,都使用健康检测
        server app2 172.16.200.104:8080 check
[root@localhost nginx]# service  haproxy start 

启动完服务后,在浏览器输入http://172.16.200.102/test ,一直刷新,红蓝两个页面交替出现证明代理成功
(2)使用httpd作为前端代理服务器

[root@localhost nginx]# service stop haproxy    #先将haproxy服务关闭
[root@localhost nginx]# yum -y install httpd
[root@localhost nginx]# vim /etc/httpd/conf.d/tom.conf
#定义分组
<proxy balancer://tcsrvs>
                                BalancerMember http://172.16.200.103:8080
                                BalancerMember http://172.16.200.104:8080
                                ProxySet lbmethod=byrequests
                        </Proxy>    
#定义虚拟机并使用分组
                        <VirtualHost *:80>
                                ServerName www.feng.com
                                ProxyVia On
                                ProxyRequests Off
                                ProxyPreserveHost On
                                <Proxy *>
                                        Require all granted
                                </Proxy>
                                ProxyPass / balancer://tcsrvs/
                                ProxyPassReverse / balancer://tcsrvs/
                                <Location />
                                        Require all granted
                                </Location>
                        </VirtualHost>
[root@localhost nginx]#  service httpd start 

浏览器访问http://172.16.200.102/test,不断刷新,红蓝交替证明代理成功。如果没有成功,可以尝试将配置文件中的Require all granted注释掉再次尝试,这个原因是版本问题。
(3)使用nginx 作为前端代理服务器

[root@localhost nginx]#  service httpd stop    #先关闭httpd服务
[root@localhost nginx]# yum -y install nginx    #安装nginx
[root@localhost nginx]# vim /etc/nginx/nginx.conf   #到主配置文件中,在http上下文中,添加以下内容
upstream webapp {     
        server 172.16.200.103:8080;
        server 172.16.200.104:8080;
        }    #定义一个7层的分组,由于tomcat监听的是8080端口,所以,这里要加上8080
[root@localhost nginx]# vim /etc/nginx/conf.d/default.conf
listen       80;
listen       [::]:80;    #将这两行的default删除
[root@localhost nginx]# vim /etc/nginx/conf.d/tom.conf
server {
        listen 80 default;
        server_name www.feng.com;
        index index.jsp index.html;
        location / {
                proxy_pass http://webapp;
        }
}
[root@localhost nginx]# nginx -t
[root@localhost nginx]# nginx -s reload

完成后浏览器访问http://172.16.200.102/test/,刷新,出现蓝色红色交替出现,代理成功。

session保持

sessionv保持有几种方法:

  • 1.使用会话粘性的方式,代理服务器通过指定定的目标,将访问同一目标的请求每次都访问同一台节点服务器,达到session保持的效果。常用的有通过源地址,通过给客户端设置session首部,通过访问的url来实现。
  • 2.使用会话同步的方式将每个节点的会话复制到别的节点中,这样客户端访问每个节点,都有自己的session了,这种方式在集群中节点多的情况下,会严重浪费资源,导致服务器崩溃,所以只能用在小型集群环境中
  • 3.使用session server,将用户的session放到一台专门存储session的服务器中,这里我们使用memcached服务来作为session服务器。这种方式的弊端在于如果session服务器只有一台,那就成了单点,所以要使用两台或以上的session服务器,不过memcached服务在集群中使用的是旁挂式工作模式,自己没有主从的功能,只能通过节点服务器将session一起写入不同的session服务器中。
下面我们来分别实现三种session保持方式

1.会话粘性
(1)haproxy做会话粘性
先关闭之前实验的nginx服务

[root@localhost httpd]# service nginx stop

在haproxy主配置文件/etc/haproxy/haproxy.cfg中做修改,如下,增加cookie行,然后在server行最后加上cookie识别信息,通常和节点名字一样就好,以便识别.

backend webapp
        balance roundrobin
        cookie SRV  insert indirect
        server app1 172.16.200.103:8080 check cookie app1
        server app2 172.16.200.104:8080 check cookie app2

完成后重启haproxy,再次访问http://172.16.200.102/test,刷新也只会出现一个页面了。
(2)httpd做会话粘性
关闭haproxy
在/etc/http/conf.d/tom.conf中修改,如下

                        Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED    #添加cookie首部
<proxy balancer://tcsrvs>
                                BalancerMember http://172.16.200.103:8080 route=tomcatA loadfactor=1    #在这行两行之后添加route 和loadfactor
                                BalancerMember http://172.16.200.104:8080 route=tomcatB loadfactor=2
                                ProxySet lbmethod=byrequests
                                ProxySet stickysession=ROUTEID    #设置会话粘性目标

设置完成后重启httpd服务,然后测试,刷新看到页面没有改变。
(3)nginx做会话粘性
先关闭httpd
在nginx主配置文件/etc/nginx/nginx.conf中修改,在upstream上下文中添加调度算法(不添加默认是轮询),如下

upstream webapp {
        server 172.16.200.103:8080;
        server 172.16.200.104:8080;
        hash $request_uri consistent;    #添加这一行,使用请求的uri为目标来做会话粘性,consistent是一致性哈希算法,不加的话只是hash表示静态数组法,也叫做取模法。
        }

完成后重启nginx,测试,刷新也不会改变页面了。

2.session同步
session同步是在节点中设置的,我们先将之前实验的会话粘性取消掉,这里就使用最后一个测试的nginx服务来做第二个方法的前端代理服务器,在/etc/nginx/nginx.conf中将调度算法hash $request_uri consistent;这行注释掉,然后重载nginx,就又回到轮询算法了,然后接可以接着搞我们的session同步实验了。
步骤:
在172.16.200.103和104中:
(1)在主配置文件中添加每台主机的标识

[root@localhost webapps]# vim /etc/tomcat/server.xml
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tcA">    #在这一行之后添加jvmRoute="tcA"
#然后在下边添加会话集群的配置
<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.16.0.4"
                            port="45564"
                            frequency="500"
                            dropTime="3000"/>
                    <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
                        address="172.16.200.103"
                        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>  

然后添加test测试程序的web.xml文件,并修改

[root@localhost webapps]# cd /usr/share/tomcat/webapps/test/WEB-INF/
[root@localhost WEB-INF]# cp /etc/tomcat/web.xml .
[root@localhost WEB-INF]# vim web.xml
#在web app段中找个位置添加如下内容
<distributable/>

注意172.16.200.103和172.16.200.104中的Receiver 段的address要写的是本机的ip,两台主机是不一样的,注意改一下
完成后重启tomcat,然后就可以验证了,我们在/var/log/tomcat/catalina./var/log/tomcat/catalina.日期.log日志文件中可以看到一条提示信息:

INFO: Replication member added:org.apache.catalina.tribes.membership.MemberImpl[tcp://{172, 16, 200, 104}:4000,{172, 16, 200, 104},400
0, alive=1026, securePort=-1, UDP Port=-1, id={-25 -69 35 46 -118 -31 64 -88 -66 -113 -103 45 -113 -88 -40 -107 }, payload={}, command={}, domain={}, ]

看到这条信息就证明一个节点收到另外一个节点启动的信息了,证明实验成功。当然,我们也可以用浏览器访问172.16.200.102这个前端主机,刷新,然后发现后端节点会变,但是session的编号没有改变,这样也表示实验成功了。

3.使用session server来保持会话,这里我们使用memcached当作session server.
实验之前我们先将前一个实验的Tomcat Session Replication Cluster注释掉(就是上个实验中会话集群配置,在/etc/tomc),然后重启tomcat,确保之前的实验不会影响这个实验的结果
步骤:
我们在两台节点上安装memcached,这样可以少开两台虚拟机,节省资源,可以把这两个memcached服务想象成是安装在独立的服务器上就行。
(1)在两个节点上安装memcached:

[root@localhost WEB-INF]# yum -y install memcached

(2)下载需要的资源
http://code.google.com/p/memcached-session-manager/, https://github.com/magro/memcached-session-manager这个github托管地址中下载如下包:
memcached-session-manager-${version}.jar
memcached-session-manager-tc${6,7,8}-${version}.jar #这个是tomcat是什么版本就下载什么版本
spymemcached-${version}.jar
msm-javolution-serializer-${version}.jar
javolution-${version}.jar
将下载出来的资源放到tomcat的lib目录中/usr/share/java/tomcat
(3)在两台节点的主配置文件中要测试的主机添加如下内容:

<Context path="/test" docBase="/usr/local/tomcat/webapps/test" reloadable="true">
              <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
                memcachedNodes="n1:172.16.100.9:11211,n2:172.16.100.10:11211"
                failoverNodes="n1"
                requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
                transcoderFactoryClass="de.javakaffee.web.msm.serializer.javolution.JavolutionTranscoderFactory"
              />
             </Context>

然后重启tomcat,测试,访问172.16.200.102/test,然后刷新,发现红蓝两个页面交替出现,但是session ID不变,实验成功

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,761评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,953评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,998评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,248评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,130评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,145评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,550评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,236评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,510评论 1 291
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,601评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,376评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,247评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,613评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,911评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,191评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,532评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,739评论 2 335

推荐阅读更多精彩内容