Spring Session + Redis 实现Session共享

1. 前言

Spring Session

关于session共享的方式有多种

  1. 通过nginx的ip_hash,根据ip将请求分配到对应的服务器

  2. 基于cookie存储

  3. 服务器内置的session复制域

  4. 基于关系型数据库存储(Spring Session JDBC

  5. 基于nosql(MemCache、MongoDB(Spring Session MongoDB)、Redis (Spring Session Data Redis)都可以)

常用的就是1和5,下面研究第5种方式,基于nosql(Redis)存储session。

其实实现原理也比较简单,在所有的请求之前配置一过滤器,在请求之前操作session,其实spring-session中真正起作用的session过滤器是:SessionRepositoryFilterspring-session集成了redis与mongodb等nosql。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述


有兴趣的可以debug跟进源码看看

2. 代码实现

2.1 添加maven依赖

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.session</groupId>
	<artifactId>spring-session-data-redis</artifactId>
</dependency>

完整pom.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>top.theonly.spring.session</groupId>
    <artifactId>spring-boot-session-redis-test</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.6.RELEASE</version>
        <relativePath/>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-data-redis</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

2.2 SpringBoot启动类

@SpringBootApplication
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 3600) //增加redis session缓存支持
public class SpringSessionApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringSessionApplication.class, args);
    }
}
  • @EnableRedisHttpSession
    该注解创建一个名为“springSessionRepositoryFilter”并实现了Filter 的Spring Bean(过滤器),该过滤器负责替将HttpSession 替换为 Spring Session支持的实现; 在此,Spring Session由Redis支持。
    • maxInactiveIntervalInSeconds :设置session的过期时间,默认为1800秒,即30分钟


在这里插入图片描述
对于SpringSession是如何将HttpSession替换为SpringSession支持的,可以查看该博客Spring Session 源码分析(1)——springSessionRepositoryFilter

2.3 配置文件application.properties

# 分别启动两个服务,一个来设置session,一个来获取session
server.port=10001
# server.port=10002
server.servlet.context-path=/

# session 存储类型。
spring.session.store-type = redis
# session 超时。如果未指定持续时间后缀,则使用秒。
server.servlet.session.timeout=5
# session 刷新模式。
spring.session.redis.flush-mode=on_save
# 用于存储session 的键的命名空间。
spring.session.redis.namespace=spring:session

#Redis服务器主机。
spring.redis.host=localhost
#Redis服务器的登录密码。
spring.redis.password=
#Redis服务器端口。
spring.redis.port=6379

2.4 controller

/**
 * session共享测试controller
 * 启动两个服务,端口为10001的服务设置session,端口为10002的服务来获取session,测试是否能够获取,实现session共享
 */
@RestController
@RequestMapping("/session")
public class SessionController {

    @Value("${server.port}")
    private Integer port;

    /**
     * 设置session
     * redis中的key有一下几个:
     *      (hash)(session存储)  spring:session:sessions:c072782b-28c6-4ca3-9122-d1a3ef21ad89
     *      (string)  spring:session:sessions:expires:c072782b-28c6-4ca3-9122-d1a3ef21ad89
     *      (set)   spring:session:expirations:1603177440000
     * @param session
     * @return
     */
    @PostMapping("/set")
    public String set(HttpSession session) {
        session.setAttribute("username", "test");
        return String.valueOf(port);
    }

    /**
     * 获取session
     * @param session
     * @return
     */
    @GetMapping("/get")
    public String get(HttpSession session) {
        String username = (String) session.getAttribute("username");
        return username + ":" + port;
    }
}

3. 启动测试

3.1 启动

分别启动端口为10001和10002的两个服务,用来设置和获取session
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

注意:修改配置文件的端口后再启动

3.2 测试

  1. 使用Postman 访问10001端口来设置Session
    在这里插入图片描述
  2. 查看Redis
    在这里插入图片描述
  3. 分别访问10001和10002端口获取Session
    在这里插入图片描述

在这里插入图片描述

4. 源码

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值