服务器之家

服务器之家 > 正文

Springboot Session共享实现原理及代码实例

时间:2020-08-17 12:22     来源/作者:柒丶月

在传统的单服务架构中,一般来说,只有一个服务器,那么不存在 Session

共享问题,但是在分布式/集群项目中,Session 共享则是一个必须面对的问题,先看一个简单的架构图:

Springboot Session共享实现原理及代码实例

在这样的架构中,会出现一些单服务中不存在的问题,例如客户端发起一个请求,这个请求到达 Nginx 上之后,被
Nginx 转发到 Tomcat A 上,然后在 Tomcat A 上往 session 中保存了一份数据,下次又来一个请求,这个请求被转发到 Tomcat
B 上,此时再去 Session中获取数据,发现没有之前的数据。对于这一类问题的解决,思路很简单,就是将各个服务之间需要共享的数据,保存到一个公共的地方(主流方案就是 Redis):

Springboot Session共享实现原理及代码实例

1 实战

1.1 创建工程

首先 创建一个 Spring Boot 工程,引入 Web、Spring Session 以及 Redis:

Springboot Session共享实现原理及代码实例

创建成功之后,pom.xml 文件如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<dependencies>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
  </dependency>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-data-redis</artifactId>
  </dependency>
</dependencies>

注意:

这里我使用的 Spring Boot 版本是 2.1.4 ,如果使用当前最新版 Spring Boot2.1.5的话,除了上面这些依赖之外,需要额外添加 Spring Security 依赖(其他操作不受影响,仅仅只是多了一个依赖,当然也多了 Spring Security 的一些默认认证流程)。

1.2 配置 Redis

spring.redis.host=192.168.66.128
spring.redis.port=6379
spring.redis.password=123
spring.redis.database=0

1.3 使用

配置完成后 ,就可以使用 Spring Session 了,其实就是使用普通的 HttpSession ,其他的 Session 同步到 Redis 等操作,框架已经自动帮你完成了:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@RestController
public class HelloController {
  @Value("${server.port}")
  Integer port;
  @GetMapping("/set")
  public String set(HttpSession session) {
    session.setAttribute("user", "javaboy");
    return String.valueOf(port);
  }
  @GetMapping("/get")
  public String get(HttpSession session) {
    return session.getAttribute("user") + ":" + port;
  }
}

考虑到一会 Spring Boot 将以集群的方式启动 ,为了获取每一个请求到底是哪一个 Spring Boot 提供的服务,需要在每次请求时返回当前服务的端口号,因此这里我注入了 server.port 。

接下来 ,项目打包:

Springboot Session共享实现原理及代码实例

打包之后,启动项目的两个实例:

java -jar sessionshare-0.0.1-SNAPSHOT.jar --server.port=8080
java -jar sessionshare-0.0.1-SNAPSHOT.jar --server.port=8081

然后先访问 localhost:8080/set 向 8080 这个服务的 Session 中保存一个变量,访问完成后,数据就已经自动同步到 Redis 中 了 :

Springboot Session共享实现原理及代码实例

然后,再调用 localhost:8081/get 接口,就可以获取到 8080 服务的 session 中的数据:

Springboot Session共享实现原理及代码实例

此时关于 session 共享的配置就已经全部完成了,session 共享的效果我们已经看到了,但是每次访问都是我自己手动切换服务实例,因此,接下来我们来引入 Nginx ,实现服务实例自动切换。

1.4 引入 Nginx

很简单,进入 Nginx 的安装目录的 conf 目录下(默认是在 /usr/local/nginx/conf),编辑 nginx.conf 文件:

Springboot Session共享实现原理及代码实例

在这段配置中:

  • upstream 表示配置上游服务器
  • javaboy.org 表示服务器集群的名字,这个可以随意取名字
  • upstream 里边配置的是一个个的单独服务
  • weight 表示服务的权重,意味者将有多少比例的请求从 Nginx 上转发到该服务上
  • location 中的 proxy_pass 表示请求转发的地址,/ 表示拦截到所有的请求,转发转发到刚刚配置好的服务集群中
  • proxy_redirect 表示设置当发生重定向请求时,nginx 自动修正响应头数据(默认是 Tomcat 返回重定向,此时重定向的地址是 Tomcat 的地址,我们需要将之修改使之成为 Nginx 的地址)。

配置完成后,将本地的 Spring Boot 打包好的 jar 上传到 Linux ,然后在 Linux 上分别启动两个 Spring Boot 实例:

nohup java -jar sessionshare-0.0.1-SNAPSHOT.jar --server.port=8080 & nohup java -jar sessionshare-0.0.1-SNAPSHOT.jar --server.port=8081 &

其中

  • nohup 表示当终端关闭时,Spring Boot 不要停止运行
  • & 表示让 Spring Boot 在后台启动

配置完成后,重启 Nginx:

/usr/local/nginx/sbin/nginx -s reload

Nginx 启动成功后,我们首先手动清除 Redis 上的数据,然后访问 192.168.66.128/set 表示向 session 中保存数据,这个请求首先会到达 Nginx 上,再由 Nginx 转发给某一个 Spring Boot 实例:

Springboot Session共享实现原理及代码实例

如上,表示端口为 8081 的 Spring Boot 处理了这个 /set 请求,再访问 /get 请求:

Springboot Session共享实现原理及代码实例

可以看到,/get 请求是被端口为 8080 的服务所处理的。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://www.cnblogs.com/qiuwenli/p/13442916.html

相关文章

热门资讯

2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
歪歪漫画vip账号共享2020_yy漫画免费账号密码共享
歪歪漫画vip账号共享2020_yy漫画免费账号密码共享 2020-04-07
Intellij idea2020永久破解,亲测可用!!!
Intellij idea2020永久破解,亲测可用!!! 2020-07-29
男生常说24816是什么意思?女生说13579是什么意思?
男生常说24816是什么意思?女生说13579是什么意思? 2019-09-17
沙雕群名称大全2019精选 今年最火的微信群名沙雕有创意
沙雕群名称大全2019精选 今年最火的微信群名沙雕有创意 2019-07-07
返回顶部