集群系统下的 Session 会话统一方案详解及 MSM 工作原理

1、前言

对于web应用集群的技术实现而言,最大的难点就是:如何能在集群中的多个节点之间保持数据的一致性,会话(Session)信息是这些数据中最重要的一块。要实现这一点, 大体上有两种方式:

  • 一种是把所有Session数据放到一台服务器上或者数据库中,集群中的所有节点通过访问这台Session服务器来获取数据
  • 另一种就是在集群中的所有节点间进行Session数据的同步拷贝,任何一个节点均保存了所有的Session数据

1.1 在集群系统下实现 session 会话统一的方案

1.1.1 请求请准定位

  • Session Sticky 例如基于访问ip的hash策略,即当前用户的请求都集中定位到一台服务器中,这样单台服务器保存了用户的session登录信息,如果宕机,则等同于单点部署,会丢失,会话不复制。

1.1.2 Session 复制共享

  • Session Replication 如 Tomcat 自带session共享,主要是指集群环境下,多台应用服务器之间同步session,使session保持一致,对外透明。 如果其中一台服务器发生故障,根据负载均衡的原理,调度器会遍历寻找可用节点,分发请求,由于session已同步,故能保证用户的session信息不会丢失,会话复制,。
  • 此方案的不足之处 1、必须在同一种中间件之间完成(如:tomcat-tomcat之间);2、
    session 复制带来的性能损失会快速增加,特别是当session中保存了较大的对象,而且对象变化较快时, 性能下降更加显著,会消耗系统性能。这种特性使得web应用的水平扩展受到了限制;3、Session内容通过广播同步给成员,会造成网络流量瓶颈,即便是内网瓶颈,在大并发下表现并不好。

1.1.3 基于 cache DB 缓存的 session 共享

  • 基于memcache/redis 缓存的 Session 共享.即使用 cacheDB 存取 session 信息,应用服务器接受新请求将 Session 信息保存在 cache DB 中,当应用服务器发生故障时,调度器会遍历寻找可用节点,分发请求,当应用服务器发现 Session 不在本机内存时,则去cacheDB 中查找,如果找到则复制到本机,这样实现 Session 共享和高可用

1.2 Tomcat 集群 Session 同步方案

  1. 使用 Tomcat 自带的 cluster 方式,多个 Tomcat 间自动实时复制 Session 信息,配置起来很简单。但这个方案的效率比较低,在大并发下表现并不好
  2. 利用 Nginx 的基于访问 ip 的 hash 路由策略,保证访问的ip始终被路由到同一个 Tomcat 上,这个配置更简单。每个请求按访问 ip 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决 Session(并不是共享session解决)的问题,并且如果应用是某一个局域网大量用户同时登录,这样负载均衡就没什么作用了
  3. 利用 Memcached 实现(MSM工具)。Memcached 存储 session,并把多个 Tomcat 的Session 集中管理,前端在利用 Nginx 负载均衡和动静态资源分离,在兼顾系统水平扩展的同时又能保证较高的性能。即通过 MSM 工具把 Tomcat 的 Session 序列化后保存到 Memcached 里面,从而实现 Session 共享
  4. 利用 Redis 实现。使用 Redis 不仅仅可以将缓存的 Session 持久化,还因为它支持的单个对象比较大,而且数据类型丰富,不只是缓存 Session,还可以做其他用途,可以一举几得。Redis 这种方式目前还不支持 Tomcat8 环境
  5. 利用 Filter 方法实现。这种方法比较推荐,因为它的服务器使用范围比较多,不仅限于Tomcat ,而且实现的原理比较简单容易控制
  6. 利用 Terracotta 服务器共享 Session。这种方式配置比较复杂。

2、MSM 介绍

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 实例均会收到请求

2.1 cookie 工作机制

假如我们创建了一个名字为 login 的 Cookie 来包含访问者的信息,创建 Cookie 时,服务器端的 Header 如下面所示,这里假设访问者的注册名是 “tang” ,同时还对所创建的 Cookie 的属性如 path 、 domain 、expires 等进行了指定。

Set-Cookie:login=tang;path=/;domain=msn.com;
expires=Monday,01-Mar-99 00:00:01 GMT

上面这个 Header 会自动在浏览器端计算机的 Cookie 文件中添加一条记录。浏览器将变量名为 “login” 的 Cookie 赋值为“tang”。

注意,在实际传递过程中这个 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 过期为止。

2.2 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)。

2.3 session 共享

为什么要持久化 Session(共享 Session)?

因为:在客户端每个用户的 Session 对象存在 Servlet 容器中,如果 Tomcat 服务器重启或者宕机的话,那么该 Session 就会丢失,而客户端的操作会由于 Session 丢失而造成数据丢失;如果当前用户访问量巨大,每个用户的 Session 里存放大量数据的话,那么就很占用服务器大量的内存,进而致使服务器性能受到影响。

可以使用数据库持久化 Session,分为物理数据库和内存数据库。物理数据库备份Session,由于其性能原因,不推荐;内存数据库可以使用 Redis 和 Memcached。

2.4 MSM 工作原理

2.4.1 Sticky Session(黏性) 模式下的工作原理

Tomcat 本地 Session 为主 Session,Memcached 中的 Session 为备 Session。Request请求到来时, 从 Memcached 加载备 Session到 Tomcat (仅当 Tomcat jvmRoute发生变化时, 否则直接取 Tomcat Session);Request 请求结束时,将 Tomcat Session 更新至Memcached,以达到主备同步之目的。

安装在 Tomcat 上的 MSM 使用本机内存保存 Session,当一个请求执行完毕之后,如果对应的 Session 在本地不存在(即某用户的第一次请求),则将该 Session 复制一份至 Memcached ;当该Session的下一个请求到达时,会使用 Tomcat 的本地 Session,请求处理结束之后,Session的变化会同步更新到 Memcached,保证数据一致。

当集群中的一个 Tomcat 挂掉,下一次请求会被路由到其他Tomcat 上。负责处理此请求的 Tomcat 并不清楚Session信息,于是从 Memcached 查找该Session,更新该 Session 并将其保存至本机。此次请求结束,Session 被修改,送回Memcached 备份。

2.4.2 Non-sticky Session (非黏性)模式下的工作原理

Tomcat 本地 Session 为中转 Session,Memcached1 为主 Session, Memcached2 为备Session 。Request 请求到来时,从 Memcached2 加载备 Session 到 Tomcat,(当容器中还是没有 Session 则从 Memcached1 加载主 Session 到 Tomcat,这种情况是只有一个Memcached 节点,或者有 Memcached1 出错时),Request 请求结束时,将Tomcat Session 更新至主 Memcached1 和备 memcached2,并且清除 Tomcat Session 。以达到主备同步之目的。

多台Tomcat 集群时 需要选择 Non-Sticky 模式,即 sticky=“false” 。

3、参考文档链接

Tomcat通过Memcached实现session共享的完整部署记录

发布了158 篇原创文章 · 获赞 7 · 访问量 9749

猜你喜欢

转载自blog.csdn.net/weixin_44983653/article/details/103025020