Gateway内网关的详细使用说明,包含由于版本问题、依赖问题引起的动态路由转发问题的详细解决说明

资料的连接

官方文档

https://spring-cloud-alibaba-group.github.io/github-pages/hoxton/en-us/index.html

基本的概念

相关属性

  1. Route:一个 Route 由路由 ID(用来绑定哪一个微服务),转发 URI(转移的目标URL),多个 Predicates 以及多个 Filters 构成。Gateway 上可以配置多个 Routes。处理请求时会按优先级排序,找到第一个满足所有 Predicates 的 Route
  2. Predicate表示路由的匹配条件,可以用来匹配请求的各种属性,如请求路径、方法、header 等。一个 Route 可以包含多个子 Predicates,多个子 Predicates 最终会合并成一个;
  3. Filter:过滤器包括了处理请求和响应的逻辑,可以分为 pre 和 post 两个阶段。多个 Filter 在 pre 阶段会按优先级高到低顺序执行post 阶段则是反向执行,由低到高的顺序。Gateway 包括两类 Filter。
    • 全局 Filter:每种全局 Filter 全局只会有一个实例,会对所有的 Route 都生效。
    • 路由 Filter:路由 Filter 是针对 Route 进行配置的,不同的 Route 可以使用不同的参数,因此会创建不同的实例

网关的概念

网关是系统的唯一对外的入口,介于客户端和服务器端之间的中间层,处理非业务功能,提供路由请求、鉴权、监控、缓存、限流等功能

使用网关的必要性

不同的微服务有不同的ip地址\端口号,客户端如果直接与各个微服务之间通信的话,就会存在以下的问题

  1. 首先是系统的复杂性问题,客户端经常会出现要多次请求不同的微服务,但是微服务的地址又不同,所以在调用的时候会因为这个地址而很麻烦
  2. 存在跨域请求,不同的微服务会部署在不同机器或者不同的端口,这就会导致跨域问题
  3. 认证比较复杂

相关配置

网关依赖

统一配置,使用SpringBoot2.7.13版本,因为SpringCloud和SpringCloud Alibaba的最新版本还比较低,所以最好就是使用这个SpringBoot版本,总而言之,最重要就是要额外添加依赖loadBalancer和boostrap

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.13</version>
        <relativePath/>
    </parent>
    
    <groupId>com.demo</groupId>
    <artifactId>spring-gateway-route</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-gateway-route</name>
    <description>spring-gateway-route</description>
    
    
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>2021.0.7</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2021.0.5.0</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <!--    注册中心    -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <!--    配置中心    -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>

        <!--    Spring Cloud 新版本默认将 Bootstrap 禁用,需要引入该依赖   -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>

        <!--gateway-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

        <!--客户端负载均衡loadbalancer-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

以下这个版本bug最少,但是版本有点混乱

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.13</version>
        <relativePath/>
    </parent>
    <groupId>com.demo</groupId>
    <artifactId>spring-gateway-route</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-gateway-route</name>
    <description>spring-gateway-route</description>
    <properties>
        <java.version>17</java.version>
        <spring-cloud.version>2021.0.1</spring-cloud.version> <!-- Update to a compatible Spring Cloud version -->
        <spring-cloud-alibaba.version>2021.0.5.0</spring-cloud-alibaba.version>
    </properties>
    <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>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.0.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>2021.1</version> 
        </dependency>
        <!--    Spring Cloud 新版本默认将 Bootstrap 禁用,需要引入该依赖   -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>
        <!--客户端负载均衡loadbalancer-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
























其他微服务的依赖

只需要使用新版本的SpringBoot和对应的比较新的Nacos就好

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.6</version>
        <relativePath/> 
    </parent>
    <groupId>com.demo</groupId>
    <artifactId>spring-gateway-user</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-gateway-user</name>
    <description>spring-gateway-user</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>2023.0.1.0</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

父工程的依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.6</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.demo</groupId>
    <artifactId>spring-gateway-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-gateway-demo</name>
    <description>spring-gateway-demo</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

网关application.yml文件配置内容

最标准的版本,这里面添加了检查和重试机制

server:
  port: 9000

