spring cloud gateway内置路由断言工厂

简介

在spring cloud gateway中有支持以服务名为开头的默认路由规则,但是在实际生产中的路由规则可能更复杂,需要支持自定义的路由规则定义,包括路径匹配、时间匹配、请求匹配等等,以下是spring cloud gateway内置的路由断言工厂及一般用法

内置断言工厂

spring cloud gateway内置的路由断言工厂在使用的使用是通过名称完成映射的,路由断言工厂的命名规则如下:xxxRoutePredicateFactory,所以在使用的时候只需要指定名称即可完成映射使用,比如:PathRoutePredicateFactory,在使用的时候只需要指定Path即可

PathRoutePredicateFactory

请求路径断言工厂,根据请求路径断言是否命中,最常用的断言工厂

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      locator:
        enabled: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**,/sc-consumer/**
          filters:
            - StripPrefix=1

多个路径用逗号隔开即可,对于多个配置路径,只要有一个匹配即命中

AfterRoutePredicateFactory

after断言工厂表示请求只有在xxx时间之后才能通过断言

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**
            - After=2025-12-26T12:00:00+08:00[Asia/Shanghai] #时间过滤器,只允许在指定时间之后的请求
          filters:
            - StripPrefix=1
   

这里的路由配置了两个断言规则,只有2个断言规则均匹配时才能命中

BeforeRoutePredicateFactory

before断言工厂表示请求只有在xxx时间之前才能通过断言

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**
            - Before=2025-12-26T12:00:00+08:00[Asia/Shanghai] #时间过滤器,只允许在指定时间之后的请求
          filters:
            - StripPrefix=1

BetweenRoutePredicateFactory

between断言工厂表示请求只有在xxx1时间和xxx2时间之间才能通过断言

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**
            - Between=2025-12-26T16:00:00+08:00[Asia/Shanghai], 2025-12-26T16:15:00+08:00[Asia/Shanghai]
          filters:
            - StripPrefix=1
   

配置需要2个参数,只有逗号隔开

CookieRoutePredicateFactory

cookie断言工厂表示请求只有携带了某个cookie值满足条件时请求才能通过断言

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**
            - Cookie=need-trace,123456
          filters:
            - StripPrefix=1
   

cookie断言工厂的匹配模式是基于String的matchs方法实现的,实际生产中可能会配置更复杂的匹配正则表达式

HeaderRoutePredicateFactory

header断言工厂表示请求只有携带了某个header且值满足条件时请求才能通过断言

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**
            - Header=need-trace,123456
          filters:
            - StripPrefix=1
   

HostRoutePredicateFactory

host断言工厂表示请求头中的Host的值满足条件时请求才能通过断言

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**
            - Host=192.168.56.*
          filters:
            - StripPrefix=1
   

MethodRoutePredicateFactory

method断言工厂表示用对应的method发起请求时才能通过断言

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**
            - Method=get
          filters:
            - StripPrefix=1
   

QueryRoutePredicateFactory

Query断言工厂表示发起请求的url中必须要携带的请求参数,且参数值匹配正则才能命中

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**
            - Query=userName,zhangsan*
          filters:
            - StripPrefix=1
   

ReadBodyPredicateFactory

在F版中不能通过配置使用,在H版及更高版本中可以通过配置使用,在该路由断言器中,会读取请求内容,缓存到内存中(ServerWebExchange的attributes,其中Key为:cachedRequestBodyObject)。可以通过判断体中的内容,实现更精细化的控制

XML 复制代码
[
  {
    "filters": [
     {
       "name": "StripPrefix",
        "args": {
           "_genkey_0": "1"
         }
      },
      {
        "name": "ModifyRequestBody",
        "args": {
          "inClass": "java.lang.String",
          "outClass": "java.lang.String",
          "rewriteFunction": "#{@testRewriteFunction}"
        }
      },
      {
        "name":"Retry",
         "args":{
            "retries": 3,
            "methods": ["GET", "POST"]
         }
      },
      {
          "name": "ModifyResponseBody",
          "args": {
            "inClass": "java.lang.String",
            "outClass": "java.lang.String",
            "rewriteFunction": "#{@testResponseBodyRewriteFunction}"
          }
       }
    ],
    "id": "test",
    "order": 0,
       "predicates": [
      {
        "args": {
          "pattern": "/sc-c/**"
        },
        "name": "Path"
      },
      {
        "name": "ReadBody",
        "args": {
            "inClass":"java.lang.String",
            "predicate":"#{@bodyPredicate}"
        }
      }
    ],
    "uri": "lb://sc-consumer"
  }
]

也可以在代码里面定义

java 复制代码
@Bean
    public RouteLocator routes(RouteLocatorBuilder builder) {
        return builder.routes().route("test11",r -> r.readBody(String.class,body -> {
                           try {
                               JSONObject entries = JSONUtil.parseObj(body);
                                                             return entries.containsKey("address");
                           } catch (Exception e) {
                               return false;
                           }
                        }).and().path("/sc-c/**")
                        .filters(f -> f.stripPrefix(1)
                                .modifyRequestBody(String.class,String.class,
                                        (exchange,s) -> Mono.just(s + "test"))
                                .retry((retryConfig -> {
                                    retryConfig.setRetries(3);
                                    retryConfig.setMethods(HttpMethod.POST,HttpMethod.GET);
                                    retryConfig.setExceptions(RuntimeException.class);
                                }))
                                .modifyResponseBody(String.class,String.class,(exchange,s) -> {
                                    try {
                                        JSONObject entries = JSONUtil.parseObj(s);
                                        entries.set("appName","yc-music");
                                        return Mono.just(JSONUtil.toJsonStr(entries));
                                             } catch (Exception e) {
                                        return Mono.just(s);
                                    }
                                }))
                        .uri("lb://sc-consumer"))
                .build();

    }
                                   
                           

WeightRoutePredicateFactory

用以指定路由的权重,可以在灰度发布,AB测试时使用,以下是配置使用示例

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**
            - Weight=group1,80
          filters:
            - StripPrefix=1

        - id: sc-service1
          uri: lb://sc-consumer1
          predicates:
            - Path=/sc-c/**
            - Weight=group1,20
          filters:
            - StripPrefix=1

在如上的配置中,sc-consumer1和sc-consumer是同一个服务的不同版本,按照如上的配置就可以实现控制流量的目的

相关推荐
m0_531237171 小时前
C语言-内存函数
c语言·开发语言·算法
迷之程序员1 小时前
llama-cpp-python用法,模型加载gpu踩坑全记录
开发语言·python·llama
yongui478341 小时前
基于C#实现视频文件解封装与媒体流读取方案
开发语言·c#·媒体
froginwe111 小时前
JavaScript、HTML 与 DOM 实例解析
开发语言
摸鱼的春哥1 小时前
春哥的Agent通关秘籍11:本地RAG实战(中上)
前端·javascript·后端
Stewie121381 小时前
企业高性能web服务器——Nginx
服务器·前端·nginx
楼田莉子1 小时前
C++高精度时间库——<chrono>
开发语言·c++·后端·学习·visual studio
亓才孓1 小时前
jdk动态代理和Cglib动态代理的区别,为什么Cglib更适配SpringAOP
java·开发语言
石牌桥网管1 小时前
Go类型断言
开发语言·后端·golang