一、session共享

问题:各个模块运行在各自的tomcat中 session不互通
未命名图片.png

1. 会话控制回顾

1) Cookie的工作机制

服务器端返回Cookie信息给浏览器

  • java代码:
    • Cookie cookie = new Cookie(key, value);
    • response.setCookie(cookie对象);
  • Http响应消息头:Set-Cookie:Cookie的名字=Cookie的值
  • 浏览器接收到服务器端返回的Cookie,以后的每一次请求都会把Cookie带上。
  • Http请求头:Cookie: Cookie的名字=Cookie的值

2) Session的工作机制

获取session对象:request.getSession();

  • 检查当前请求是否携带了JSESSIONID这个cookie
    • 带了:根据这个JSESSIONID在服务器端查找对应的Session对象
      • 能找到:就报找到的session对象返回
      • 没找到:新建Session对象返回,同时返回JSESSIONID的cookie
    • 没带:新建Session对象返回,同时返回JSESSIONID的Cookie

      2.Session共享

      在分布式和集群环境下,每个具体模块运行在单独的 Tomcat 上,而 Session 是被不同 Tomcat 所“区隔”的,所以不能互通,会导致程序运行时,用户会话数据发生错误。有的 服务器上有,有的服务器上没有

3. 解决方案探讨

1) 方案一:Session同步

未命名图片.png
问题 1:造成 Session 在各个服务器上“同量”保存。TomcatA 保存了 1G 的 Session 数据,TomcatB 也需要保存 1G 的 Session 数据。数据量太大的会导 致 Tomcat 性能下降。
问题 2:数据同步对性能有一定影响。

2) 方案二:将Session数据存储到Cookie中

  • 做法:
    • 所有会话数据在浏览器端使用 Cookie 保存,服务器端不存储任何 会话数据。
  • 好处:
    • 服务器端大大减轻了数据存储的压力。不会有 Session 不一致问题
  • 缺点:

    • Cookie 能够存储的数据非常有限。一般是 4KB。不能存储丰富的数据。
    • Cookie 数据在浏览器端存储,很大程度上不受服务器端控制,如果浏 览器端清理 Cookie,相关数据会丢失。

      3) 方案三:反向代理hash一致性

      未命名图片.png
  • 问题 1:具体一个浏览器,专门访问某一个具体服务器,如果服务器宕机, 会丢失数据。存在单点故障风险。

  • 问题 2:仅仅适用于集群范围内,超出集群范围,负载均衡服务器无效。

4) 方案四:后端统一存储Session数据[使用 Spring Session]

  • 后端存储 Session 数据时,一般需要使用 Redis 这样的内存数据库,而一 般不采用 MySQL 这样的关系型数据库。
  • 原因如下:
    • Session 数据存取比较频繁。内存访问速度快。
    • Session 有过期时间,Redis 这样的内存数据库能够比较方便实现过期释放。

未命名图片.png

  • 优点
    • 访问速度比较快。虽然需要经过网络访问,但是现在硬件条件已经能够达 到网络访问比硬盘访问还要快。
      • 硬盘访问速度:200M/s
      • 网络访问速度:1G/s
    • Redis 可以配置主从复制集群,不担心单点故障