zoukankan      html  css  js  c++  java
  • Cloud++:SpringCloud Gateway WebSession 笔记

    刚接触到 gateway 的时候难免会遇到一些坎坷,特此写下笔记。

    WebSession:

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

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

    session 的jar包引入POM:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.springframework.session</groupId>
        <artifactId>spring-session-core</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 配置:

    spring:
      redis:
        host: 192.168.1.101
        port: 6379
        timeout: 20000
        pool:
          # 连接池最大连接数(使用负值表示没有限制)
          max-active: 8
          # 连接池中的最小空闲连接  
          min-idle: 0
          # 连接池中的最大空闲连接
          max-idle: 8
          # 连接池最大阻塞等待时间(使用负值表示没有限制)
          max-wait: 5000
        password:

    然后在 filter 里面配置:

        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            ServerHttpRequest request = exchange.getRequest();
            String url = request.getURI().getPath();
            return exchange.getSession().flatMap(webSession -> {
                LOGGER.info("websession: {}", webSession.getId());
                webSession.getAttributes().put(webSession.getId(), "sign");
                return chain.filter(exchange);
            }).then(Mono.fromRunnable(() -> {
                LOGGER.info("this is a post filter");
            }));
        }

     请求经过filter的时候,会将 webSession.getAttributes().put(webSession.getId(), “sign”); 存入redis

     

     

    可以看到刚才保存进去的数据:

    但是这里有一个问题,直接这样存储的数据,由于 Gateway 使用 Netty 作为容器,转发的时候 sessionId 已经发生了变化,所以下游服务并不能获取到正确的 sessionId

    网关中的 sessionId:

    下游的 sessionId:

    使用 Gateway 只能用 token 的方案,不能用浏览器自身的 session 作为客户端凭证的方案 例如在 heade r里面加入 token 的头 存入到 redis 中。

    之后的请求都携带 token 信息作为凭证,如何运用 token 这里就不叙述了。

    - - - 

    另外在实际使用中,发现低版本的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相关的组件感觉还是没有完全成熟,使用的时候可能还是会遇到比较多的坑。

  • 相关阅读:
    hadoop再次集群搭建(3)-如何选择相应的hadoop版本
    48. Rotate Image
    352. Data Stream as Disjoint Interval
    163. Missing Ranges
    228. Summary Ranges
    147. Insertion Sort List
    324. Wiggle Sort II
    215. Kth Largest Element in an Array
    快速排序
    280. Wiggle Sort
  • 原文地址:https://www.cnblogs.com/codingmode/p/15333160.html
Copyright © 2011-2022 走看看