对于web应用集群的技术实现而言,最大的难点就是:如何能在集群中的多个节点之间保持数据的一致性,会话(Session)信息是这些数据中最重要的一块。要实现这一点, 大体上有两种方式: 一种是把所有Session数据放到一台服务器上或者数据库中,集群中的所有节点通过访问这台Session服务器来获取数据; 另一种就是在集群中的所有节点间进行Session数据的同步拷贝,任何一个节点均保存了所有的Session数据。
Tomcat集群session同步方案有以下几种方式: 1)使用tomcat自带的cluster方式,多个tomcat间自动实时复制session信息,配置起来很简单。但这个方案的效率比较低,在大并发下表现并不好。 2)利用nginx的基于访问ip的hash路由策略,保证访问的ip始终被路由到同一个tomcat上,这个配置更简单。但如果应用是某一个局域网大量用户同时登录,这样负载均衡就没什么作用了。 3)利用nginx插件实现tomcat集群和session同步,nginx-upstream-jvm-route-0.1.tar.gz,是一个Nginx的扩展模块,用来实现基于Cookie的Session Sticky的功能。 4)利用memcached实现(MSM工具)。memcached存储session,并把多个tomcat的session集中管理,前端在利用nginx负载均衡和动静态资源分离,在兼顾系统水平扩展的同时又能保证较高的性能。 5)利用redis实现。使用redis不仅仅可以将缓存的session持久化,还因为它支持的单个对象比较大,而且数据类型丰富,不只是缓存 session,还可以做其他用途,可以一举几得。 6)利用filter方法实现。这种方法比较推荐,因为它的服务器使用范围比较多,不仅限于tomcat ,而且实现的原理比较简单容易控制。 7)利用terracotta服务器共享session。这种方式配置比较复杂。
在Tomcat集群中,当一个节点出现故障,虽然有高可用集群来负责故障转移,但用户的session信息如何保持呢? 下面介绍第4种方案,session复制同步使用MSM(Memcache-Session-Manager),即利用MSM+Memcached做Session共享。
MSM介绍:(详细介绍可以参考:http://www.cnblogs.com/kevingrace/p/6401025.html) MSM是一个高可用的Tomcat Session共享解决方案,除了可以从本机内存快速读取Session信息(仅针对黏性Session)外,还可使用Memcached存取Session,以实现高可用。 传统tomcat集群,会话复制随着结点数增多,扩展性成为瓶颈。MSM使用memcached完成统一管理tomcat会话,避免tomcat结点间过多会话复制。 MSM利用Value(Tomcat 阀)对Request进行跟踪。Request请求到来时,从memcached加载session,Request请求结束时,将tomcat session更新至memcached,以达到session共享之目的, 支持sticky和non-sticky模式: sticky : 会话粘连模式(黏性session)。客户端在一台tomcat实例上完成登录后,以后的请求均会根据IP直接绑定到该tomcat实例。 no-sticky:会话非粘连模式(非粘性session)。客户端的请求是随机分发,多台tomcat实例均会收到请求。
在进行环境部署之前,要对cookie和session的工作机制非常了解,如果不了解其中的原理且只是机械性地去按照参考文档部署,那么这是毫无意义的。 a)cookie是怎么工作的? 加入我们创建了一个名字为login的Cookie来包含访问者的信息,创建Cookie时,服务器端的Header如下面所示,这里假设访问者的注册名是“wangshibo”,同时还对所创建的Cookie的属性如path、domain、expires等进行了指定。
1 2 |
|
上面这个Header会自动在浏览器端计算机的Cookie文件中添加一条记录。浏览器将变量名为“login”的Cookie赋值为“wangshibo”。 注意,在实际传递过程中这个Cookie的值是经过了URLEncode方法的URL编码操作的。 这个含有Cookie值的HTTP Header被保存到浏览器的Cookie文件后,Header就通知浏览器将Cookie通过请求以忽略路径的方式返回到服务器,完成浏览器的认证操作。 此外,我们使用了Cookie的一些属性来限定该Cookie的使用。例如Domain属性能够在浏览器端对Cookie发送进行限定,具体到上面的例子,该Cookie只能传到指定的服务器上,而决不会跑到其他的Web站点上去。Expires属性则指定了该Cookie保存的时间期限,例如上面的Cookie在浏览器上只保存到1999年3月1日1秒。 当然,如果浏览器上Cookie太多,超过了系统所允许的范围,浏览器将自动对它进行删除。至于属性Path,用来指定Cookie将被发送到服务器的哪一个目录路径下。 说明:浏览器创建了一个Cookie后,对于每一个针对该网站的请求,都会在Header中带着这个Cookie;不过,对于其他网站的请求Cookie是绝对不会跟着发送的。而且浏览器会这样一直发送,直到Cookie过期为止。
b)session是如何工作的? 由于http是无状态的协议,你访问了页面A,然后再访问B页面,http无法确定这2个访问来自一个人,因此要用cookie或session来跟踪用户,根据授权和用户身份来 显示不同的页面。比如用户A登陆了,那么能看到自己的个人信息,而B没登陆,无法看到个人信息。还有A可能在购物,把商品放入购物车,此时B也有这个过程, 你无法确定A,B的身份和购物信息,所以需要一个session ID来维持这个过程。 cookie是服务器发给客户端并保持在客户端的一个文件,里面包含了用户的访问信息(账户密码等),可以手动删除或设置有效期,在下次访问的时候,会返给服务器。 注意:cookie可以被禁用,所以要想其他办法,这就是session。cookie数据存放在客户的浏览器上,session数据放在服务器上。cookie同时也是session id的载体,cookie保存session id。另外:cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗,考虑到安全应当使用session。session是服务器端缓存,cookie是客户端缓存。所以建议:将登陆信息等重要信息存放为session;其他信息如果需要保留,可以放在cookie中, 比如:你去商场购物,商场会给你办一张会员卡,下次你来出示该卡,会有打折优惠,该卡可以自己保存(cookie),或是商场代为保管,由于会员太多,个人需要保存卡号信息(session ID)。
为什么要持久化session(共享session)? 因为:在客户端每个用户的Session对象存在Servlet容器中,如果Tomcat服务器重启或者宕机的话,那么该session就会丢失,而客户端的操作会由于session丢失而造成数据丢失;如果当前用户访问量巨大,每个用户的Session里存放大量数据的话,那么就很占用服务器大量的内存,进而致使服务器性能受到影响。 可以使用数据库持久化session,分为物理数据库和内存数据库。物理数据库备份session,由于其性能原因,不推荐;内存数据库可以使用redis和memcached,这里介绍memcached的方法。
MSM工作原理: a)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备份。 b)Non-sticky Session (非黏性)模式下的工作原理(记住:多台tomcat集群或多个tomcat实例时需要选择Non-Sticky模式,即sticky="false"): Tomcat本地Session为中转Session,Memcached为主备Session。 收到请求,加载备Session至本地容器,若备Session加载失败则从主Session加载; 请求处理结束之后,Session的变化会同步更新到Memcached,并清除Tomcat本地Session。
------------------------------------------------------------------------------------------------------------ 废话不多说了,下面直接看nginx+memcached+tomcat实现session共享的集群操作记录:: 一、集群实验环境信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
实验拓扑图:
二、nginx安装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
|
三、memcached安装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
四、安装jdk
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
|
五、安装与配置tomcat 1)安装tomcat [[email protected] src]# wget http://apache.fayea.com/tomcat/tomcat-7/v7.0.75/bin/apache-tomcat-7.0.75.tar.gz [[email protected] src]# tar -zvxf apache-tomcat-7.0.75.tar.gz [[email protected] src]# mv apache-tomcat-7.0.75 /usr/local/tomcat1
2)添加memcached和msm(Memcached_Session_Manager)的依赖jar包,如下:
1 2 3 4 5 6 7 8 9 |
|
注意:memcached-session-manager-tc7-1.7.0.jar中的tc7为tomcat的版本号。一定要注意:不同版本号的tomcat,对应的msm包也不同。此处为tomcat7的jar包
上面依赖包下载地址:https://pan.baidu.com/s/1eRRncpO 提取密码:y56i
--------------------------------------------------------------------------------------------------------------------------------- msm相关版本的jar包下载地址:http://repo1.maven.org/maven2/de/javakaffee/msm/ spymemcached相关版本下载地址:http://repo1.maven.org/maven2/net/spy/spymemcached ---------------------------------------------------------------------------------------------------------------------------------
把依赖包下载后全部上传到tomcat1和tomcat2的安装路径下的lib/ 目录下
3)配置tomcat
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
接下来进行序列化tomcat配置,修改conf/context.xml文件。 序列化tomcat配置的方法有很多种:java默认序列化tomcat配置、javolution序列化tomcat配置、xstream序列化tomcat配置、flexjson序列化tomcat配置和kryo序列化tomcat配置。官网介绍说 使用kryo 序列化tomcat的效率最高,所以这里只介绍kryo序列化。 在No-Stick模式和Stick模式下context.xml文件配置也有所不同(一般用的是No-Stick模式) a)No-Stick模式(记住:多台tomcat集群或多个tomcat实例时 需要选择Non-Sticky模式,即sticky="false")
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
b)Stick模式。故障转移配置节点(failoverNodes),不能使用在non-sticky sessions模式,多个使用空格或逗号分开,配置某个节点为备份节点,当其他节点都不可用时才会存储到备份节点,适用于sticky模式(即一台tomcat,多台memcached)。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
-------------------------------------------------------------------------------------------------------------- 注意:这里实验环境是开启了两个memcached端口,如果开启一个memcached端口也可以的,比如只开启11211端口,则No-Stick模式的配置如下:
1 2 3 4 5 6 7 8 9 |
|
--------------------------------------------------------------------------------------------------------------
六、配置tomcat集群
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
七、启动tomcat集群
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
八、启动nginx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
|
九、测试session是否共享
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
本机绑定hosts进行访问测试: 110.110.115.118 www.wangshibo.com
测试步骤(服务器上iptables防火墙开通相应web端口) a)访问http://www.wangshibo.com/tomcat-session,显示出Session ID值,说明nginx反向代理tomcat运行正常。 b)按F5刷新多次,看看Session ID是否会变化。如果Session ID指一直不变,说明Session ID共享成功;反之,共享不成功! c)关闭其中一个tomcat实例,观察页面的Session ID是否有变化,如果Session ID一直不变,则表示Session ID已经共享到其他tomcat实例上)了。
响应速度: MSM在Session管理时,Tomcat中会保持本地Session,往Memcached中的同步是异步完成的,所以访问速度和普通模式没什么区别。 唯一有区别的是,tomcat实例关闭后的首次访问时,响应速度会变慢,但是持续一小段时间后续访问速度恢复正常。
-------------------------------------------------扩展------------------------------------------------------ 以上介绍了nginx+tomcat+memcached实现session共享集群的操作记录,下面再追加一些需要注意的东西:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
|
序列化tomcat配置中有关Manager各参数说明:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
|
再说下stick和non-stick的工作流程:
1 2 3 4 5 |
|
需要清除的是:
1 2 |
|