第十七节 SpringBoot通过Redis实现Session共享
一、基本原理
Cookie 保存在客户端浏览器中,而 Session 保存在服务器上。浏览器第一次访问服务器,服务器会创建一个Session,并将SessionId通过Cookie的形式传递给浏览器。下次浏览器再次向服务器请求数据的时候,会带着这个Cookie。服务器会快速识别出这个Cookie,并且通过Cookie找到刚才创建的Session。说的简单一点就是,顾客去超市,超市给顾客一张VIP卡,下次顾客去超市,只要出示这张VIP卡,超市就能快速的识别出这个顾客。
在实际工作中我们建议使用外部的缓存设备来共享 Session,避免单个服务器节点挂掉而影响服务,共享数据都会放到外部缓存容器中。为了达到共享Session的目的,那么就把Session存放到Redis中。
使用Redis实现共享session原理:
所有服务器的session信息都存储到了同一个Redis集群中,即所有的服务都将 Session 的信息存储到 Redis 集群中,无论是对 Session 的注销、更新都会同步到集群中,达到了 Session 共享的目的。
二、使用SpringSession
Spring 官方针对 Session 管理这个问题,提供了专门的组件 Spring Session,使用 Spring Session 在项目中集成分布式 Session 非常方便。Spring 为 Spring Session 和 Redis 的集成提供了组件:spring-session-data-redis。以前我在传统的SSM项目中,为了达到分布式项目共享Session的问题,还要实现SessionDao,现在想来真的是太麻烦了。
如何集成呢 ?简直不要太容易。
(1)第一步:导入Redis依赖与SpringSession依赖。
<!-- Redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<!-- Spring Session Redis 依赖-->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
(2)第二步:在yml中添加Redis的配置。因为Session就是存放在Redis中的。所以必须添加Redis的配置。
spring:
redis:
# Redis 数据库索引(默认为 0)
database: 0
# Redis 服务器地址
host: localhost
# Redis 服务器连接端口
port: 6379
password:
timeout: 10s
lettuce:
pool:
#连接池最大连接数(使用负值表示没有限制) 默认 8
max-active: 50
#连接池中的最大空闲连接 默认 8
max-idle: 8
#连接池中的最小空闲连接 默认 0
min-idle: 0
(3)第三步:在SpringBoot启动类上添加@EnableRedisHttpSession注解(其实不加也会自动生效,以防万一)。我这里配置了Session过期时间为1小时。原生的server.session.timeout 属性不再生效。
package com.zhoutianyu.learnspringboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
@SpringBootApplication
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800 * 2 )
public class LearnspringbootApplication {
public static void main(String[] args) {
SpringApplication.run(LearnspringbootApplication.class, args);
}
}
二、测试
package com.zhoutianyu.learnspringboot.session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
@RestController
@RequestMapping(value = "session")
public class SessionController {
private static final Logger LOGGER = LoggerFactory.getLogger(SessionController.class);
@RequestMapping(value = "/setSession")
public String setSession(HttpServletRequest request) {
request.getSession().setAttribute("key", "第十七节 通过Redis实现Session共享");
return "8081端口设值成功";
}
@RequestMapping(value = "/getSession")
public Object getSession(HttpServletRequest request) {
return request.getSession().getAttribute("key");
}
}
1)先打开Redis服务器,然后把项目设置成可以多节点启动,端口分别为8081与9081。
2)根据上面的SessionController的设置。首先请求/setSession ,它为session存放键值对:{key : 第十七节 通过Redis实现Session共享}。
3)然后在同一个浏览器中,访问9081端口的 /getSession。看代码,它取出session中键为key的值。
4)通过页面发现,9081端口取出的是值是"第十七节 通过Redis实现Session共享",说明9081端口取到了8081端口的Session数据。这表明,Session已经成功交由Redis管理,两个节点之间的Session共享成功。
三、源码下载
本章节项目源码:点我下载源代码
如果本系列文章对你有帮助,不妨请我喝瓶可乐吧!
你的打赏是对我最好的支持!