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

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

时间:2024-06-14 22:58:15浏览次数:12  
标签:网关 spring springframework gateway 路由 详细 org Gateway cloud

资料的连接

官方文档

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的相关属性

标签:网关,spring,springframework,gateway,路由,详细,org,Gateway,cloud
From: https://blog.csdn.net/m0_73500407/article/details/139691513

相关文章

  • 基于SpringBoot+Vue+uniapp微信小程序的垃圾分类系统的详细设计和实现(源码+lw+部署文
    文章目录前言详细视频演示项目运行截图技术框架后端采用SpringBoot框架前端框架Vue可行性分析系统测试系统测试的目的系统功能测试数据库表设计代码参考数据库脚本为什么选择我?获取源码前言......
  • Modbus转Profinet网关连接ABB变频器Modbus通讯调试
    一、前景:在工业自动化领域,Modbus协议和Profinet协议是两种常见的通讯协议,而ABB变频器作为一种常用的变频控制设备,其通讯调试对于系统稳定运行至关重要。二、优势:Modbus协议转Profinet协议网关能够实现不同协议之间的无缝对接和通信,为工业自动化系统的互联提供了便利。通过网关的......
  • ncverilog与finesim联合进行混合仿真的详细过程(以spice为顶层)
    第一步:Makefile仿真命令one:ncverilog+access+rwc+nc64bit+loadvpi=finesim.so:finesim_startup-frun.f第二步:环境结构(1)以模拟为顶层,顾名思义是把CDL网表中某一个模块替换为数字的function,其余全是CDL,以上图为例,把其中inv替换为数字的function。(2)需要文件:testben......
  • shell编程-sed命令详解(超详细)
    目录前言一、sed命令介绍1.sed命令简介2.sed命令的基本语法3.常用的sed命令选项4.常用的sed编辑命令二、sed命令示例用法1.替换文本2.删除匹配行3.打印特定行4.在指定行之前插入文本5.从文件中读取编辑命令6.使用sed命令在core-site.xml文件中的<configuration>标签之前......
  • 实用软件下载:MathType最新安装包及详细安装教程
    ​MathType是一款数学公式编辑器,用于创建和编辑数学表达式、方程式和符号。它提供了直观的界面和丰富的工具,使用户能够以专业水平轻松地生成高质量的数学公式。MathType支持各种常见的数学符号和结构,包括上下标、分数、根号、积分、矩阵等等,并且可以与许多流行的文字处理软件(如......
  • iMazing3软件:超级详细安装步骤(最新版软件下载)
    简介:iMazing功能强大且软件界面友好,方便用户使用。它是Mac和PC上最好用的iOS设备管理器,可以安全备份任何iPhone,iPad或iPodtouch。iMazing拥有数据备份、文件传输、数据管理等强大功能。另外,用户可以自由地使用USB数据线、Wi-Fi等方式来进行iMazing与苹果设备的连接,而无需局......
  • 【Py/Java/C++三种语言OD独家2024D卷真题】20天拿下华为OD笔试之【贪心/脑筋急转弯】2
    有LeetCode算法/华为OD考试扣扣交流群可加948025485可上全网独家的欧弟OJ系统练习华子OD、大厂真题绿色聊天软件戳od1441了解算法冲刺训练(备注【CSDN】否则不通过)文章目录题目描述与示例题目描述输入描述输出描述示例一输入输出说明示例二输入输出说明示例三......
  • 【Py/Java/C++三种语言OD独家2024D卷真题】20天拿下华为OD笔试之【二分查找】2024D-部
    有LeetCode算法/华为OD考试扣扣交流群可加948025485可上全网独家的欧弟OJ系统练习华子OD、大厂真题绿色聊天软件戳od1441了解算法冲刺训练(备注【CSDN】否则不通过)文章目录题目描述与示例题目描述输入描述输出描述示例输入输出说明解题思路代码pythonjavacpp时......
  • 【Py/Java/C++三种语言OD独家2024D卷真题】20天拿下华为OD笔试之【DFS】2024D-计算三
    有LeetCode算法/华为OD考试扣扣交流群可加948025485可上全网独家的欧弟OJ系统练习华子OD、大厂真题绿色聊天软件戳od1441了解算法冲刺训练(备注【CSDN】否则不通过)文章目录题目描述与示例题目描述:输入描述输出描述示例一输入输出说明示例二输入输出说明示例三......
  • 实用软件下载:硕思LOGO设计师最新安装包及详细安装教程
    ​硕思Logo设计师是一款操作灵活简单,且功能强大的logo制作软件,它可以通过简单的点击就可以为网站、博客、论坛和邮件创建专业的logo、条幅、按钮、标题、图标和签名等。 该软件提供了很多精心设计的模板和丰富的资源,为更好的创建logo艺术作品,用户可以导入图片并将SWF电影反编......