个人博客
在分布式环境中,如果用户在A服务器登录,在下一步操作时如果转发到B服务器,如果这时候没有做Session共享则会导致用户需要再次登录。我们可以使用Redis来缓存Session,然后共享给集群来解决这个问题。
1、Maven依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.4.RELEASE</version> </parent> <dependencies> <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> </dependencies>
|
2、应用配置redis
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| server: port: 30600
spring: application: name: redis-session redis: cluster: nodes: - 148.70.153.63:9426 - 148.70.153.63:9427 - 148.70.153.63:9428 - 148.70.153.63:9429 - 148.70.153.63:9430 - 148.70.153.63:9431 password: password timeout: 60000
|
这个时候,就已经完成了Session的分布式共享的配置,我们不需要在应用上做任何操作。因为Spring对于Session的缓存和获取已经做了封装,所以对于应用是无感的。我们只需要在应用层获取Session即可。
3、测试验证
1 2 3 4 5 6 7 8
| @RestController public class SessionController { @RequestMapping("/getSessionId") public String getSessionId(HttpServletRequest request) { String sessionId = request.getSession().getId(); return sessionId; } }
|
在实际应用中,是由Nginx
这种反向代理服务器转发给后面的服务器,客户端访问的地址始终是一样的。这里为了方便演示,分别用2个端口30600
、30700
启动服务,代表2台不同的服务器。
打开浏览器分别访问:
http://127.0.0.1:30600/getSessionId
http://127.0.0.1:30700/getSessionId
可以看到获取的SessionId是一样的,说明2个服务已经共享了Session。
4、指定分布式Session过期时间
原server.session.timeout
配置Session过期时间不再生效。
需要通过在启动类添加注解@EnableRedisHttpSession
来指定Session过期时间。
1 2 3 4 5 6 7
| @SpringBootApplication @EnableRedisHttpSession(maxInactiveIntervalInSeconds = 3600) public class RedisSessionApplication { public static void main(String[] args) { SpringApplication.run(RedisSessionApplication.class, args); } }
|
代码地址