正常情况下,HttpSession是通过Servlet容器创建并进行管理的,创建成功后保存在内存中,如果开发者需要对项目进行横向扩展搭建集群,那么可以利用一些硬件或软件工具来做负载均衡,此时,来自同一用户的Http请求就有可能被分发到不同的实例上去,如何保证各个实例之间Session的同步就成为一个必须解决的问题。SpringBoot提供了自动化的Session共享配置,它结合Redis可以非常方便地解决这个问题。原理就是 把原本存储在不同服务器上的Session拿出来放在一个独立的服务器上,如图所示:
当一个请求到达Nginx服务器后,首先进行请求分发,假设请求被realServer1处理了,realServer1在处理请求时,无论是存储session还是读取session,都去操作session服务器而不是操作自身内存中的session,其他realserver在处理请求时也是如此,即可实现session共享。
具体步骤:
1.引入manven包,重点是spring-session-data-redis, SpringSession可以做到透明化地替换掉应用的Session容器.
2.application.yml配置redis的基础连接信息
3.controller
@RestController
public class HelloController{
@Value("${server.port}")
String port;
@PostMapping("/save")
public String saveName(String name,HttpSession session){
session.setAttribute("name",name);
return port;
}
@GetMapping("/get")
public String getName(HttpSession session){
return port+":"+session.getAttribute("name").toString();
}
}
save接口用来向Session中存储数据,get接口用来从Session中获取数据,这里注入了项目启动的端口号,主要是为了区分到底是哪个服务器提供的服务。另外,虽然还是操作的HttpSession,但是实际上HttpSession容器已经被透明替换,真正的Session此时存储在Redis服务器上。
然后使用nginx做负载均衡,
请求分发
当realServer和nginx都启动后,调用"/save"接口存储数据