谷粒商城-高级-60 -商城业务-认证服务-分布式 Session

一、分布式session不共享不同步问题

Session共享问题-Session原理

file

session作用域:
file

问题:1、不能跨不同域名共享

Session共享问题-分布式下Session共享原理

file

Session共享问题解决-分布式下Session复制

file

Session共享问题解决-客户端存储

file

Session共享问题解决-hash一致性

file

Session共享问题解决-统一存储

file

Session共享问题解决-不同服务、子域session共享

file

二、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.propertiesapplication.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。

file

查看页面的cookie:
file

页面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 微服务,然后重启进行测试。

file

查看登录的Session:
file

可以看上边两张图,Session已经可以子域共享。

现在已经完全解决了Session子域共享问题,以及服务复制的session共享问题,无论复制多少份,Session统一存储,只要是 gulimall.com 下的域名,都可以访问的到。Session保存的时候也是Json 序列化后的数据。

为者常成,行者常至