分布式session的解决方法
一、背景
上篇博客,使用微博社交登录谷粒商城后,将用户信息保存在session中,此时进入到谷粒商城的任何页面都需要能够取到用户信息,
谷粒商城首页(gulimall.com/index.html), 首页搜索商品后搜索到的商品列表(search.gulimall.com/index.html)
二、session的原理
三、分布式服务下session存在的问题
1、分布式服务下的session共享问题
微服务架构下,每个服务存在 多个示例,因为session的默认实现是内存中的map,所以不同实例的session是不能共享的,
若第一次请求路由到会员1服务,并在session中存放了东西,第二次请求路由到会员2服务,此时,会员2服务是不能取到session中的内筒的
分布式session解决方案
①、session复制
②、客户端cookie存储原本存在session中的内筒
③、hash一致性
④、统一存储
一般情况下使用该方法解决分布式服务中,多个实例 的session共享问题
2、不同服务,子域session共享
例如:上述阐述的背景中,你通过auth服务进行登录,并使用session将用户信息保存在其中,此时auth服务会在浏览器中保存一个
cookie,cookie中携带jsessionid,但是这个cookie只会在浏览器访问auth.gulimall.com中携带,访问其他域名的服务(例如gulimall.com,search.gulimall.com)
则不会携带该cookie,没有jessionid,则自然不能拿到该用户存在session中的内容,不能共享
四、使用SpringSession来解决上述提到的两个问题
使用 SpringSession 解决分布式服务下session的共享问题 + 子域间session共享问题
①、引入SpringSession的依赖
<!-- redis作为session的共享存储区域 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- 整合SpringSession完成Session共享问题 --> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> </dependency>
②、配置文件上 配置redis作为session的存储类型
spring.session.store-type=redis
server.servlet.session.timeout=30m
③、主启动类上开启SpringSession功能
@EnableRedisHttpSession //整合redis作为session存储
④、增加配置类解决解决子域的session共享问题,以及使用JSON的序列化,序列化对象到redis中
@Configuration public class GulimallSessionConfig { /** * @Description: 指定cookie的作用域,访问所有的子域和父域的域名时,都能携带这个cookie * @author houChen * @date 2021/12/31 7:39 */ @Bean public CookieSerializer cookieSerializer(){ DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer(); cookieSerializer.setDomainName("gulimall.com"); cookieSerializer.setCookieName("GULISESSION"); return cookieSerializer; } /** * @Description: redis的序列化器 * @author houChen * @date 2021/12/31 7:41 */ @Bean public RedisSerializer<Object> SpringSessionDefaultRedisSerializer(){ return new GenericFastJsonRedisSerializer(); } }
⑥、正常在代码中使用session 即可
session.setAttribute("loginUser", data);
demo: https://gitee.com/houchen1996/gulimall 下的gulimall-auth-server
实现微博社交登录,用到了SpringSession,当微博登录后(auth.gulimall.com),gulimall.com item.gulimall.com服务下的页面都能取
到用户信息