session实现共享的方法有多种, 对于Web应用集群的技术实现而言,最大的难点就是如何在集群中的多个节点之间保持数据的一致性,session会话是这些数据中最重要的一块,要实现这一点大体上有两种方式:
一种是把所有的session数据放到一台服务器或者数据库中,集群中的所有节点通过访问这台Session服务器来获取数据;另一种就是集群中的所有节点间进行Session数据的同步拷贝,任何一个节点均保存了所有的session数据。
下面是具体的几种session同步共享方案,通过分析其各自优劣找出其适应场景:
1)应用服务器自身集群特性实现seesion复制
大部分应用服务器在集群中都提供了session复制的功能。如Tomcat,jboss
优点:简单
缺点:性能随着服务器增加而下降,容易引起广播风暴
2)使用数据库保存session
每次请求都进行数据库读写,还要HA解决数据库单点故障问题
3)使用共享存储来保存session
共享存储是一个单点,可以通过raid解决
4)使用memcached来保存session
和数据库类似,不过因为是内存存取的,性能要比数据库好很多,不过如果memcached服务器宕机,session就会丢失,在扩展Tomcat 6.x中,使用mecached存放session
系统环境:rhel6.5 x64 selinux and iptables disabled
主机角色:
node1: 192.168.0.91:nginx tomcat memcached
node2: 192.168.0.92:tomcat memcached
软件下载:http://www.nginx.org
http://code.google.com/p/memcached-session-manager
实验工作原理:
<T1> <T2>
. \ / .
. \ / .
. / \ .
. / \ .
<M1> <M2>
Tomcat-1将session存储在memcached-2(T2)上,只有当M2不可用时,T1才将session存储在memcached-1(M1是T1的failoverNode),使用这种配置的好处是当T1和M1同时崩溃时也不会丢失session会话,避免单点故障。
1.在两个节点node1和node2上同时安装tomcat
sh jdk-6u26-linux-x64.bin
mv jdk1.6.0_26/ /usr/local/jdk
vi /etc/profile //设置java的环境变量
export JAVA_HOME=/usr/local/jdk
export CLASSPATH=:$JAVA_HOME/lib
export PATH=$PATH:$JAVA_HOME/bin
source /etc/profile
tar zxf apache-tomcat-7.0.8.tar.gz -C /usr/local //解压到/usr/local目录下
mv /usr/local/apache-tomcat-7.0.8 /usr/local/tomcat
session 的序列化方案官方推荐的有 4 种:
1. java serialization
2. msm-kryo-serializer
3. msm-javolution-serializer
4. msm-xstream-serializer
其中性能最好的序列化方案是 Kryo,此实验我们采用 kryo 方式。
session会话的保持我们用到的是msm(memcached-session-manager),它需要一些类库,所以将如下软件包放置到/usr/local/tomcat/lib 目录中
kryo-1.03.jar
kryo-serializers-0.8.jar
memcached-2.5.jar
memcached-session-manager-1.5.1.jar
memcached-session-manager-tc7-1.5.1.jar
minlog-1.2.jar
msm-kryo-serializer-1.5.1.jar
reflectasm-0.9.jar
vi /usr/local/tomcat/conf/context.xml //在这个文件下修改是可以立即将session丢入到memcached中
<Context>
...... //添加以下字段
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="n1:192.168.0.91:11211,n2:192.168.0.92:11211" //在节点处添加memcached的ip和端口号
failoverNodes="n1" #在 node2 上此项设置为“n2”
requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
/>
</Context>
/usr/local/tomcat/bin/startup.sh #启动 tomcat
2.在两个节点上安装memcached
yum install memcached -y
service memcached start //11211端口打开
3.在节点node1上安装nginx
yum install -y pcre-devel openssl-devel
tar zxf nginx-1.0.6.tar.gz
tar zxf nginx-sticky-module-1.0.tar.gz -C nginx-1.0.6
useradd -s /sbin/nologin nginx
cd nginx-1.0.6
./configure --user=nginx --group=nginx –with-http_ssl_module --with-http_stub_status_module -add-module=nginx-sticky-module-1.0/
make && make install
注: nginx-sticky-module 为 nginx 的第三方模块,使 nginx 支持 sticky 模式,所谓 sticky 模式
就是指同一个用户的访问请求都被发送到同一个 tomcat 实例上处理。
http {
upstream server.example.com {
sticky;
server 192.168.0.91:8080;
server 192.168.0.92:8080;
}
server {
listen
server_name 80;
desktop91.example.com;
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html
location = /50x.html {
root html;
}
location ~ \.jsp$ { #所有 jsp 页面交给 tomcat 处理,动静分离
proxy_pass http://server.example.com;
}
}
}
4.以下为测试页面,保存到/usr/local/tomcat/webapps/ROOT/test.jsp //定义一个会话窗口
<%@ page contentType="text/html; charset=GBK" %>
<%@ page import="java.util.*" %>
<html><head><title>Cluster App Test</title></head>
<body>
Server Info:
<%
out.println(request.getLocalAddr() + " : " + request.getLocalPort()+"<br>");%>
<%
out.println("<br> ID " + session.getId()+"<br>");
String dataName = request.getParameter("dataName");
if (dataName != null && dataName.length() > 0) {
String dataValue = request.getParameter("dataValue");
session.setAttribute(dataName, dataValue);
}
out.print("<b>Session list</b>");
Enumeration e = session.getAttributeNames();
while (e.hasMoreElements()) {
String name = (String)e.nextElement();
String value = session.getAttribute(name).toString();
out.println( name + " = " + value+"<br>");
System.out.println( name + " = " + value);
}
%>
<form action="test.jsp" method="POST">
name:<input type=text size=20 name="dataName">
<br>
key:<input type=text size=20 name="dataValue">
<br>
<input type=submit>
</form>
</body>
</html>
tail -f logs/catalina.out //查看日志
访问 http://server.example.com/test.jsp,不同的主机访问时会调度到不同的 tomcat 实例上处理
来自同一主机的请求会交给同一个 tomcat 实例处理,此时你 down 掉当前正在响应的 tomcat 实
例,nginx 会自动把用户的请求调度到另一个 tomcat 实例上,同时 session 也没有丢掉。
本文出自 “8397752” 博客,请务必保留此出处http://8407752.blog.51cto.com/8397752/1685410
nginx+tomcat+memcached实现session共享
原文地址:http://8407752.blog.51cto.com/8397752/1685410