您的位置:首页 > 运维架构 > Tomcat

Tomcat(四):MSM实现Tomcat的session集群

2016-03-16 15:31 483 查看
转自:http://my.oschina.net/masachencer/blog/637374

目录[-]

Tomcat(四):MSM实现Tomcat的session集群
session简介:
MSM简介:
实验拓扑:
实验环境:
实验流程:

Tomcat(四):MSM实现Tomcat的session集群

session简介:

  session:httpd是无状态协议,多个http请求之间是没有关联的,服务器端也无法识别哪些请求来自同一个客户端。为了解决这一问题,当客户端第一次访问时,服务器端会创建一个session来保存这一次的会话信息,然后将sessionID(session的唯一标识符)放置在响应报文的首部发送给客户端,客户端再次请求时会携带这个sessionID(通常在request的cookie中)表示这属于哪一个会话。

  session保持的方式:在Tomcat实现负载均衡后,客户端的请求会被调度至不同的服务器,session信息往往保存在其中一台服务器的内存中,若之后的请求被调度至其他的服务器上,则客户端无法访问到之前的session信息。解决这一问题的方式有3种:

  session绑定:在调度时,将同一个客户端的请求始终调度至同一台服务器;可以在前端的代理服务器上配置相应的参数实现,但是这种方式会影响负载均衡的效果,并且其中的一台服务器故障了,其上的session信息也会全部丢失。

  session集群:将多台服务器上的session信息实时进行同步;通过同步session实现,即每一个会话的session信息存在于所有的服务器上,这个不适用于大型的集群环境

  session服务器,将所有服务器上的session信息都存放至session服务器;将session信息集中存放至一台专用的服务器上,服务器在处理请求时会首先将session信息从memcache同步至本地,然后进行处理

MSM简介:

  MSM:Memcached Session Manager是一个高可用的Tomcat session共享解决方案,除了可以从本机内存快速读取Session信息(仅针对黏性Session)外,同时可使用memcached存取Session,以实现高可用。

MSM工作原理:

  粘性模式(Sticky Session):Tomcat本地Session为主Session,Memcached中的Session为备Session;安装在Tomcat上的MSM使用本机内存保存Session,当一个请求执行完毕之后,如果对应的Session在本地不存在(即某用户的第一次请求),则将该Session复制一份至Memcached;当该Session的下一个请求到达时,会使用Tomcat的本地Session,请求处理结束之后,Session的变化会同步更新到 Memcached,保证数据一致。当集群中的一个Tomcat挂掉,下一次请求会被路由到其他Tomcat上。负责处理此此请求的Tomcat并不清楚Session信息,于是从Memcached查找该Session,更新该Session并将其保存至本机。此次请求结束,Session被修改,送回Memcached备份。

  非黏性模式:Tomcat本地Session为中转Session,Memcached为主备Session;收到请求,加载备Session至本地容器,若备Session加载失败则从主Session加载;请求处理结束之后,Session的变化会同步更新到Memcached,并清除Tomcat本地Session

实验拓扑:





实验环境:

OS:CentOS-6.7-x86_64

Apache:

IP:192.168.1.3

Tomcat Node1:

IP:192.168.1.4

Tomcat Node2:

IP:192.168.1.5

Memcached1:

IP:192.168.1.6

Memcached2:

IP:192.168.1.7


实验流程:

Tomcat:两个Tomcat节点安装流程相同;

先安装Jvm:

[root@node1 ~]# yum install java-1.7.0-openjdk
[root@node1 ~]# java -version
java version "1.7.0_79"
OpenJDK Runtime Environment (rhel-2.5.5.4.el6-x86_64 u79-b14)
OpenJDK 64-Bit Server VM (build 24.79-b02, mixed mode)

安装tomcat:官网:http://tomcat.apache.org

[root@node1 ~]# tar xf apache-tomcat-7.0.65.tar.gz -C /usr/local/
[root@node1 ~]# cd /usr/local/
[root@node1 local]# ln -sv apache-tomcat-7.0.65 tomcat
"tomcat" -> "apache-tomcat-7.0.65"
[root@node1 ~]# vim /etc/profile.d/tomcat.sh
export CATALINA_HOME=/usr/local/tomcat
export PATH=$CATALINA_HOME/bin:$PATH
[root@node1 ~]# source /etc/profile.d/tomcat.sh