spring:
  application:
    name: spring-gateway-route

  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848

    gateway:
      default-filters:
        - name: Retry
          args:
            retries: 3
            statuses: BAD_GATEWAY, GATEWAY_TIMEOUT, SERVICE_UNAVAILABLE
            methods: GET, POST
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: spring-gateway-user
          uri: lb://spring-gateway-user
          predicates:
            - Path=/user/**

logging:
  level:
    org.springframework.cloud.gateway: DEBUG
    com.alibaba.nacos: DEBUG

应用版本内容

server:
  port: 8100 # 网关端口

spring:
  application:
    name: czp-gateway # 服务名称
  cloud:
    nacos:
      server-addr: localhost:8888 # nacos地址
    gateway:
      default-filters:
        - name: Retry
          args:
            retries: 3
            statuses: BAD_GATEWAY, GATEWAY_TIMEOUT, SERVICE_UNAVAILABLE
            methods: GET, POST
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes: # 网关路由配置
        - id: user-service # 路由id,自定义,只要唯一即可
          # uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址,和下面的版本不同之处就在于下面的版本可以实现负载均衡
          uri: lb://userservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称
          predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
            - Path=/user/** # 这个是按照路径匹配,只要以/user/开头就符合要求

其他微服务application.yml文件配置内容

其他微服务的配置

server:
  port: 8080

spring:
  application:
    name: spring-gateway-user

  main:
    allow-bean-definition-overriding: true
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848

logging:
  level:
    org.springframework.cloud.gateway: DEBUG
    com.alibaba.nacos: DEBUG

(这里面添加一个配置 main: allow-bean-definition-overriding: true是因为原本项目里面的web依赖已经被包含在Gateway依赖里面了所以就要使用这个来排除)

说明

  • Gateway网关是实现路由的转发,包含路由转发之前和之后的修改等其他操作

    Nacos是服务注册和发现中心,是微服务把信息注册在Nacos里面,然后微服务之间相互调用的时候就可以在这里面拉取信息来调用

  • 这里面的要单独配置Nacos的地址,如果是部署在云服务器上面的话就要修改ip和port

  • routes的id可以自定义,只需要保持唯一就好

  • 断言Path代表发送来的请求里面包含指定的形式就会执行转发

  • lower-case-service-id: true是为了把上传到注册中心的服务名变为全小写,原本默认是全大写的,所以统一一下会更好

  • 这里面的uri对应的是对应微服务的ip+端口

  • uri有两种方案,一种是固定转发的地址,另一种可以实现负载均衡,基于Spring Cloud LoadBalancer来实现,会根据配置的负载均衡策略(例如轮询、随机、权重等策略)在这个微服务的所有的实例里面选择一个实例进行请求转发(一个微服务可以有多个运行在不同服务器\虚拟机\容器里面的运行实例)

    多实例的作用

    1. 高可用性:如果一个实例发生故障,其他实例可以继续提供服务,不会导致服务不可用。
    2. 负载均衡:多个实例可以均衡地处理请求,避免单个实例过载,提高系统性能和响应速度。
    3. 扩展性:可以根据流量需求动态增加或减少实例数量,实现弹性伸缩

    负载均衡的实现原理

    1. 服务注册与发现
      • 当你的微服务(例如 userservice)启动时,它会将自己的实例信息(包括地址、端口等)注册到 Nacos 服务注册中心。
      • Nacos 作为服务注册中心,保存了所有已注册服务的实例信息。
    2. Spring Cloud Gateway 的配置
      • Spring Cloud Gateway 配置中使用了 uri: lb://userservice,其中 lb 代表 LoadBalancer。
      • 当 Gateway 接收到符合路由断言的请求时,它会通过负载均衡策略来选择一个 userservice 的实例进行请求转发。
    3. 负载均衡过程
      • Spring Cloud Gateway 使用 Spring Cloud LoadBalancer 来实现负载均衡。
      • Gateway 会向 Nacos 查询 userservice 服务的所有可用实例列表。
      • 根据配置的负载均衡策略(例如轮询、随机、权重等),从可用实例中选择一个实例进行请求转发

路由的配置

  1. 路由id:路由的唯一标示
  2. 路由目标(uri):路由的目标地址,http代表固定地址,lb代表根据微服务名负载均衡
  3. 路由断言(predicates):判断路由的规则,
  4. 路由过滤器(filters):对请求或响应做处理

断言工厂(predicates的子属性)

img

过滤器

过滤器工厂

Spring提供了31种过滤器,以下为一部分常用的

过滤器filters属性是写在id为。。。路由下的,那么过滤器只对符合这个路由要求的请求生效

(配置在路由下的过滤器只对当前路由的请求生效)

1. AddRequestHeader

  • 功能:在请求头中添加一个新的头部信息。
  • 配置示例
spring:
  cloud:
    gateway:
      routes:
        - id: add_request_header_route
          uri: http://httpbin.org
          filters:
            - AddRequestHeader=X-Request-Foo, Bar
          predicates:
            - Path=/headers
            
spring:
  cloud:
    gateway:
      routes:
      - id: user-service 
        uri: lb://userservice 
        predicates: 
        - Path=/user/** 
        filters: # 过滤器
        - AddRequestHeader=Truth, Itcast is freaking awesome! # 添加请求头

这样子请求URL符合前缀为/user/而且要进入微服务userservice的请求就会被添加一个请求头

Truth=itcast is freaking awesome!

2. AddRequestParameter

  • 功能:在请求参数中添加一个新的参数。
  • 配置示例
spring:
  cloud:
    gateway:
      routes:
        - id: add_request_parameter_route
          uri: http://httpbin.org
          filters:
            - AddRequestParameter=foo, bar
          predicates:
            - Path=/get

3. AddResponseHeader

  • 功能:在响应头中添加一个新的头部信息。
  • 配置示例
spring:
  cloud:
    gateway:
      routes:
        - id: add_response_header_route
          uri: http://httpbin.org
          filters:
            - AddResponseHeader=X-Response-Foo, Bar
          predicates:
            - Path=/headers

4. DedupeResponseHeader

  • 功能:删除响应头中的重复条目。
  • 配置示例
spring:
  cloud:
    gateway:
      routes:
        - id: dedupe_response_header_route
          uri: http://httpbin.org
          filters:
            - DedupeResponseHeader=X-Response-Foo RETAIN_FIRST
          predicates:
            - Path=/headers

5. ModifyRequestBody

  • 功能:修改请求体内容。
  • 配置示例
spring:
  cloud:
    gateway:
      routes:
        - id: modify_request_body_route
          uri: http://httpbin.org
          filters:
            - ModifyRequestBody=
              inClass: org.springframework.util.MultiValueMap
              outClass: java.lang.String
              newBody: new_request_body
          predicates:
            - Path=/post

6. ModifyResponseBody

  • 功能:修改响应体内容。
  • 配置示例
spring:
  cloud:
    gateway:
      routes:
        - id: modify_response_body_route
          uri: http://httpbin.org
          filters:
            - ModifyResponseBody=
              inClass: java.lang.String
              outClass: java.lang.String
              newBody: new_response_body
          predicates:
            - Path=/post

7. RewritePath

  • 功能:重写请求路径。
  • 配置示例
spring:
  cloud:
    gateway:
      routes:
        - id: rewrite_path_route
          uri: http://httpbin.org
          filters:
            - RewritePath=/foo/(?<segment>.*), /${segment}
          predicates:
            - Path=/foo/**

8. SetPath

  • 功能:设置新的请求路径。
  • 配置示例
spring:
  cloud:
    gateway:
      routes:
        - id: set_path_route
          uri: http://httpbin.org
          filters:
            - SetPath=/new/path
          predicates:
            - Path=/old/path

9. StripPrefix

  • 功能:从请求路径中去除指定数量的路径前缀。
  • 配置示例
spring:
  cloud:
    gateway:
      routes:
        - id: strip_prefix_route
          uri: http://httpbin.org
          filters:
            - StripPrefix=1
          predicates:
            - Path=/prefix/**

10. Retry

  • 功能:对失败的请求进行重试。
  • 配置示例
spring:
  cloud:
    gateway:
      routes:
        - id: retry_route
          uri: http://httpbin.org
          filters:
            - name: Retry
              args:
                retries: 3
                statuses: BAD_GATEWAY
                methods: GET
          predicates:
            - Path=/delay/3

11. Hystrix

  • 功能:使用 Hystrix 进行断路保护。
  • 配置示例
spring:
  cloud:
    gateway:
      routes:
        - id: hystrix_route
          uri: http://httpbin.org
          filters:
            - name: Hystrix
              args:
                name: mycmd
          predicates:
            - Path=/delay/3

12. CircuitBreaker

  • 功能:使用 Resilience4j 进行断路保护。
  • 配置示例
spring:
  cloud:
    gateway:
      routes:
        - id: circuitbreaker_route
          uri: http://httpbin.org
          filters:
            - name: CircuitBreaker
              args:
                name: mycmd
                fallbackUri: forward:/fallback
          predicates:
            - Path=/delay/3

默认过滤器default-filters

如果要对所有的路由都生效的话,那么就可以把过滤器工厂写到default-filters下**(注意这个属性由于是对所有的路由生效的,所以其位置是和routes平行的)**

spring:
  application:
    name: czp-gateway # 服务名称
  cloud:
    nacos:
      server-addr: localhost:8888 # nacos地址
    gateway:
      routes: # 网关路由配置
        - id: user-service # 路由id,自定义,只要唯一即可
          # uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址,和下面的版本不同之处就在于下面的版本可以实现负载均衡
          uri: lb://userservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称
          predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
            - Path=/user/** # 这个是按照路径匹配,只要以/user/开头就符合要求
      default-filters:
        - AddRequestHeader=HeaderName, HeaderValue

实现全局过滤器(需要使用java类实现)

全局过滤器的作用对所有路由都生效,并且可以自定义处理逻辑

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
 
@Order(-1)
@Component
public class AuthorizeFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 1.获取请求参数
        MultiValueMap<String, String> params = exchange.getRequest().getQueryParams();
        // 2.获取authorization参数
        String auth = params.getFirst("authorization");
        // 3.校验
        if ("admin".equals(auth)) {
            // 放行
            return chain.filter(exchange);
        }
        // 4.拦截
        // 4.1.禁止访问,设置状态码
        exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
        // 4.2.结束处理
        return exchange.getResponse().setComplete();
    }
}

[!NOTE]

上面的全局过滤器的作用为判断请求的URL的参数是否有authorization并且其值是否为admin,如果是就放行,否则拦截,实现的过程为:

  1. 这个类需要实现GlobalFilter,并且重写其方法

    Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain)

  2. 添加注解@Order或者实现接口Ordered,

    @Order注解的说明

    在 Spring 框架中,@Order 注解用于定义组件或方法的执行顺序。特别是在 Spring Cloud Gateway 中,它可以用来设置过滤器的执行顺序。@Order 注解可以用于实现 Ordered 接口的类,也可以直接在类上使用。

    使用 @Order 注解

    @Order 注解可以在类级别使用,以指定过滤器的顺序。接收请求的值越小的过滤器优先级越高,会先执行,处理请求的时候顺序调反,值越小的过滤器优先级越低

    示例:使用 @Order 注解
    import org.springframework.cloud.gateway.filter.GlobalFilter;
    import org.springframework.core.Ordered;
    import org.springframework.core.annotation.Order;
    import org.springframework.stereotype.Component;
    import org.springframework.web.server.ServerWebExchange;
    import reactor.core.publisher.Mono;
    
    @Component
    @Order(1)
    public class CustomGlobalFilter implements GlobalFilter {
    
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, org.springframework.cloud.gateway.filter.GatewayFilterChain chain) {
            // Pre-filter logic
            System.out.println("Custom Global Filter with Order 1 - Pre-processing");
    
            return chain.filter(exchange).then(Mono.fromRunnable(() -> {
                // Post-filter logic
                System.out.println("Custom Global Filter with Order 1 - Post-processing");
            }));
        }
    }
    
    示例:实现 Ordered 接口

    如果你不想使用 @Order 注解,也可以通过实现 Ordered 接口来指定顺序:

    import org.springframework.cloud.gateway.filter.GlobalFilter;
    import org.springframework.core.Ordered;
    import org.springframework.stereotype.Component;
    import org.springframework.web.server.ServerWebExchange;
    import reactor.core.publisher.Mono;
    
    @Component
    public class AnotherGlobalFilter implements GlobalFilter, Ordered {
    
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, org.springframework.cloud.gateway.filter.GatewayFilterChain chain) {
            // Pre-filter logic
            System.out.println("Another Global Filter - Pre-processing");
    
            return chain.filter(exchange).then(Mono.fromRunnable(() -> {
                // Post-filter logic
                System.out.println("Another Global Filter - Post-processing");
            }));
        }
    
        @Override
        public int getOrder() {
            return 2;  // Specify the order
        }
    }
    

    如何确定顺序

    • 值越小,优先级越高,越早执行。
    • 可以是负值,负值表示更高的优先级。

    结合示例

    假设你有两个全局过滤器,并希望它们按特定顺序执行:

    CustomGlobalFilter(优先级 1)
    import org.springframework.cloud.gateway.filter.GlobalFilter;
    import org.springframework.core.Ordered;
    import org.springframework.core.annotation.Order;
    import org.springframework.stereotype.Component;
    import org.springframework.web.server.ServerWebExchange;
    import reactor.core.publisher.Mono;
    
    @Component
    @Order(1)
    public class CustomGlobalFilter implements GlobalFilter {
    
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, org.springframework.cloud.gateway.filter.GatewayFilterChain chain) {
            System.out.println("Custom Global Filter with Order 1 - Pre-processing");
    
            return chain.filter(exchange).then(Mono.fromRunnable(() -> {
                System.out.println("Custom Global Filter with Order 1 - Post-processing");
            }));
        }
    }
    
    AnotherGlobalFilter(优先级 2)
    import org.springframework.cloud.gateway.filter.GlobalFilter;
    import org.springframework.core.Ordered;
    import org.springframework.stereotype.Component;
    import org.springframework.web.server.ServerWebExchange;
    import reactor.core.publisher.Mono;
    
    @Component
    public class AnotherGlobalFilter implements GlobalFilter, Ordered {
    
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, org.springframework.cloud.gateway.filter.GatewayFilterChain chain) {
            System.out.println("Another Global Filter - Pre-processing");
    
            return chain.filter(exchange).then(Mono.fromRunnable(() -> {
                System.out.println("Another Global Filter - Post-processing");
            }));
        }
    
        @Override
        public int getOrder() {
            return 2;
        }
    }
    

    运行结果

    当一个请求通过网关时,过滤器将按顺序执行:

    1. CustomGlobalFilterPre-processing
    2. AnotherGlobalFilterPre-processing
    3. 实际请求处理
    4. AnotherGlobalFilterPost-processing
    5. CustomGlobalFilterPost-processing

    总结

    @Order 注解和 Ordered 接口提供了一种简单的方式来控制过滤器在 Spring Cloud Gateway 中的执行顺序。通过合理设置过滤器的顺序,你可以确保全局逻辑按照预期的顺序执行,从而更好地管理和控制请求和响应的处理流程。

过滤器的执行顺序

  1. 每一个全局过滤器都必须指定一个int类型的order值,order值越小,优先级越高,执行顺序越靠前。

  2. GlobalFilter通过实现Ordered接口,或者添加@Order注解来指定order值,由我们自己指定

  3. 路由过滤器和defaultFilter的order由Spring指定默认是按照声明顺序从1递增,也就是在application.yml文件里面的顺序

  4. 当过滤器的order值一样时,会按照 defaultFilter > 路由过滤器 > GlobalFilter的顺序执行

和网关Zuul的对比

  1. Zuul网关不支持长连接,但是Gateway支持
  2. Gateway适用于大流量、高并发的情景,在中小流量的情景里面用Zuul网关会更合适一些
  3. Gateway网关里面内置限流过滤器(可以再application.yml文件里面进行配置)

实现Gateway和Nacos的结合

给每一个要注册的微服务添加这个Nacos的相关的配置,然后还要给内网关Gateway所在的微服务里面的application.yml配置文件添加Gateway的相关属性

  • 6
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值