分布式Session

分布式session不共享不同步的问题:

常规的,session:

我们可以理解session(办理的各种业务等)就是 保存在服务器内存中的一块数据(保存在map中),访问某一个网站,则客户端保存一个该网站发给其的cookie(银行卡)。

不同域名下,session无法共享:

如何解决session的无法共享问题?

1.session复制(同步)方案

缺点: 加入100个服务器,要完成session的共享,则需要各自都有100g的内存,来保存所有服务器的session数据,在大型服务项目中是不适用的。

2.客户端存储session

3.hash一致性

4.Session共享问题解决——统一存储

 将session存储在中间件中,例如 DB/Redis

通过springSession来解决不同域的session共享问题。

当在auth.gulimall.com下边登录之后,session保存用户名,然后用户名可以在不同域下都可以使用,就实现了session的共享问题。

 通俗来讲,例如: 在 auth.gulimall.com下的session,在 gulimall.com下也能用,在order.gulimall.com下也能用。

使用:

1.导入spring - session - data - redis的依赖

2.开启redis作为session的存储

 3.当登录完成之后,就会保存一个vo数据,该数据就是要保存的session对象,如果要将该数据保存到redis中,就需要先对该vo进行序列化从而保存到redis里边。

如下实现序列化:

理解:把需要共享session的服务 整合springSession依赖,然后将这些session保存到redis中,其它的服务都可以在redis里边把session信息拿出来并使用。例子就是登录服务的session保存到redis中,然后其它服务,如商品服务和主页服务都可以拿到,并一直保存登录状态。

问题: auth服务的session,无法实现子域的共享---TODO

要实现session的子域共享,就是把cookie的域名给放大到了父域中:

实现域名的放大效果,进行自定义的session配置:1.cookieSerializer,进行session的域名和cookie名的修改   2.实现session的json格式序列化机制,使用了Jackson方法序列化 3.将session的 config配置,因为每一个服务都需要,因此抽取出来放到common项目下。

进行了相关的自定义配置之后,需要在html页面也进行相关的修改:如果未登录,则返回空串,反之返回登录名称。

总结:

每一个微服务都要配置整合springSession(相关session保存在redis中——当然要在项目中进行redis和springSession的配置,  哪一个微服务需要这样的“登录Session”,就进行redis和springSession的配置,然后auth服务的“登录session”数据就可以保存在了redis中。

将“登录session”保存在redis之前,要进行自定义session的配置:1.设置cookie域名(将cookie域名放大到父域——实现session的子域共享)2.指定json序列化器对session进行序列化,便于微服务对于redis中session数据的存取。

至此,完成了session的子域共享问题。

springSession的核心原理(通过装饰者模式实现的):主要实现该功能的就是SessionRepositoryFilter,主要的核心逻辑如下:

 通过装饰者模式改变了默认的Filter,变成: SessionRepositoryFilter

当前端来一个请求,则会对该请求进行包装成一个 wrappedRequest的对象,然后调取wrappedRequest对象的.getSession()对session进行增删改查,所有对session的增删改查都是在redis中进行的。

如何保存session的呢? 是通过SessionRepository接口进行保存的(相当于Dao),通过接口的不同实现——可以使用 map保存session(则保存在redis中)——可以使用redis保存在redis中 ——如果引入JDBC相关的场景,还可以使用数据库保存session...

具体的:

1.完成springSession的依赖整合,在服务中使用@EnableRedisHttpSession注解,且该注解源码中添加了组件:RedisHttpSessionConfiguration ,里边添加了RedisOperationSessionRepository组件,是进行redis操作session的,在redis中进行session的增删改查。

RedisOperationSessionRepository中包含的方法有:

 2.RedisHttpSessionConfiguration 就是 SpringHttpSessionConfiguration,添加了 SessionRepositoryFilter组件,是session的存储过滤器,而该Filter就是spring里边默认的Filter,每一个请求过来都必须经过该Filter。

 3. 2中的SessionReposityFilter只包含一个有参构造器,且传入的是一个 SessionRepository,就是存储session的“仓库”,即 RedisOperationSessionRepository。

因此当Filter创建的时候,就自动从容器中获取到了SessionReposity,即 RedisOperationSessionRepository。

4. 通过SessionRepositoryFilter重写了Spring中原生的Filter方法,核心逻辑如下:

4.1 SessionRepositoryFilter中的 doFilterInternal()方法对原始的Http原始请求对象和响应对象都进行了包装,分别包装成: SessionRepositoryRequestWrapper和SessionRepositoryResponseWrapper类型的对象wrappedRequest和wrappedResponse,并使用包装后的对象进行后序业务逻辑。

对于原生的http请求中的session进行获取,是使用request.session()获取到, 由于 doFilterInternal()对原生的Http中的session进行了包装,因此使用包装后的对象 wrappedRequest.getSession()获取到包装后的session:

4.1.1.该session是从SessionRepository中获取到的。

 4.1.2.getSession()方法是重写了spring中的filter。

4.1.3 getSession()方法执行对session的获取。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时光、相遇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值