分布式一致性Session的实现方式

声明:本文参考自微信公众号来:Java极客技术

1.问题来源:

  后端系统有两台服务器,使用Nginx做反向代理,而且后台系统的一些网页需要登录授权之后才能进行相应操作。架构如下:

  

   这样的架构导致一个问题就是,登录过后没一会又要重新登录。

2.问题原因:

  我们登录之后将会把用户登录信息放在 Session 中,用户每次操作首先先校验Session 是否存在用户信息,如果不存在将会强制让用户先去登录。我们部署了两台系统,由于 Nginx 使用默认负载均衡策略(轮询),请求将会按照时间顺序逐一分发到后端应用上。也就是说刚开始我们在 Tomcat1 登录之后,用户信息放在 Tomcat1 的 Session 里。过了一会,请求又被 Nginx 分发到了 Tomcat2 上,这时 Tomcat2 上 Session 里还没有用户信息,于是又要登录。另外由于我们系统采用单点登录的方式,Tomcat2 登录之后会将 Tomcat1 登录信息失效,于是乎等到 Nginx 再把流量分发到 Tomcat1 时,Session 中用户登录信息已经失效,又要重新登录。

3.解决方法:分布式一致性Session

  分布式一致性 Session 有四种解决办法:

  

4.Session复制:

  如果我们将 Tomcat1 的 Session 复制到 Tomcat2 上,后面 Nginx 将请求转发到 Tomcat2 上,由于 Tomcat2 存在 Session ,这时就不需要再重新登录了。

  架构图如下:

  

   Tomcat的session复制方式,主要是在配置文件中增加jvmRoute="node1"配置;

  Session复制的好处:我们只需要修改Tomcat配置就好,不用修改应用代码;

  Session复制的缺点:

    1.Session 复制传输需要占用内网带宽。

    2.机器少还好,如果机器比较多的话,可能会形成网络风暴,复制性能也会呈指数级下降。

    3.Tomcat 需要保存所有的 Session 数据,这个方案的 Session 存储在内存中,容易受到机器的总内存的限制。

5.Session前端存储:

  每个用户浏览器存储自己的 Cookie 信息,接下来用户每次请求都把这个 Cookie 给传给后端,之在后端判断 Cookie 里面用户信息。

  架构图如下:

  

   前端Session复制的缺点:

    1.用户信息是敏感数据,如果用这种方案,首先要想好加密方案。

    2.这个方案每次请求都要携带 Cookie 传输,这会占用外网的带宽,如果 Cookie过大,会增大网络的开销。

    3.存储的数据大小,容易受到 Cookie 限制。

6.Session粘滞(Sticky Sessions)

  修改 Nginx 默认的负载均衡策略,使用 IP Hash 的方式。Nginx 会使用请求者的 IP 来做 Hash,然后分发到一台机器上,这样可以保证同一 IP 的请求都落在同一台 Tomcat 上。

  架构图如下:

  

   Session粘滞的优点:

    1.这种方案看起来挺简单的,我们只需要修改 Nginx 配置就好了,应用端配置无需改动。

    2.后面如果两台机器扛不住,我们还可以水平扩展,再加机器,只要修改 Nginx 配置即可。

  Session粘滞的缺点:

    1.一个公司的出口IP都是一个,那么一个公司的所有请求只会到一台机器上,那我们这种情况等于又变成单点了。

    2.如果 Tomcat 重启,Session 由于是放置在内存内存中,这一部分的 Session 将会丢失,这就导致这部分用户将会重新登录。

    3.如果我们临时再加机器,修改完 Nginx 配置,重新启动之后,Nginx 将会重新计算 Hash 分发请求,会导致有一部分用户重新路由到一台新机器上,由于没有 Session,又需要重新登录了。

7.后端集中存储

  上面几种的方式我们都是把 Session 存储在应用内存上,应用机器只要重启,Session 就会丢失。为了这个解决这个问题,我们将 Session 单独存起来,保存到 Redis 或者 MySQL 中。不过由于 Session 需要过期失效的特性,不需要持久化保存,所以这里建议使用 Redis 来保存。

  架构图如下:

  

   后端存储的优点:

    1.使用这种方案,Redis 不能宕机情况下,没有 Session 丢失的风险 。

    2.后期方便水平扩展,如果后面应用的请求量很大,一台 Redis 扛不住了,那我们可以其实可以做集群扩展,根据缓存 Key 做路由。

  后端存储的缺点:

    1.每次请求都需要调用一次 Redis ,这就增加一次网络的开销。

    2.引入 Redis,我们需要对相应的代码做出修改,这样复杂度就变高。

8.总结:

  布式一致性 Session 主流解决方案有四种:

    1.Session 复制:利用 Tomcat 等 Web 容器同步复制

    2.Session 前端存储:利用用户浏览器中 Cookie 保存 Session 信息

    3.Session  粘滞方案:利用 Nginx 可以做四层 Hash 或七层 Hash 的特性,保证用户的请求都落在同一台机器上

    4.Session 后端集中存储方案:利用 Redis 集中存储 Session,Web 应用重启或扩容,Session 也无需丢失。

  

posted @   WK_BlogYard  阅读(203)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示