Tomcat集群Session共享方法
HTTP协议属于无状态协议,当完成数据交换时,客户端与服务器端的连接就会关闭;但再次进行数据交换时,就需要建立新的连接。这意味着服务器无法从连接上跟踪会话,客户端与服务器端之间的联系是离散的、非连续性的。当用户在同一网站的多个页面转换时,服务器无法确定是否是同一用户。例如:用户登录淘宝后进入商品页购买商品,但是服务器不能将用户和商品对应起来。因此,需要通过Session会话跟踪技术来实现追踪定位,以保证用户在多次切换时,服务器可以保存该用户的相关信息,使用Session技术可以实现会话跟踪。
8.1.2案例前置知识点
1. Session概述
Session(中文为"会话")在计算机中被称之为"会话控制",是指一个终端用户与交互系统进行通信的时间间隔,通常是指从登录进入系统开始到注销退出系统结束之间的所用时间。Session所包括的客户端、服务器端以及不中断的操作时间,决定Session的不同。例如:用户A和服务器C建立连接时所处的Session与用户B和服务器C建立连接时所处的Session是两个完全不同的Session。
2. Session共享方案
对于Web应用集群的技术而言,最大的难点是在集群中多个节点之间保持数据的一致性,其中会话(Session)信息是这些数据中最重要的一部分。要实现这一点, 可以采用以下两种方式。
· 把所有Session数据放到一台服务器上或者数据库中,集群中的所有节点通过访问这台Session服务器来获取数据;
· 在集群中的所有节点间进行Session数据的同步拷贝,任何一个节点均保存了所有的Session数据。
在集群中可以通过以下几种方案实现Session共享:
(1) 请求精确定位
例如基于访问IP地址的Hash策略,即当前用户的请求都集中定位到一台服务器中,这样单台服务器就会保存用户的Session登录信息。但是如果宕机,则等同于单点故障,保存用户的Session登录信息就会丢失,会话不复制。
(2) Session复制共享
例如Tomcat自带Session共享,主要是指集群环境下多台应用服务器之间同步Session,使Session保持一致,对外则是保持透明。 如果其中一台服务器发生故障,根据负载均衡的原理,调度器会遍历寻找可用节点来分发请求。由于Session已同步,所以能够保证用户的Session信息不会丢失,也就是所谓的会话复制。
但是这个方案存在以下几个缺点:
· 必须在同一种中间件之间完成,例如Tomcat与Tomcat之间;
· Session复制带来的性能损失会快速增加,特别是当Session中保存了较大的对象,而且对象变化较快时,性能下降更加显著,会大量消耗系统性能。这种特性使得Web应用的水平扩展受到了限制。
· Session内容通过广播同步给成员,会造成网络流量瓶颈。
(3) 基于高速缓存数据库的Session共享
基于Memcached/Redis缓存的Session共享,即使用高速缓存数据库存取Session信息,应用服务器接受新请求将Session信息保存在高速缓存数据库中。应用服务器发生故障时,调度器会遍历寻找可用节点来分发请求,当应用服务器发现Session不在本机内存时,则去高速缓存数据库中查找。如果找到则复制到本机,这样实现Session共享和高可用。
3.Tomcat集群Session同步方案
Tomcat集群Session同步方案有以下几种方式:
(1)使用Tomcat自带的Cluster方式
多个Tomcat之间自动实时复制Session信息,配置起来比较简单。但这个方案的效率比较低。
(2)利用Nginx的基于访问IP地址的Hash路由策略
保证访问的IP地址始终被路由到同一个Tomcat上。每个请求按访问IP地址的Hash结果分配,这样每个访客固定访问一个后端服务器,可以解决Session的问题。
(3)利用Nginx插件实现Tomcat集群和Session同步
nginx-upstream-jvm-route是一个Nginx的扩展模块,用来实现基于Cookie的Session Sticky(会话粘滞)的功能。但是这个模块的补丁在Nginx1.4版本之后就没有再更新了,所以Nginx1.4之后版本跟该模块就不兼容。
(4)利用Memcached实现(MSM工具)
Memcached存储Session,并把多个Tomcat的Session集中管理,前端利用Nginx实现负载均衡和动静态资源分离,在兼顾系统水平扩展的同时又能保证较高的性能。其原理是通过MSM工具把Tomcat的Session序列化后保存到Memcached里面,从而实现Session共享。
MSM是一个高可用的Tomcat Session共享解决方案,除了可以从本机内存快速读取Session信息(仅针对黏性Session)外,还可使用Memcached存取Session,以实现高可用。传统Tomcat集群,会话复制随着结点数增多,扩展性成为瓶颈。MSM使用memcached完成统一管理Tomcat会话,避免Tomcat节点之间过多会话复制。
MSM利用Value(Tomcat 阀)对Request进行跟踪。Request请求到来时,从Memcached加载Session,Request请求结束时将Tomcat Session更新至Memcached,以达到Session共享DE 目的,支持Sticky和Non-Sticky模式:
· Sticky :会话粘连模式(黏性Session)。客户端在一台Tomcat实例上完成登录后,以后的请求均会根据IP直接绑定到该Tomcat实例。
· Non-Sticky:会话非粘连模式(非粘性Session)。客户端的请求是随机分发,多台Tomcat实例都会收到请求。
(5)利用Redis实现
使用Redis不仅仅是因为它可以将缓存的Session持久化,还因为它支持的单个对象比较大,而且数据类型丰富。也就是说Redis不仅仅可以用于缓存 Session,还可以做其他用途。Redis这种方式目前还不支持Tomcat8环境(现在网上插件不支持Tomcat8,想要支持Tomcat8的话,则需修改插件jar包的源代码)。
在Tomcat集群中,当一个节点出现故障,虽然有高可用集群来负责故障转移,但用户的Session信息如何保持呢?下面通过案例的方式具体介绍上述所说的第4种Tomcat集群Session同步方案:使用MSM(Memcached-Session-Manager)进行Session复制同步,即利用MSM+Memcached实现Session共享。