在分布式环境中,如果用户在A服务器登录,在下一步操作时如果转发到B服务器,如果这时候没有做Session共享则会导致用户需要再次登录。我们可以使用Redis来缓存Session,然后共享给集群来解决这个问题。
1、Maven依赖
<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
server:
port: 30600
spring:
application:
name: redis-session
# redis配置
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、测试验证
@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过期时间。
@SpringBootApplication
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 3600)
public class RedisSessionApplication {
public static void main(String[] args) {
SpringApplication.run(RedisSessionApplication.class, args);
}
}
网友评论