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

  • 相关阅读:
    JVM调优2
    CAP理论/AP架构/CP架构
    JDK8 JVM性能优化-1
    string+和stringbuffer的速度比较
    @SpringBootApplication注解分析
    Spring Cloud底层原理
    Window 下安装 redis
    Spring的任务调度@Scheduled注解——task:scheduler和task:executor的解析
    多线程捕获线程中的异常
    将 HTML 页面内容转换为图片或PDF文件
  • 原文地址:https://www.cnblogs.com/codingmode/p/15333160.html
Copyright © 2011-2022 走看看