Spring Cloud Gateway 的三大核心概念:Route(路由)、Predicate(断言)和 Filter(过滤器)
Spring Cloud Gateway 是 Spring 官方推出的第二代微服务网关,旨在替代早期的 Zuul。它基于 Spring 5.0、Spring Boot 2.0 和 Project Reactor 构建,具有响应式、非阻塞的特性。
要完全掌握 Spring Cloud Gateway,最核心的就是理解它的三大基石:Route(路由)、Predicate(断言) 和 Filter(过滤器)。
为了方便记忆,你可以用现实生活中的高铁乘车来类比:
- Route(路由):一张完整的高铁票(包含车次、目的地、检票口、安检要求)。
- Predicate(断言):检票机(判断你是不是这趟车、时间对不对、票是真的还是假的)。
- Filter(过滤器):安检员和乘务员(在进站时检查行李、出站时核验身份,或者在你的票上盖个章)。
1. Route(路由)—— “去哪里”
路由是网关中最基础的构建单元。 它定义了一个请求应该被转发到哪个后端服务。
一个完整的路由包含以下几个部分:
- id:路由的唯一标识符(不能重复)。
- uri:目标服务地址(请求最终要转发到的目的地,支持
http://、https://或配合注册中心的lb://)。 - predicates:断言集合(判断是否走这个路由的条件)。
- filters:过滤器集合(对请求或响应进行拦截和修改)。
一句话总结:路由就是一个配置好的“转发规则”,只要请求满足了条件,就按照这个规则转发。
2. Predicate(断言)—— “能不能去”
断言是路由的匹配条件。 它的概念来源于 Java 8 的 java.util.function.Predicate。
当一个外部请求到达网关时,网关会遍历所有的路由规则,使用断言去检查这个请求。只有当断言结果为 true 时,请求才会被路由到对应的 uri。
Spring Cloud Gateway 内置了非常多常用的断言工厂(Route Predicate Factories),可以基于 HTTP 请求的各个属性进行匹配:
- Path:根据请求路径匹配(最常用,如
/api/user/)。 - Method:根据 HTTP 方法匹配(如
GET,POST)。 - Header:根据请求头匹配(如请求头必须包含
X-Request-Id)。 - Query:根据请求参数匹配(如 URL 中必须携带
token参数)。 - Cookie:根据 Cookie 匹配。
- After/Before/Between:根据时间匹配(比如只允许某段时间内访问,常用于秒杀)。
一句话总结:断言就是一系列的 If 判断条件,决定了当前请求是否符合该路由的规则。
3. Filter(过滤器)—— “路上做什么”
过滤器用于拦截和修改请求(Request)和响应(Response)。
如果断言(Predicate)匹配成功,网关会将请求交给过滤器链(Filter Chain)处理。过滤器可以在请求到达后端服务之前(Pre)或者后端服务返回响应之后(Post)执行特定的业务逻辑。
过滤器的生命周期:
- Pre(前置):在请求被转发到微服务之前执行。常用于:参数校验、权限认证、限流、添加请求头、修改请求体等。
- Post(后置):在微服务处理完请求,响应返回给客户端之前执行。常用于:修改响应状态码、添加响应头、日志记录等。
过滤器的作用范围分类:
- GatewayFilter(局部过滤器):应用在单个指定的路由上。
- 内置示例:
StripPrefix(去除请求路径前缀)、AddRequestHeader(添加请求头)。
- 内置示例:
- GlobalFilter(全局过滤器):应用在所有路由上,不需要在配置文件中专门配置。
- 常用于:全局权限校验(如 JWT 验证)、全局统一日志记录、全局跨域处理等。
一句话总结:过滤器就是在网关转发请求的前后,对请求或响应进行“加工处理”的插件。
综合示例(YAML 配置)
下面是一个完整的 application.yml 配置示例,将三大概念结合在一起:
spring:
cloud:
gateway:
routes:
- id: user_service_route # 【Route】路由ID,唯一
uri: lb://user-service # 【Route】目标地址:lb代表从注册中心获取user-service服务
predicates: # 【Predicate】断言:什么时候走这个路由?
- Path=/api/user/** # 1. 当请求路径以 /api/user/ 开头时
- Method=GET,POST # 2. 且请求方法必须是 GET 或 POST
- Header=X-Request-Id, \d+ # 3. 且请求头必须包含 X-Request-Id,且值为数字
filters: # 【Filter】过滤器:转发前后要做什么处理?
- StripPrefix=1 # 1. 转发前,去掉路径的第1层(例如把 /api/user/1 变成 /user/1)
- AddRequestHeader=X-Test, 123 # 2. 转发前,给请求头加一个 X-Test=123 的键值对
- AddResponseHeader=X-Res, OK # 3. 响应时,给响应头加上 X-Res=OK
工作流程图(三大概念如何协同工作)
- Client(客户端) 发送请求到网关。
- 网关的 Handler Mapping 根据配置的 Predicate(断言) 判断请求匹配哪个 Route(路由)。
- 如果匹配成功,请求会被发送到 Web Handler。
- Web Handler 执行该路由对应的 Filter(过滤器)链。
- Pre Filter 逻辑 执行(比如鉴权、改路径)。
- 请求最终被转发到 URI(目标微服务)。
- 微服务处理完毕,返回响应。
- 返回的响应再次经过 Filter(过滤器)链。
- Post Filter 逻辑 执行(比如改响应头、记录耗时日志)。
- 最后将响应返回给 Client(客户端)。