Spring Gateway Redis 会话存储类型 - 保存问题

问题描述

我在微服务架构中有一个 spring 网关。

当请求到达网关时,它必须按照下面提到的方式运行

  1. 创建会话并设置属性
  2. 在 redis 中保存会话。
  3. 将请求路由到微服务 B
  4. 微服务 B 收到 sessionId 并获取 来自会话的属性

在尝试实现这一点时,保存 sessionId 的(第 2 点)发生在微服务 B 被调用并返回其响应(第 4 点)之后。 (即第 2 点发生在第 4 点之后)。

但是,在将请求路由到应用程序 B 之前,期望 sessionId 保存在 redis 中。

网关应用

application.yml

server:
  port: 4000
spring:
  cloud:
    gateway:
      routes:
      - id: demo-app1
        uri: http://localhost:4001/demo-app1
        predicates:
        - Path=/demo-app1/**
        filters:
        - SaveSession
        - CustomSessionHandle
        - name: Retry
          args:
            retries: 2
            statuses: BAD_GATEWAY
            methods: GET,POST
            backoff:
              firstBackoff: 10ms
              maxBackoff: 50ms
              factor: 2
              basedOnPrevIoUsValue: false

  session:
    store-type: redis             # Defines where the session is stored JVM or redis
    redis:
      flush-mode: immediate      #Tells spring to flush the session data immediately into redis
  redis:
    host: 127.0.0.1
    port: 6379

@Component
public class CustomrequestFilter implements GatewayFilter,Ordered {

    @Override
    public int getorder() {
        return -1;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange,GatewayFilterChain chain) {
        Map<String,Object> sessionMap = new HashMap<>();
        sessionMap.put("param","Hi,I am the value from cloud gateway");    

        return exchange.getSession().doOnNext(webSession -> webSession.getAttributes().putAll(sessionMap))).then(chain.filter(
                exchange));
    }

   
}

@Component
public class CustomSessionHandle extends AbstractGatewayFilterFactory<Object> {

    @Override
    public GatewayFilter apply(Object config) {
        return new CustomrequestFilter();
    }

}

POM 文件 --> 使用 spring boot 2.3.9

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-sleuth</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.zalando</groupId>
            <artifactId>logbook-spring-boot-starter</artifactId>
            <version>${logbook-spring-boot-starter}</version>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

解决方法

您可以使用@order注解提及过滤器的顺序

,
<div id='menu' class='topnav'>
  <a href='#1'>abcdefg</a>
  <a href='#2'>abcdefg</a>
  <a href='#3'>abcdefg</a>
  <a href='#4'>abcdefg</a>
  <input type='text' placeholder='Search here'>
</div>