远方蔚蓝
一刹那情真,相逢不如不见

文章数量 126

访问次数 199895

运行天数 1437

最近活跃 2024-10-04 23:36:48

进入后台管理系统

Springboot一个依赖搞定session共享


一个简化的方案就是使用 Spring Session 来实现这一功能,Spring Session 就是使用 Spring 中的代理过滤器,将所有的 Session 操作拦截下来,自动的将数据 同步到 Redis 中,或者自动的从 Redis 中读取数据。
对于开发者来说,所有关于 Session 同步的操作都是透明的,开发者使用 Spring Session,一旦配置完成后,具体的用法就像使用一个普通的 Session 一样。
首先 创建一个 Spring Boot 工程,引入 Web、Spring Session 以及 Redis:
<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
这里的 Redis ,我虽然配置了四行,但是考虑到端口默认就是 6379 ,database 默认就是 0,所以真正要配置的,其实就是两行。
1.3 使用
配置完成后 ,就可以使用 Spring Session 了,其实就是使用普通的 HttpSession ,其他的 Session 同步到 Redis 等操作,框架已经自动帮你完成了:
@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 。
打包之后,启动项目的两个实例:
java -jar sessionshare-0.0.1-SNAPSHOT.jar --server.port=8080
java -jar sessionshare-0.0.1-SNAPSHOT.jar --server.port=8081
然后,再调用 localhost:8081/get 接口,就可以获取到 8080 服务的 session 中的数据
然后先访问 localhost:8080/set 向 8080 这个服务的 Session 中保存一个变量,访问完成后,数据就已经自动同步到 Redis 中 了
此时关于 session 共享的配置就已经全部完成了,session 共享的效果我们已经看到了,但是每次访问都是我自己手动切换服务实例,因此,接下来我们来引入 Nginx ,实现服务实例自动切换。
1.4 引入 Nginx
很简单,进入 Nginx 的安装目录的 conf 目录下(默认是在 /usr/local/nginx/conf),编辑 nginx.conf 文件:
upstream javaboy.org {
	server 127.0.0.1:8080 weight=1;
	server 127.0.0.1:8081 weight=2;
}
server {
	listen			80;
	server_name		localhost;
	#charset		koi8-r;
	#access_log		logs/host.access.logs	main;
	location / {
		proxy_pass http://javaboy.org;
		proxy_redirect default;
		#root	html;
		index	index.html index.html;
	}
}
在这段配置中:
  1. upstream 表示配置上游服务器
  1. javaboy.org 表示服务器集群的名字,这个可以随意取名字
  1. upstream 里边配置的是一个个的单独服务
  1. weight 表示服务的权重,意味者将有多少比例的请求从 Nginx 上转发到该服务上
  1. location 中的 proxy_pass 表示请求转发的地址,/ 表示拦截到所有的请求,转发转发到刚刚配置好的服务集群中
  1. 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 实例
使用 8081 的 Spring Boot 访问这个 /set 请求,再访问 8080 Spring Boot 的 /get 请求: