一口气说出 4 种分布式一致性 Session 实现方式,面试杠杠的~

下面小黑哥将会以跟组长对话的形式,讲解分布式一致性 Session 解决办法。

Session 复制


组长:

如果此时 Tomcat1 Session 存在用户信息,而 Tomcat2 上没有存在。

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

架构图如下:

一致性 Session-Session 复制

Tomcat 的 Session 复制的配置,网上有比较多的例子,这里小黑就不再贴了,感兴趣的同学可以自行搜索一下。

小黑:

对的,这种方式挺好啊。Tomcat 就支持这种方式,我们只需要修改 Tomcat 配置就好,我们应用代码都不用修改了。

组长:

说的对,但是这种方式还是有很多缺点。

第一,Session 复制传输需要占用内网带宽。

第二,我们的例子就只有两台机器,这个复制性能还可以。但是假设我们有 N 台机器,那么每次复制都要复制给 N-1 台机器,如果机器很多,可能会形成网络风暴,复制性能也会呈指数级下降。

第三, Tomcat 需要保存所有的 Session 数据,这个方案的 Session 存储在内存中,容易受到机器的总内存的限制。我们没办法通过加机器的方式水平扩展,我们能做的方式就是加大机器内存。但是机器内存越大,价格真的很贵!!!

所以不推荐使用这种方案。

Session 前端存储


小黑:

恩,这个方案确实有点不靠谱~

哎,有了!我们的 Session 里面其实就是存了用户的信息,那我现在不存 Tomcat Session 里,我把信息拿出来,存到浏览器的 Cookie 中。

这样,每个用户浏览器存储自己的 Cookie 信息,服务端就不需要存储,这就解决了 Session 复制方案的缺陷了。

接下来用户每次请求都把这个 Cookie 给我发过来,我判断 Cookie 里面用户信息不就好了。

架构图如下:

一致性 Session-Session 前端存储

组长,欣赏看了一下我:

对,你这个方案确实可行。

不过么,如果用这种方案,首先你要想好加密方案。

用户信息可是我们的敏感数据,不能让别人轻易的窃取或者篡改数据了。

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

另外,我们存储的数据大小,容易受到 Cookie 限制。

所以这种还是不怎么常用,不过也是一种思路。

我比较推荐下面两种方案。

Session 粘滞(Sticky Sessions)


组长:

刚才应该看到了,我只是对 Nginx 的配置做了一些修改,然后这个问题就解决了吧。

其实这是因为我修改 Nginx 默认的负载均衡策略,使用 IP Hash 的方式。

Nginx 会使用请求者的 IP 来做 Hash,然后分发到一台机器上,这样可以保证同一 IP 的请求都落在同一台 Tomcat 上。

架构图如下:

Session 粘滞-IP Hash

上面这种方式我们使用 Nginx 四层负载均衡方式,其实 Nginx 还可以做到七层负载均衡方式,也就是使用 Http 协议中的一些业务属性来做 Hash,常见的有 userId,_loginId_等等。

架构图如下:

一致性 Session-Session 粘滞-七层

小黑:

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

只要请求来源 IP 足够的随机,那么 IP HASH 之后两台应用上的流量将会足够随机。

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

组长:

你说的这几点都很正确!

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

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

最后,如果我们临时再加机器,修改完 Nginx 配置,重新启动之后,Nginx 将会重新计算 Hash 分发请求。

这种情况就会导致有一部分用户重新路由到一台新机器上,由于没有 Session,又需要重新登录了。

不过么,Tomcat 重启或者新加机器次数不会很多,所以这个问题也不大,用户体验稍差点。

今天的我们这个问题解决方案就先使用这个。

不过后面我们还是改成下面这种方式。

后端集中存储


组长:

上面几种的方式我们都是把 Session 存储在应用内存上,应用机器只要重启,Session 就会丢失。

为了这个解决这个问题,我们将 Session 单独存起来,保存到 Redis 或者 MySQL 中。

不过由于 Session 需要过期失效的特性,不需要持久化保存,所以这里我建议使用 Redis 来保存。

这样架构就变成下方这样的:

一致性 Session-Session 后端存储

我们使用这种方案,上没有 Session 丢失的风险,当然前提是 Redis 不能宕机。

另外后期如果应用可以直接水平扩展。

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

小黑:

对对,这种方式好~

组长:

你不要高兴的太早,我们使用这个方案需要付出一定的代价的。

首先我们每次请求都需要调用一次 Redis ,这就增加一次网络的开销。

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

所以说,这个方案有利也有弊,当然对于我们的场景来说,利大于弊。

小黑:

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

总结

我们总是喜欢瞻仰大厂的大神们,但实际上大神也不过凡人,与菜鸟程序员相比,也就多花了几分心思,如果你再不努力,差距也只会越来越大。

面试题多多少少对于你接下来所要做的事肯定有点帮助,但我更希望你能透过面试题去总结自己的不足,以提高自己核心技术竞争力。每一次面试经历都是对你技术的扫盲,面试后的复盘总结效果是极好的!

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
总结

我们总是喜欢瞻仰大厂的大神们,但实际上大神也不过凡人,与菜鸟程序员相比,也就多花了几分心思,如果你再不努力,差距也只会越来越大。

面试题多多少少对于你接下来所要做的事肯定有点帮助,但我更希望你能透过面试题去总结自己的不足,以提高自己核心技术竞争力。每一次面试经历都是对你技术的扫盲,面试后的复盘总结效果是极好的!

[外链图片转存中…(img-E7UW8Qli-1713561160023)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 23
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值