提供脚本:

[root@node1 ~]# cat /etc/rc.d/init.d/tomcat
#!/bin/sh
# Tomcat init script for Linux.
#
# chkconfig: 2345 96 14
# description: The Apache Tomcat servlet/JSP container.
# JAVA_OPTS='-Xms64m -Xmx128m'
JAVA_HOME=/usr/lib/jvm/jre
CATALINA_HOME=/usr/local/tomcat
export JAVA_HOME CATALINA_HOME

case $1 in
start)
exec $CATALINA_HOME/bin/catalina.sh start ;;
stop)
exec $CATALINA_HOME/bin/catalina.sh stop;;
restart)
$CATALINA_HOME/bin/catalina.sh stop
sleep 2
exec $CATALINA_HOME/bin/catalina.sh start ;;
*)
echo "Usage: `basename $0` {start|stop|restart}"
exit 1
;;
esac
[root@node1 ~]# chmod +x /etc/rc.d/init.d/tomcat
[root@node1 ~]# chkconfig tomcat --add

定义管理页面用户名及密码:

[root@node1 ~]# cd /usr/local/tomcat/conf
[root@node1 conf]# vim tomcat-users.xml
<role rolename="manager-gui"/>
<role rolename="admin-gui"/>
<user username="tomcat" password="tomcat" roles="manager-gui,admin-gui"/>

配置文件复制到node2,并启动服务:

[root@node1 conf]# scp tomcat-users.xml node2:/usr/local/tomcat/conf/
[root@node1 conf]# service tomcat start; ssh node2 'service tomcat start'

访问测试:





部署站点文件:

Node1:
[root@node1 ~]# mkdir -p /tomcat/webapps/test/WEB-INF/{classess,lib}
[root@node1 ~]# cd /tomcat/webapps/test
[root@node1 test]# vim index.jsp
<%@ page language="java" %>
<html>
<head><title>Tomcat Node1</title></head>
<body>
<h1><font color="red">node1.chencer.org</font></h1>
<table align="centre" border="1">
<tr>
<td>Session ID</td>
<% session.setAttribute("chencer.org","chencer.org"); %>
<td><%= session.getId() %></td>
</tr>
<tr>
<td>Created on</td>
<td><%= session.getCreationTime() %></td>
</tr>
</table>
</body>
</html>

Node2:
[root@node2 ~]# mkdir -p /tomcat/webapps/test/WEB-INF/{classess,lib}
[root@node2 ~]# cd /tomcat/webapps/test
[root@node2 test]# vim index.jsp
<%@ page language="java" %>
<html>
<head><title>Tomcat node2</title></head>
<body>
<h1><font color="red">node2.chencer.org</font></h1>
<table align="centre" border="1">
<tr>
<td>Session ID</td>
<% session.setAttribute("chencer.org","chencer.org"); %>
<td><%= session.getId() %></td>
</tr>
<tr>
<td>Created on</td>
<td><%= session.getCreationTime() %></td>
</tr>
</table>
</body>
</html>

定义虚拟主机,并重启tomcat:

Node1:
[root@node1 ~]# cd /usr/local/tomcat
[root@node1 tomcat]# vim conf/server.xml
<Engine name="Catalina" defaultHost="node1.chencer.org">

<Host name="node1.chencer.org" appBase="/tomcat/webapps" unpackWARs="true" autoDeploy="true">
<Context path="/" docBase="test" />
</Host>
[root@node1 tomcat]# service tomcat restart

Node2:
[root@node2 ~]# cd /usr/local/tomcat
[root@node2 tomcat]# vim conf/server.xml
<Engine name="Catalina" defaultHost="node2.chencer.org">

<Host name="node2.chencer.org" appBase="/tomcat/webapps" unpackWARs="true" autoDeploy="true">
<Context path="/" docBase="test" />
</Host>
[root@node2 tomcat]# service tomcat restart

