1. 准备环境
Tomcat8.x
SpringMvc | SpringBoot Redis
2. 实现方案
目前要实现SpringMvc项目在Tomcat集群之间session共享,网上大概有几种方案:
第一种方案:Tomcat自带Tomcat每台机器节点之间都会互相复制session,对于较小的集群问题不大,如果集群节点较大不推荐,需要考虑session大小,网络等等因素,此处不考虑这种方案。
第二种方案:tomcat-redis-session-manage
只支持到Tomcat7
,如果要在Tomcat8
上使用需要修改源码,也不做考虑。redisson-tomcat
只需要添加2个jar包,以及一个配置文件,如果不打算使用spring-session
,该方案简单以及不需要修改工程项目代码,可以采用该方案。
第三种方案:Spring提供的session共享解决方案,基于过滤器对request包装实现,可以通过配置切换存储方式,支持Redis、MongoDB、JDBC
等等,推荐采用该方案。
3. Spring Session整合
Spring Session是用于管理Http Session的框架,通过简单配置即可完成Session共享。
Spring Session支持JDBC、MongoDB、Gemfire、Redis
持久化session,本文示例采用Redis
。
3.1 基于 Java配置(非SpringBoot)
3.1.1 添加所需依赖
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session</artifactId>
<version>1.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.5.0.RELEASE</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.4.2</version>
</dependency>
3.1.2 Spring Session Java配置
添加相关依赖后,在添加一个配置类完成我们的配置
@Configuration
@EnableRedisHttpSession
public class SessionConfig extends AbstractHttpSessionApplicationInitializer {
@Bean
public JedisConnectionFactory connectionFactory() {
return new JedisConnectionFactory();
}
}
本文示范使用
JedisConnectionFactory
最简单配置,实际使用中需要根据具体配置相关参数。
@EnableRedisHttpSession
注册了一个SessionRepositoryFilter
过滤器。该过滤器对request和response进行了包装,并对request的getSession
方法进行了扩展。请求完成,调用request的commitSession
方法对session进行了保存。
3.2 SpringBoot 配置
上述例子是采用Spring的方式配置,如果使用的是SpringBoot可以直接通过依赖相关jar包及修改配置文件完成配置。
3.2.1 添加所需依赖
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
3.2.2 properties添加以下设置
# 可以设置的存储类型:REDIS、MONGODB、JDBC、HAZELCAST
spring.session.store-type=redis
# 使用Redis需要配置相关参数
spring.redis.host=localhost
spring.redis.password=
spring.redis.port=6379
更多相关参数请查看:spring-docs
配置完成,下面我们对此进行测试。
3.3 测试
3.3.1 添加测试代码
添加一个接口,并启动两个实例,端口分别为8080、8081,分别访问查看返回的sessionId是否相同。
@RestController
@RequestMapping("/session")
public class SessionController {
@GetMapping
public String getId(HttpSession session) {
return session.getId();
}
}
3.3.2 访问实例1
3.3.2 访问实例2
最后我们查看Redis
中是否也新增了对应的值
至此基本完成,最后还可以尝试删除Redis
中的key,并重新访问接口查看返回值的sessionId是否重新生成,确认session是否由Spring接管,本文不在演示。
4. 代码例子
Github:
https://github.com/RainorshineGW/SpringBoot-Example/tree/master/springboot-session