前言
在CS模式中,大部分业务场景都需要server维护用户的session。存储session的方式可分为两种,一是依赖container维护,一是采用cache或DB存储。container方式使用简单,但无法满足分布式要求。另一种方式,需要额外维护cache或DB,可满足分布式场景。正文以时序图的方式展示了维护session信息的基本流程,另外添加了单点登录、spring session。
依赖容器维护session
依赖容器维护session,无需开发者做额外的事情,但是只使用于单个服务器的情况,若多台服务器,则无法同步session,不满足分布式要求。
问题例如:应用部署到A、B两个服务器(或docker 容器),用户1在服务器A登录并维护session,下次请求分发到服务器B,发现session中不存在登录信息,导致用户返回登录页面。
请求处理的时序图如下
自行维护分布式Session
为满足分布式要求,需要使用可供多个服务器共享的数据存储,例如cache、db。基本流程与上图一致,差异仅在于获取和存储session的方式。container方式是直接使用request.getSession,而对于当前方式,就必须额外封装session操作,涉及从存储介质存取session数据。
请求处理的时序图如下,红色字体标注了差异点。
采用Spring Session
Spring session封装了分布式session的解决方案,让开发者仅需要提供配置,而不用关注如何存取session。使用简单,就像使用container方式一样,直接使用request.getSession皆可。对比上述方式,spring session必然更加优雅。
session的存取被封装于SessionRepositoryRequestWrapper和SessionRepositoryResponseWrapper。
请求处理的时序图如下
使用SSO登录
无论应用系统本身是否提供登录能力,都有可能存在使用第三方登录的情况。可以理解为Auth2的一种场景,对应的授权服务为用户登录,对应的资源服务为用户信息。避免每次请求都从资源服务器获取资源,就需应用维护分布式session。
请求处理的时序图如下
总结
由上文可见,可以简单的实现分布式session。所以实现不是重点,重点在于设计初期就要关注到分布式情况,做好选型。Spring Session提供了优雅的实现,而且使用简单。