4. Spring Cloud Gateway 入门:核心概念与快速搭建

好,咱们正式开始聊网关。说实话,我在做量化平台之前,对网关的理解也就停留在「反向代理」这个层面。直到有一次,我们的交易信号推送服务因为流量突增直接被打挂,我才意识到——网关这东西,在量化系统里简直就是命门。

今天这一章,我带大家快速入门 Spring Cloud Gateway。咱们不讲虚的,直接上干货。

4.1 核心概念:Route、Predicate、Filter

Spring Cloud Gateway 的核心就三个东西:路由(Route)断言(Predicate)过滤器(Filter)。你想想看,一个请求进来,网关要决定「去哪」、「能不能去」、「去了之后怎么处理」——这三个概念正好对应这三个问题。

4.1.1 Route(路由)

路由是网关的基本构建块。它由 ID、目标 URI、断言集合和过滤器集合组成。说白了,就是一条规则:如果满足某些条件,就把请求转发到某个地址

我在项目中习惯把路由配置放在 YAML 文件里,这样运维同学也能看懂。当然,你也可以用 Java DSL 来写,看团队习惯。

spring:
  cloud:
    gateway:
      routes:
        - id: quant-trade-route
          uri: lb://quant-trade-service
          predicates:
            - Path=/api/trade/**
          filters:
            - StripPrefix=1

这段配置的意思是:所有以 /api/trade/ 开头的请求,都转发到 quant-trade-service 这个微服务。嗯,这里要注意,lb:// 表示使用负载均衡。

4.1.2 Predicate(断言)

断言就是条件判断。Spring Cloud Gateway 内置了很多实用的断言工厂,比如:

  • Path:匹配请求路径
  • Method:匹配 HTTP 方法(GET、POST 等)
  • Header:匹配请求头
  • Query:匹配查询参数
  • Cookie:匹配 Cookie
  • After/Before/Between:匹配时间范围

举个例子,在量化平台里,我们经常需要根据请求头中的 X-Client-Type 来区分不同客户端:

predicates:
  - Header=X-Client-Type, quant-trader

我曾经踩过一个坑:断言是「与」的关系,不是「或」。也就是说,如果你写了多个断言,必须全部满足才会匹配。这个细节很容易被忽略,尤其是在配置复杂路由的时候。

4.1.3 Filter(过滤器)

过滤器可以对请求和响应进行修改。Spring Cloud Gateway 的过滤器分为两种:

  • Pre 过滤器:在请求被转发之前执行
  • Post 过滤器:在响应返回给客户端之前执行

常用的内置过滤器有:

过滤器名称 作用 我在量化平台中的用法
StripPrefix 去掉路径前缀 去掉 /api 前缀再转发
AddRequestHeader 添加请求头 注入用户身份信息
RateLimiter 限流 防止高频交易请求打垮后端
Retry 重试 网络抖动时自动重试
CircuitBreaker 熔断 保护下游服务
我的习惯:在量化平台里,我一般会在网关层统一做鉴权和限流。这样后端服务就不用重复实现了,清爽很多。

4.2 快速搭建第一个网关

好,概念讲完了,咱们动手搭一个。我保证,这是你见过最简单的网关搭建过程。

4.2.1 创建项目

用 Spring Initializr 创建一个项目,依赖选上:

  • Spring WebFlux(注意,不是 Spring Web MVC)
  • Spring Cloud Gateway
  • (可选)Eureka Discovery Client

为什么用 WebFlux?因为 Gateway 底层是基于 Reactor 的响应式编程模型。说白了,就是异步非阻塞,性能更好。我第一次用的时候还不太习惯,但用顺手之后,真香。

4.2.2 配置路由

application.yml 里写一个最简单的路由:

server:
  port: 8080

spring:
  cloud:
    gateway:
      routes:
        - id: baidu-route
          uri: https://www.baidu.com
          predicates:
            - Path=/baidu/**
          filters:
            - StripPrefix=1

这个配置的意思是:访问 http://localhost:8080/baidu/s,网关会把请求转发到 https://www.baidu.com/s

4.2.3 启动测试

启动项目,打开浏览器访问 http://localhost:8080/baidu/s?wd=spring+cloud+gateway。如果看到百度搜索结果页面,恭喜你,第一个网关搭建成功了。

注意:如果你用的是 Spring Cloud 2020.0.x 之后的版本,记得加上 spring.cloud.gateway.routes[0].filters[0].name=StripPrefix 的完整写法。我刚开始升级版本时就因为这个折腾了半天。

4.3 本章知识体系

为了让你更直观地理解 Spring Cloud Gateway 的工作流程,我画了一张图:

客户端 Spring Cloud Gateway Predicate Filter Route 后端 微服务 集群 工作流程: 客户端请求 → Predicate 匹配条件 → Filter 处理请求 → Route 转发到后端服务 → Filter 处理响应 → 返回客户端

这张图把整个流程串起来了。你想想看,客户端发一个请求,网关先拿 Predicate 去匹配,匹配上了就经过 Filter 链处理,最后通过 Route 转发到后端。响应回来的时候,再走一遍 Filter 链(不过是反向的)。

4.4 避坑指南

最后,分享几个我实际项目中踩过的坑:

  • 路由顺序很重要:Spring Cloud Gateway 按配置顺序匹配路由,一旦匹配成功就不再继续。所以精确的路由要放在前面,模糊的放后面。
  • 不要用 @SpringBootApplication 扫描所有包:Gateway 和普通 Web 项目不一样,扫描范围太大会导致冲突。我建议单独建一个 gateway 模块。
  • 调试时开启日志:在配置里加上 logging.level.org.springframework.cloud.gateway=DEBUG,能看到每个请求的匹配过程和过滤链执行情况,排查问题利器。

总结一下:Route 是路由规则,Predicate 是匹配条件,Filter 是处理逻辑。这三个概念搞清楚了,Spring Cloud Gateway 你就掌握了 80%。剩下的就是多写多练,遇到问题看日志。


公众号:蓝海资料掘金营,微信deep3321