访问测试:





配置apache基于mod_proxy实现Tomcat负载均衡:

安装httpd:

[root@node0 ~]# yum install httpd

确保httpd有以下模块:

[root@node0 ~]# httpd -M | grep proxy
proxy_module (shared)
proxy_balancer_module (shared)
proxy_ftp_module (shared)
proxy_http_module (shared)
proxy_ajp_module (shared)
proxy_connect_module (shared)

编辑httpd配置文件:

[root@node0 ~]# cd /etc/httpd/conf
[root@node0 conf]# vim httpd.conf
# DocumentRoot "/var/www/html"  \\:关闭中心主机;

在全局配置段中添加以下内容:
<proxy balancer://cluster>  \\:定义系群名;
BalancerMember http://192.168.1.4:8080 loadfactor=1 \\:集群节点,loadfactor表示权重;
BalancerMember http://192.168.1.5:8080 loadfactor=1
ProxySet  lbmethod=bytraffic    \\:调度算法;
</proxy>

NameVirtualHost *:80    \\:启用虚拟主机;
<VirtualHost *:80>
ServerName node0.chencer.org
ProxyVia On \\:via信息;
ProxyRequests off   \\:关闭正向代理;
ProxyPreserveHost on    \\:支持虚拟合租记;
ProxyPass  / balancer://cluster stickysession=jsessionid    \\:请求至后端主机;
ProxyPassReverse / balancer://cluster stickysession=jsessionid  \\:请求至后端主机;
</VirtualHost>
[root@node0 conf]# httpd -t
[root@node0 conf]# service httpd start

访问测试:





Memcached:两个Memcached节点安装流程相同;

安装并启动Memcached:

[root@node3 ~]# yum install memcached libevent
[root@node3 ~]# service memcached start

Memcached默认监听11211/tcp端口:

[root@node3 ~]# ss -tnl
State  Recv-Q  Send-Q  Local Address:Port  Peer Address:Port
LISTEN 0       128     :::11211            :::*
LISTEN 0       128       *:11211               *:*

配置Tomcat支持Memcached:

准备所需jar包:

[root@node1 msm]# ls
javolution-5.4.3.1.jar
memcached-session-manager-1.8.3.jar
memcached-session-manager-tc7-1.8.3.jar
msm-javolution-serializer-1.8.3.jar
spymemcached-2.10.6.jar
[root@node1 msm]# cp * /usr/local/tomcat/lib/

Tomcat默认虚拟主机添加容器:

Node1:
[root@node1 msm]# cd /usr/local/tomcat
[root@node1 tomcat]# vim conf/server.xml
<Host name="node1.chencer.org" appBase="/tomcat/webapps" unpackWARs="true" autoDeploy="true">
<Context path="/" docBase="test" reloadable="true">
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="n1:192.168.1.6:11211,n2:192.168.1.7:11211"
failoverNodes="n1"
requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
transcoderFactoryClass="de.javakaffee.web.msm.serializer.javolution.JavolutionTranscoderFactory" />
</Context>
</Host>
[root@node1 tomcat]# service tomcat restart

Node2:
[root@node2 msm]# cd /usr/local/tomcat
[root@node2 tomcat]# vim conf/server.xml
<Host name="node2.chencer.org" appBase="/tomcat/webapps" unpackWARs="true" autoDeploy="true">
<Context path="/" docBase="test" reloadable="true">
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="n1:192.168.1.6:11211,n2:192.168.1.7:11211"
failoverNodes="n1"
requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
transcoderFactoryClass="de.javakaffee.web.msm.serializer.javolution.JavolutionTranscoderFactory" />
</Context>
</Host>
[root@node2 tomcat]# service tomcat restart

访问测试:



模拟故障:关闭node1;

[root@node1 tomcat]# service tomcat stop

请求被调度到Node2,但是Session ID并未发生改变;



关闭Memcached2:

[root@node4 ~]# service memcached stop

Session已转移到n1上,而且Session ID并未发生改变;

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: