前言
现在随着分布式, 微服务架构的日益成熟, 越来越多的企业将传统的单体服务改造成微服务或者分布式架构. 当然不是说单体服务现在是百无一用, 只能说没有最好的, 只要适合就好. 在分布式服务改造中, 大家都遇到过一个问题, 那就是分布式 session 管理. 之前的单体服务 session 是保存在容器的内存中的. 微服务架构中一个服务为了实现高可用都是至少 3 个点部署, 这样就遇到一个问题, 就是这个部署在不同服务器上的三个点如何实现共享 session 呢? 其实解决方案是很多的, 原理也是差不多的. 比如说我们现在项目就是将 session 保存在数据库中, 这样三个点都去读取数据库来实现 session 共享. 还有的方案就是大家比较熟悉的将 session 存储在 Redis 中, 而且 Redis 支持 key 设置过期时间, 这个和用户会话的过期就不谋而合了. 只不过传统的集成方案需要我们手动的将 session 存储在 Redis 中, 然后再在 Redis 中读取, 这种方式操作起来可能比较重复繁琐. 所以 spring 已经在 spring 全家桶中提供了分布式 session 共享集成方案, 就是标题中所说的 springsession. 这里基于 springboot 来搭建个入门 demo, 以便大家快速了解 springsession, 它其实就是把你本来需要手动存储 Redis 的操作给做了, 让开发者不需要自己手动去存储 session
配置 maven
- <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>
配置 application.YAML
- spring:
- session:
- store-type: Redis
- timeout: 3600s
- Redis:
- flush-mode: on_save
- namespace: spring:session
- Redis:
- host: 192.168.99.100
- port: 6379
- timeout: 5000ms
主类首先开启 EnableRedisHttpSession 注解
- // 主类首先开启 EnableRedisHttpSession 注解
- @SpringBootApplication
- @EnableRedisHttpSession
- public class DistributeSessionApplication {
- public static void main(String[] args) {
- SpringApplication.run(DistributeSessionApplication.class, args);
- }
- }
编写 controller,set 用于向 session 添加属性, get 用于从 session 获取属性
- package com.example.distributesession.controller;
- import org.springframework.Web.bind.annotation.GetMapping;
- import org.springframework.Web.bind.annotation.RestController;
- import javax.servlet.http.HttpServletRequest;
- import java.util.HashMap;
- import java.util.Map;
- /**
- * @Author: 小混蛋
- * @CreateDate: 2018/12/11 17:20
- */
- @RestController
- public class TestController {
- @GetMapping("/set")
- public void test(HttpServletRequest request){
- request.getSession().setAttribute("message",request.getQueryString());
- }
- @GetMapping("/get")
- public Map<String,Object> two(HttpServletRequest request){
- Map<String,Object> map = new HashMap<>();
- map.put("sessionId",request.getSession().getId());
- map.put("message",request.getSession().getAttribute("message"));
- return map;
- }
- }
配置集群服务器
配置两个配置文件分别是 dev 和 pro, 服务器端口分别设置为 8081 和 8082,
- java -jar name.jar --spring.profiles.active=dev
- java -jar name.jar --spring.profiles.active=pro
测试
一台服务器访问: http://localhost:8081/set 和另外一台服务器访问: http://localhost:8081/get
此处声明下, 在实际项目中域名端口号肯定是一致的 , 此时是为了模拟分布式环境测试
总结
本质上利用 Tomcat 的 Filter 的实现类 SpringSessionRepositoryFilter 实现了对每一次请求的拦截, 拦截之后把 Session 放到 Redis 里面
这篇博文主要是介绍如何利用 Redis 来实现 session, 当然 Redis 只是一个内存数据库也可以使用其他的, 只是 Redis 是目前社区中最活跃的, springboot 也有利用 cache 整合 Redis 还有如何整合 Redis 的工具类, SpringBoot 整合 Redis 及 Redis 工具类撰写 https://www.cnblogs.com/fangh816/p/13306755.html
来源: http://www.bubuko.com/infodetail-3644758.html