美文网首页springbootJava webSpring Cloud
session一致性架构的四种设计实施方案

session一致性架构的四种设计实施方案

作者: 毛福林 | 来源:发表于2020-07-25 23:19 被阅读0次

    一、缘起

    1.1 什么是session?

    服务器为每个用户创建一个会话,存储用户的相关信息,以便多次请求能够定位到同一个上下文。
    Web开发中,web-server可以自动为同一个浏览器的访问用户自动创建session,提供数据存储功能。最常见的,会把用户的登录信息、用户信息存储在session中,以保持登录状态。

    1.2 什么是session一致性问题?

    只要用户不重启浏览器,每次http短连接请求,理论上服务端都能定位到session,保持会话

    1.3 通常情况下的应用部署

    • 单个应用
      当只有一台web-server提供服务时,每次http短连接请求,都能够正确路由到存储session的对应web-server(废话,因为只有一台),这种情况在实际中很少使用,只有少出的网站或者服务提供单个节点应用提供服务。


      单个应用
    • 多个应用,负载使用
      为了能够保证应用的高可用,采用“冗余+故障转移”的多台web-server来保证高可用时,每次http短连接请求就不一定能路由到正确的session了。


      多个应用,负载使用

    如上图所示,假设用户在第一个web-server上登录,登录信息的session都记录在第一台web-server上,nginx反向代理如果将请求路由到另一台web-server上,会出现找不到session的情况,而用户需要重新登录。

    在web-server高可用时,如何保证session路由的一致性,是今天将要讨论的问题。

    二、session同步法

    当存在多个应用时,一台应用机器上存在session,而另一台应用机器上不存在session,我们最先想到的是将session同步到另外一台机器上,如下图所示:

    session同步

    解决方案:多个web-server之间相互同步session,这样每个web-server之间都包含全部的session。

    那不同机器间的session需要我们自己应用去同步信息吗?
    答案是不用!web-server已经帮我们做好了一切

    如有我们自己编写相应的程序同步session需要较大的工作量,session是在应用的jvm里,我们自己有能力设计一个完美的程序吗?

    三、客户端存储法

    服务端存储所有用户的session,内存占用较大,可以将session存储到浏览器cookie中,每个客户端只要存储一个用户的数据,既节省了服务端内存,同时也避免了多个不同web-server内存可能存在不一致的问题


    cookies存储session

    四、反向代理hash一致性

    反向代理hash一致性,通常也是我们说的会话保持,将相同用户的请求分发到同一台web-server上,这样用户在web-server上登陆后,该用户的所有请求都会分发到这一台机器上,这样保证了session一致性

    反向代理hash一致性

    hash一致性,通常有两种做法:

    • 方案1:四层代理hash
      使用用户IP来进行hash,以保证同一个IP的请求落在同一个web-server上
    • 方案2:七层代理hash
      使用http协议中的某些业务属性进行hash,比如:用户id,能够更加灵活的实施hash策略,以保证相同用户的的请求落到同一个web-server上

    那对于这两种方案如何选择呢?

    个人推荐前者:让专业的软件做专业的事情,反向代理就负责转发,尽量不要引入应用层业务属性。

    五、后端统一存储

    session分散到不同的机器上,必然会存在session不一致的问题,那可不可以把session存放到相同的位置(db、缓存或者文件等),不同web-server访问相同的存储位置,也可以避免session不一致的问题

    后端统一存储

    对于 db、缓存或者文件等方式,推荐使用缓存的方式,比如redis等缓存数据库,用户每一次请求都需要访问session,使用db或者文件的访问速度都比较低,可以使用spring-session简化相关工作

    六、四种方法的比较

    对四种方案的优点和不足进行比较

    解决方案 优点 不足
    session同步方案 web-server支持的功能,应用程序不需要修改代码 1.session的同步需要数据传输,占内网带宽,有时延
    2.所有web-server都包含所有session数据,数据量受内存限制,无法水平扩展
    3.有更多web-server时要歇菜
    客户端存储方案 1.服务端不需要存储session,节省内存
    2.不需要考虑session一致性问题
    1.每次http请求都携带session,占外网带宽
    2.数据存储在端上,并在网络传输,存在泄漏、篡改、窃取等安全隐患
    3.session存储的数据大小受cookie限制
    反向代理hash一致性 1.只需要改nginx配置,不需要修改应用代码
    2.负载均衡,只要hash属性是均匀的,多台web-server的负载是均衡的
    3.可以支持web-server水平扩展(session同步法是不行的,受内存限制)
    1.如果web-server重启,一部分session会丢失,产生业务影响,例如部分用户重新登录
    2.如果web-server水平扩展,rehash后session重新分布,也会有一部分用户路由不到正确的session
    3.如果有某台web-server上的用户频繁请求,会出现负载不均衡的情况
    后端统一存储 1.不存在安全隐患
    2.可以水平扩展,数据库/缓存水平切分即可
    3.web-server重启或者扩容都不会有session丢失
    1.增加了一次网络调用,并且需要修改应用代码
    2.可能会增加额外的设备,比如redis服务器等

    七、总结

    保证session一致性的架构设计常见方法:

    • session同步法:多台web-server相互同步数据
    • 客户端存储法:一个用户只存储自己的数据
    • 反向代理hash一致性:四层hash和七层hash都可以做,保证一个用户的请求落在一台web-server上
    • 后端统一存储:web-server重启和扩容,session也不会丢失

    对于方案3和方案4,个人建议推荐后者:
    •web层、service层无状态是大规模分布式系统设计原则之一,session属于状态,不宜放在web层
    •让专业的软件做专业的事情,web-server存session?还是让cache去做这样的事情吧

    八、参考文献

    1.架构师之路-session一致性架构设计实践

    相关文章

      网友评论

        本文标题:session一致性架构的四种设计实施方案

        本文链接:https://www.haomeiwen.com/subject/ekhvlktx.html