Spring Cloud Gateway 的路由和断言是什么关系?

发布于:2025-07-13 ⋅ 阅读:(15) ⋅ 点赞:(0)

1. 基本概念

路由是 Spring Cloud Gateway 的基本组成单元。它定义了从客户端接收到的请求应该被转发到哪个目标服务。一个完整的路由通常包含以下几个要素:

  • ID (id):路由的唯一标识符。
  • 目标 URI (uri):请求最终要被转发到的后端服务地址。
  • 断言集合 (predicates):一个或多个断言的集合,用于匹配传入的请求。
  • 过滤器集合 (filters):一个或多个过滤器集合,用于在请求转发前后对请求或响应进行修改。

简单来说,路由就是一条规则,告诉网关:“如果请求满足某些条件(断言),就把它发到这个地方(URI),并在发送前后做一些处理(过滤器)。”

断言就是 判断传入的请求是否满足路由规则中定义的条件。只有当一个路由中的所有断言都评估为 true 时,该路由才会被匹配成功。

# 路由配置
spring:
  cloud:
    gateway:
      routes:
      - id: user-service                    # 路由ID
        uri: http://localhost:8081          # 目标URI
        predicates:                         # 断言集合(匹配条件)
        - Path=/user/**                     # 路径断言
        - Method=GET                        # 方法断言
        - Header=X-Request-Id, \d+          # 请求头断言
        filters:                            # 过滤器集合
        - StripPrefix=1

2. 工作流程

客户端请求进入Gateway
获取所有已配置的路由
遍历路由列表
是否还有未检查的路由?
获取当前路由的断言集合
返回404 Not Found
当前路由的所有断言是否匹配?
选择该路由
应用Pre过滤器
转发请求到目标服务
目标服务处理并返回响应
应用Post过滤器
返回响应给客户端

3. 常用断言类型

Spring Cloud Gateway 提供了许多内置的断言工厂,可以根据请求的不同属性进行匹配,

predicates:
# 路径匹配
  # Path 断言:根据请求路径匹配,例如 /users/**。
  - Path=/api/user/{id}
# 时间相关
  # After/Before/Between 断言:根据请求到达时间匹配。
  - After=2023-01-01T00:00:00+08:00
  - Before=2023-12-31T23:59:59+08:00
  - Between=2023-01-01T00:00:00+08:00,2023-12-31T23:59:59+08:00
# HTTP相关
  # Method 断言:根据 HTTP 请求方法匹配,例如 GET, POST。
  - Method=GET,POST
  # Header 断言:根据请求头信息匹配,例如 Host=example.com。
  - Header=X-Request-Id, \d+
  # Query 断言:根据查询参数匹配,例如 param=value。
  - Query=name, jack
  # Cookie 断言:根据 Cookie 信息匹配。
  - Cookie=session, abc
# 网络相关
  # Host 断言:根据请求的主机名匹配。
  - Host=**.example.com
  # RemoteAddr 断言:根据客户端 IP 地址匹配。
  - RemoteAddr=192.168.1.0/24

4. 自定义断言

@Component
public class CustomRoutePredicateFactory 
    extends AbstractRoutePredicateFactory<CustomRoutePredicateFactory.Config> {
    
    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
        return exchange -> {
            // 自定义匹配逻辑
            return exchange.getRequest()
                          .getHeaders()
                          .getFirst("Custom-Header")
                          .equals(config.getValue());
        };
    }
    
    @Data
    public static class Config {
        private String value;
    }
}

网站公告

今日签到

点亮在社区的每一天
去签到