SpringCloudGateway笔记(4)-WebSession

本文记录了在SpringCloudGateway中使用Redis进行WebSession管理时遇到的问题,包括sessionId变化导致下游服务无法获取正确session,以及Lettuce客户端读取数据为null的bug。文中提到该问题在Lettuce的高版本中已修复,并建议使用token而非session作为客户端凭证。还提到了WebFlux组件在实际应用中的不成熟性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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相关的组件感觉还是没有完全成熟,使用的时候可能还是会遇到比较多的坑

GITHUB代码地址

欢迎关注微信交流
在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值