SpringBoot 使用SpringSeesion实现共享Session方案

原创
2020/12/05 16:30
阅读数 4.5K

Http协议本身是无状态的,为了保存会话信息,浏览器Cookie通过SessionID标识会话请求,服务器以SessionID为key来存储会话信息。在单实例应用中,可以考虑应用进程自身存储,随着应用体量的增长,需要横向扩容,多实例Session共享问题随之而来。

下面假设我们使用Nginx来实现负载均衡横向扩节点:

在这样的架构中,会出现无法获取到Session信息,不知道是哪个用户的请求。例如客户端发起一个请求,这个请求到了Nginx之后,会被Nginx转发到 Tomcat A上,然后在Tomcat A上的Session存储数据。后面又来一个请求,这个请求被Nginx转发到Tomcat B上,此时再去获取Session会发现没有数据。对于这样的问题有一个主流的解决办法,就是实现共享Session,把Session存储到Reids里面。如下:

这样无论存储还是读取Session的操作,都是去操作Redis中存储Session信息而不是自身内存中的Session,其他Tomcat也是如此,这样就实现了Session 共享。

 

一、添加依赖

除了Redis依赖之外,这里还要提供spring-session-data-redis依赖,SpringSession可以做到透明化地替换掉应用的Session容器。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <exclusions>
        <exclusion>
            <groupId>io.lettuce</groupId>
            <artifactId>lettuce-core</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-data-redis</artifactId>
</dependency>

 

二、Application.properties中配置Redis连接信息:

####  redis 配置 ####
# 基本连接信息配置
spring.redis.database = 0
spring.redis.host = 127.0.0.1
spring.redis.port = 6379
spring.redis.password = 123456
# 连接池信息配置
spring.redis.jedis.pool.max-active = 8
spring.redis.jedis.pool.max-idle = 8
spring.redis.jedis.pool.max-wait = -1
spring.redis.jedis.pool.min-idle = 0
spring.redis.timeout = 0

 

三、编写测试Controller

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpSession;

@RestController
public class SessionController {

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

    @GetMapping("/save/{name}")
    public String saveName(@PathVariable("name") String name, HttpSession session) {
        session.setAttribute("name", name);
        return port;
    }

    @GetMapping("/get")
    public String getName(HttpSession session) {
        return port + ":" + session.getAttribute("name").toString();
    }

}

 

四、运行项目

(1)使用maven打包运行,然后传入不同端口参数启动。

mvn clean package
nohup java -jar test-0.0.1-SNAPSHOT.jar --server.port=8080 &
nohup java -jar test-0.0.1-SNAPSHOT.jar --server.port=8081 &

nohup 表示不挂断程序运行,即当终端窗口关闭后,程序依然在后台运行,最后的 & 表示让程序在后台运行。

 

(2)使用idea编译器启动多个项目,设置不同端口参数。

如果想使用该方案,可以查看这篇文章:IDEA 启动多个SpringBoot项目不同端口

 

五、验证结果

1.我们先请求8081端口的save接口,存储一个session数据。

2.请求8081端口get接口,获取session数据。

3.请求8082端口的get接口,获取session数据。

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部