SpringBoot共享Session的方法,Redis示例
Hi I'm Shendi
首先说下Session,Session是服务端对于用户的一次会话
当新的用户访问服务器时,服务器会创建并存储一个信息代表此用户,并响应给浏览器(set-cookie响应头),浏览器会将这个消息保存起来,在下次请求此服务器的时候带上此信息,而服务器通过此信息就知道是哪个用户(会话)了
对于验证码等一些用户的临时数据用Session是比较方便的
Session共享
传统web应用的Session被单台服务器容器管理,如果要搭建集群,则需要共享Session
Session共享常用有以下几种方法
Session复制
Tomcat/jetty等容器支持,修改配置即可
多台服务器组成集群,当其中一台有新用户连接,生成session时,会将此session同步到其他服务器,这样就实现了session共享
但是这样会占用比较大的带宽,每台服务器都保存了session,不适合集群
浏览器存储
将信息都存到Cookie上,获取信息从Cookie上取,但是Cookie是有大小限制的,而且用户每次请求都会携带Cookie,占用带宽,但可以节省服务器内存开销,而且Cookie容易泄露,所以不能存储重要信息
Nginx Hash一致性
搭建集群一般用的nginx,负载均衡将请求随机分配或者平摊到其他服务器上,session不一致是因为用户访问了不同服务器导致的,如果能保证用户每次都访问的相同的服务器,那么就可以解决
在nginx配置负载均衡内增加 ip_hash,这样相同ip的就会访问相同的服务器
upstream test {
server 127.0.0.1:8080;
server 127.0.0.1:8081;
ip_hash;
}
但重启服务器会导致session丢失,且不能共享,对Session要求不高,仅仅是用作验证码可以使用此方法
Spring Session
Spring的会话管理工具,推荐使用这种方法来共享Session
共享session有一个最简单的办法就是将session存储到其他地方,例如Redis,Spring Session就是干这个的
当服务器接到请求,先进入过滤器(Filter),过滤器内将session存储到Redis中,通过Redis来共享Session(将Session从Web容器剥离)
对于使用Session的方法和之前无区别
以Redis作为第三方服务来共享Session
分为两步
- 引入依赖
- 给启动类加上
@EnableRedisHttpSession
注解来启用Redis接管Session
引入依赖,pom加入
<!-- SpringDataRedis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- 用于redis接管session -->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
启动类加上 @EnableRedisHttpSession
注解
@SpringBootApplication
@EnableRedisHttpSession
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
测试
配置好redis,加两个接口,一个获取session内容,一个设置session内容,例如
@RestController
public class UserControl {
@GetMapping("/get")
public String get(HttpServletRequest req) {
String name = (String) req.getSession().getAttribute("name");
System.out.println(name);
return name;
}
@GetMapping("/set")
public String set(HttpServletRequest req, String name) {
req.getSession().setAttribute("name", name);
return "设置成功";
}
}
启动SpringBoot,然后更改端口在启动一个,例如端口为9910和9911,启动完成后,可以尝试下在9910调用set接口设置session内容,然后在9911端口获取
可以在 redis 中看到新增了三个key
在9911端口可以获取到内容,证明session已经共享了
END
本文链接:https://sdpro.top/blog/html/article/1026.html♥ 赞助 ♥
尽管去做,或许最终的结果不尽人意,但你不付出,他不付出,那怎会进步呢?