谷粒商城-高级-60 -商城业务-认证服务-分布式 Session
一、分布式session不共享不同步问题
Session共享问题-Session原理
session作用域:
问题:1、不能跨不同域名共享
Session共享问题-分布式下Session共享原理
Session共享问题解决-分布式下Session复制
Session共享问题解决-客户端存储
Session共享问题解决-hash一致性
Session共享问题解决-统一存储
Session共享问题解决-不同服务、子域session共享
二、SpringSession
整合 redis 作为session存储,Spring Session 已经为我们做好了,只需要配置即可,不用修改代码。
Spring session官方文档
1、SpringSession整合
1、导入依赖
将 SpringSession 引入到gulimall-auth-servet
, gulimall-product
, gulimall-member
涉及需要登录的微服务。gulimall-auth-server/pom.xml
<!-- 整合SpringSession完成session共享问题 -->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
2、修改配置属性application.properties
或 application.yml
项目文件:gulimall-auth-server/src/main/resources/application.yml
# spring.session.store-type=redis # Session store type.
spring:
# 配置nacos注册中心
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
application:
name: gulimall-auth-server
thymeleaf:
cache: false # 测试期间关掉缓存
redis:
host: 192.168.10.10
prot: 6379
session:
store-type: redis # Session store type,SpringSession整合
server:
port: 20000
servlet:
session:
timeout: 30m # Session timeout,SpringSession整合
Servlet 容器初始化原理:
我们的Spring Boot Configuration创建了一个名为springSessionRepositoryFilter的Spring bean,它实现了Filter。
springSessionRepositoryFilter bean负责用Spring Session支持的自定义实现替换HttpSession。
为了使我们的过滤器发挥作用,Spring需要加载我们的Config类。最后,我们需要确保我们的servlet容器(即Tomcat)对每个请求都使用springSessionRepositoryFilter。幸运的是,Spring Boot为我们完成了这两个步骤。
3、启动类添加开启注释
gulimall-auth-server/xxx/auth/GulimallAuthServerApplication.java
package com.atguigu.gulimall.auth;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
@EnableRedisHttpSession // 整合redis作为session存储
@EnableFeignClients(basePackages = "com.atguigu.gulimall.auth.feign") // 开启远程调用
@EnableDiscoveryClient // 开启注册发现功能
@SpringBootApplication
public class GulimallAuthServerApplication {
public static void main(String[] args) {
SpringApplication.run(GulimallAuthServerApplication.class, args);
}
}
4、测试
重启服务,然后登陆页面,可以看到Redis里边已经保存了Session。
查看页面的cookie:
页面cookie保存的sessionId作用域太小了,其他子域名不能共用。
在 gulimall-auth-server
服务中存储session, 需要在gulimall-product
微服务中获取,那么gulimall-product
也需要引用开启 Spring Session。
2、子域共享Session及JSon序列化存储
gulimall-auth-server/xxx/auth/config/GulimallSessionConfig.java
package com.atguigu.gulimall.auth.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.session.web.http.CookieSerializer;
import org.springframework.session.web.http.DefaultCookieSerializer;
/**
* @author: kaiyi
* @create: 2020-09-09 17:05
*/
@Configuration
public class GulimallSessionConfig {
/**
* 子域名共享设置及session名自定义
* @return
*/
@Bean
public CookieSerializer cookieSerializer(){
DefaultCookieSerializer defaultCookieSerializer = new DefaultCookieSerializer();
defaultCookieSerializer.setDomainName("gulimall.com"); // 设置作用域,这里是父域名,子域名也可以共享
defaultCookieSerializer.setCookieName("GULISESSION"); // 设置session名
return defaultCookieSerializer;
}
/**
* 默认序列化转为JSON存储
*
* @return
*/
@Bean
public RedisSerializer<Object> springSessionDefaultRedisSerializer(){
return new GenericJackson2JsonRedisSerializer();
}
}
将上边的配置文件也同样放到 gulimall-product
微服务,然后重启进行测试。
查看登录的Session:
可以看上边两张图,Session已经可以子域共享。
现在已经完全解决了Session子域共享问题,以及服务复制的session共享问题,无论复制多少份,Session统一存储,只要是
gulimall.com
下的域名,都可以访问的到。Session保存的时候也是Json 序列化后的数据。
为者常成,行者常至
自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)