WebSession
以往用zuul作网关的时候,直接使用@EnableRedisHttpSession 在配置里面就可以通过redis共享session信息
spring同时提供了EnableRedisWebSession 来对WebFlux的支持
session的jar包引入POM
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
由于redis我们使用lettuce的客户端,所以需要引入commons-pool2的包
添加redis的配置
redis:
host: localhost
port: 6379
database: 1
lettuce:
pool:
max-active: 8
max-idle: 8
max-wait: -1ms
min-idle: 1
然后在filter里面配置
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("this is a pre filter");
return exchange.getSession().flatMap(webSession -> {
log.info("websession: {}", webSession.getId());
webSession.getAttributes().put(webSession.getId(), "aaaa");
return chain.filter(exchange);
}).then(Mono.fromRunnable(() -> {
log.info("this is a post filter");
}));
}
请求经过filter的时候,会将 webSession.getAttributes().put(webSession.getId(), “aaaa”);存入redis
用PostMan发起一个请求,然后查看redis
可以看到刚才保存进去的数据
但是这里有一个问题,直接这样存储的数据,由于Gateway使用Netty作为容器,转发的时候sessionId已经发生了变化,所以下游服务并不能获取到正确的sessionId
比如这里的sessionId是b6f97cff-d743-4100-be8d-22bfd0cdc9c9
在微服务里面看到的sessionId却是DCC905E21ED70ADECCB76465051056E0
使用Gateway只能用token的方案,不能用浏览器自身的session作为客户端凭证的方案
例如在header里面加入token的头
然后发起请求
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("this is a pre filter2");
String token = exchange.getRequest().getHeaders().getFirst("token");
redisTemplate.opsForValue().set("token:" + token, "aaaa");
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
log.info("this is a post filter2");
}));
}
再查看redis
再查看下游服务的日志信息
INFO 3644 --- [nio-8801-exec-1] c.m.d.client.controller.DemoController : header: token, 78105107-fdc4-3a39-898a-b5c5ca3d13b5
可以看到header里面的信息透传下去了
目前还没有找到Spring自带的EnableRedisWebSession怎么使用
redis里面存在数据,但是lettuce的客户端读出来为null
另外在实际使用中,发现低版本的lettuce存在严重bug,会有redis里面存在数据但读出来为null的情况
这种情况在lettuce的github上也有看到issue
https://github.com/lettuce-io/lettuce-core/pull/987
在5.1.5.RELEASE已经修复,在实际使用的时候需要注意尽量引用高版本的。
使用Springboot 2.1.5.RELEASE版自动依赖的就是5.1.6.RELEASE版本的lettuce
目前webflux相关的组件感觉还是没有完全成熟,使用的时候可能还是会遇到比较多的坑
欢迎关注微信交流