前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringCloudGateway笔记(4)-WebSession

SpringCloudGateway笔记(4)-WebSession

作者头像
yingzi_code
发布2019-08-30 22:11:53
6.9K0
发布2019-08-30 22:11:53
举报

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/yingziisme/article/details/94590953

WebSession

以往用zuul作网关的时候,直接使用@EnableRedisHttpSession 在配置里面就可以通过redis共享session信息

spring同时提供了EnableRedisWebSession 来对WebFlux的支持

session的jar包引入POM

代码语言:javascript
复制
        <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的配置

代码语言:javascript
复制
  redis:
    host: localhost
    port: 6379
    database: 1
    lettuce:
      pool:
        max-active: 8
        max-idle: 8
        max-wait: -1ms
        min-idle: 1

然后在filter里面配置

代码语言:javascript
复制
 @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的头

在这里插入图片描述
在这里插入图片描述

然后发起请求

代码语言:javascript
复制
    @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

在这里插入图片描述
在这里插入图片描述

再查看下游服务的日志信息

代码语言:javascript
复制
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代码地址

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019年07月03日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 但是这里有一个问题,直接这样存储的数据,由于Gateway使用Netty作为容器,转发的时候sessionId已经发生了变化,所以下游服务并不能获取到正确的sessionId
  • redis里面存在数据,但是lettuce的客户端读出来为null
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档