1.为什么要将 Session 存储在 Redis 中
如果我们不将 Session 存储在 MySQL 或者 Redis 中, 那么做出来的项目就只能支持单机部署, 不支持分布式部署. 因为之前我们只是将 Session 存储在当前电脑的内存里面. 当张三去登录的时候, 将 Session 信息存储在 A 服务器, 这个时候负载均衡器将张三转到 B 服务器了, 而 B 服务器里面是没有张三的登录信息的, 那么这个时候, 张三又得登录一次, 这就不太合理了.
为了解决这个问题, 我们就需要将 Session 存储在 MySQL 或者 Redis 中, 而大部分的做法几乎都是将 Session 存储在 Redis 中.
画图理解 >>
单机部署

分布式部署

分布式部署相较于单机部署的区别 :
一台服务器升级为多台服务器
好处 : 1. 提升性能. 2. 当 A 服务器挂了, 还有 B 服务器, C 服务器顶着.
假设 1 台服务器每秒能够承载的并发数是 100 的话, 那么升级为 3 台服务器之后, 服务器能够承载的并发数的理论值就提升了 3 倍, 相当于性能提升了 3 倍. 但是它也带来了相应的问题 :
1. 最早只有一台服务器的时候, 张三的 Session 信息就存储在 A 服务器里, 如果不考虑服务器重启, Session 信息过期等情况, 那么服务器就会认为张三一直处于登录状态.
2. 而多台服务器中, 张三去访问程序的时候, 就不再是固定的去访问 A 服务器了, 第二次访问的时候, 张三的请求就被分配给了 B 服务器了, 这是完全可能的.如果不配置负载均衡规则的话, 默认是轮询的负载均衡策略, 也就是第一次请求分配了 A , 下一次就分配给了 B , 这样轮着分配. 如果 Session 存储在当前电脑的内存中, A 的第一次请求, 已经将 Session 信息存储在 A 服务器了, 那么下一次访问程序时, 如果请求被分配给了 B 服务器, 而 B 服务器并没有张三的登录信息, 那么就需要重新登录一次, 这就不合理了.
将 Session 持久化到数据库 - 支持分布式部署
对于上述问题, 将 Session 持久化到数据库中, 就解决了这个问题, 轮询的是程序, 而不是数据库, 所以无论请求被分配到哪个服务器, 都是可以获取到当前用户的登录信息的.
2. 如何将 Session 存储到 Redis
2.1 添加依赖
-
<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>
2.2 修改配置
application.properties
-
# 告诉 spring 将 session 存储在什么介质中
-
spring.session.store-type=redis
-
# session 的过期时间
-
server.servlet.session.timeout=1800
-
# session 的存储方式 - 磁盘存储
-
spring.session.redis.flush-mode=on_save
-
# 存储 session 的文件目录 (作用域)
-
spring.session.redis.namespace=spring:session
-
spring.redis.host=43.139.1.94
-
spring.redis.password=
-
spring.redis.port=6379
-
spring.redis.database=2
2.3 存储和读取 Session
创建 User 类 >>
-
@Data
-
public
class
User
implements
Serializable {
-
private
int id;
-
private String username;
-
private String password;
-
}
存储和读取 Session
-
@RestController
-
public
class
UserController {
-
-
private
final
String
user_session_key
=
"session_1";
-
-
/**
-
* 存储 Session
-
* @param session
-
* @return
-
*/
-
@RequestMapping("/login")
-
public
boolean
login
(HttpSession session) {
-
// .... 省去验证过程
-
// 伪代码
-
User
user
=
new
User();
-
user.setId(
1);
-
user.setUsername(
"张三");
-
user.setPassword(
"123");
-
session.setAttribute(user_session_key, user);
-
return
true;
-
}
-
-
/**
-
* 获取 Session
-
* @param request
-
* @return
-
*/
-
@RequestMapping("/getsess")
-
public User
getSession
(HttpServletRequest request) {
-
HttpSession
session
= request.getSession(
false);
-
if(session !=
null) {
-
return (User) session.getAttribute(user_session_key);
-
}
-
return
null;
-
}
-
}
其实这个存储和读取 Session 的代码和以前的方式很想, 只不过将 Session 存储到 Redis 的事情都由框架帮我们做了, 我们只需要遵守约定即可.
验证程序 >> 127.0.0.1:8080/login

查看 Redis 客户端 >>

获取 Session >> 127.0.0.1:8080/getsess

此时就算我们重启服务器, 再去调用 getsess, 依然可以拿到张三的身份信息, 下来可以自己测试一下.
本篇博客就到这里了, 谢谢观看~
转载:https://blog.csdn.net/xaiobit_hl/article/details/128956949
查看评论