一、背景
上篇博客,使用微博社交登录谷粒商城后,将用户信息保存在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服务下的页面都能取到用户信息