状态保持的解决方案:详解分布式session

分布式session解决了什么问题?

随着容器化、云原生等的流行,DevOps团队也在不断鼓吹「以无状态为荣,以有状态为耻」。因为有状态的服务难以部署、难以扩展。

「状态」其实对用户体验而言是个好东西。保存用户的登录状态;浏览器异常关闭再次打开恢复用户之前的窗口状态;记录用户的偏好状态……于是勤于动脑的软件工程师们就想了:怎么既能拥有无状态化的扩展性,又拥有有状态时的良好用户体验呢?

答案就是分布式session。它更像是一种业务问题的解决方案

常用的分布式session解决方案

2007年至今-客户端存储

使用cookie

客户端存储是指直接将信息存储在cookie中。客户端通过http协议和服务器进行cookie交互,通常用来存储一些不敏感信息。它有很明显的缺点:

  • 数据存储在客户端,存在安全隐患

  • cookie存储大小、类型存在限制

  • 数据存储在cookie中,如果一次请求cookie过大,会给网络增加更大的开销

虽然这种方式有缺点,但是可以通过合理的控制减少副作用。所以我从07年参加工作时就在用这种方法,现在的系统也还在用。JWT就是其中一个典型,它长度小,信息做了加密,一般仍然是存储在cookie中解决单点登录问题。

JWT

JWT:Json Web Token,是基于Json的一个公开规范,这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息,他的两大使用场景是:认证和数据交换。

由服务端根据规范生成一个令牌(token),并且发放给客户端。此时客户端请求服务端的时候就可以携带者令牌,以令牌来证明自己的身份信息。

2009年开始我进行互联网领域,有几年和JWT打交道比较多。因为那时候,你想不想做全栈都是全栈,因为前后端不分离,做什么都是一坨。也就是近7年更专注做后端了。那时候记忆比较深的就是cookie里存着一段用很简易的加密做的字符串,用户名信息等关键信息之间用一个下划线隔开,还有一个带有效期的随机数字段,数据库里也存一份。匹配上了就认证成功用户登录状态session有效。

没听说谁家用过-session会话保持(黏滞会话)

会话保持是利用负载均衡的原地址Hash算法实现,负载均衡服务器总是将来源于同一IP的请求分发到同一台服务器上,,也可以根据cookie信息将同一个用户的请求每次都分发到同一台服务器上,不过这时的负载均衡服务器必须工作在HTTP协议层上。这种会话保持也叫黏滞会话(Sticky Sessions)。

这种方案虽然保证了每个用户都能准确的拿到自己的session,而且大量用户访问也不怕,但是这种会话保持不符合系统高可用的需求。这种方案有着致命的缺陷:一旦某台服务器发生宕机,则该服务器上的所有session信息就会不存在,用户请求就会切换到其他服务器,而其他服务器因为没有其对应的session信息导致无法完成相关业务。所以这种方法基本上不会被采纳。

2010年-服务器session复制

原理:任何一个服务器上的session发生改变(增删改),该节点会把这个 session的所有内容序列化,然后广播给所有其它节点,以此来保证Session同步。

优点:可容错,各个服务器间session能够实时响应。

缺点:会对网络负荷造成一定压力,如果session量大的话可能会造成网络堵塞,拖慢服务器性能。

我在10年的时候,在公司举行了一个讲座上听人家说过,自己没用过。对这个印象也不深:因为当初那个讲座是leader非要我去的,我坐在第一排,然后……睡着了。因为确实也比较无聊,互联网场景下很少有场景需要这样用。

2011年至今-状态集中存储

2011年,我经过两年的努力,终于在公司里,从一个写业务代码的开发,转成了一个中间件开发者。当时让我一个负责约等于是开发一个zookeeper吧。那时候zookeeper还没有普及,当时很多公司都在开发自己的中间件。

一个下午,我在测试环境发布了一个不成熟的版本,自己的服务挂了。一屋子的人都站了起来。因为我这边挂了,其他人的模块都跑不起来。好像有点跑题了,总之,从那之后,市面上开始出现了各种集中式的状态存储:zookeeper、memcache缓存,其实数据库也是一种。

本质上,对于Java开发者来说,session存储的东西只是从JVM内移到了JVM外。而这种场景下会话保持就相当于是按照hash值进行路由,session复制就相当于集中存储的副本了。也就是说session会话保持和服务器session复制实际上是现代状态集中存储的基础原理,只不过是管理方由业务开发人员转移到中间件管理端,降低了对业务开发人员的开发管理成本。

session使用注意事项

15年时,我们线上发生过一个问题:我正在验证一个线上功能。为了更好的验证,用chrome浏览器登录一个用户,用IE登录另外一个用户。这时候,我刷新了IE页面,结果IE用户突然自己变成了chrome的用户。以多年做技术的敏锐嗅觉,我意识到在组件层面出了问题。于是将这个问题立即上报了技术经理。技术经理听了我的报告,联系了负责CDN的团队。经过他们的排查,CDN的静态缓存策略设置的有问题,他们立即更新了策略解决了问题。(现在想来一身冷汗啊,随随便便就操作生产了?)

Guess you like

Origin blog.csdn.net/m0_62051288/article/details/121874949