Skip to content

配置详解 (Configuration)

Spring Cloud Gateway 的配置是由一组 RouteDefinitionLocator 实例驱动的。 以下代码展示了 RouteDefinitionLocator 接口的定义:

RouteDefinitionLocator.java

java
public interface RouteDefinitionLocator {
    Flux<RouteDefinition> getRouteDefinitions();
}

默认情况下,PropertiesRouteDefinitionLocator 使用 Spring Boot 的 @ConfigurationProperties 机制来加载属性(即从 YAML 或 properties 文件中加载)。

之前的配置示例都使用了快捷方式 (Shortcut) 符号,即使用位置参数而不是命名参数。 以下两个示例是等效的(以 SetStatus 过滤器为例):

application.yml

yaml
spring:
  cloud:
    gateway:
      routes:
      - id: setstatus_route
        uri: https://example.org
        filters:
        - name: SetStatus
          args:
            status: 401
      - id: setstatusshortcut_route
        uri: https://example.org
        filters:
        - SetStatus=401

对于网关的某些使用场景,使用配置文件(Properties/YAML)就足够了,但某些生产用例需要从外部源(如数据库)加载配置。 未来的里程碑版本将提供基于 Spring Data Repositories(如 Redis、MongoDB 和 Cassandra)的 RouteDefinitionLocator 实现。

1. RouteDefinition Metrics (路由定义指标)

要启用 RouteDefinition 指标,请添加 spring-boot-starter-actuator 作为项目依赖项。 然后,默认情况下,只要 spring.cloud.gateway.metrics.enabled 属性设置为 true,指标就会可用。 系统会添加一个名为 spring.cloud.gateway.routes.count 的 Gauge(仪表)指标,其值为 RouteDefinition 的数量。 该指标可以通过 /actuator/metrics/spring.cloud.gateway.routes.count 端点获取。

补充教学 —— 进阶:如何实现动态路由?

文档中提到了 RouteDefinitionLocator 是核心,这其实是实现动态路由(Dynamic Routing)的关键入口。

为什么需要动态路由? 默认的 YAML 配置方式在网关启动时就固定了。但在生产环境中,我们经常需要:

  • 新增一个微服务路由,不想重启网关。
  • 临时下线某个路由进行维护。
  • 调整路由的权重或限流策略。

实现原理: Spring Cloud Gateway 会把所有注册的 RouteDefinitionLocator Bean 返回的路由定义合并起来。 因此,你只需要自己实现一个 RouteDefinitionLocator,并在 getRouteDefinitions() 方法中返回你存储在外部(如 Redis、Nacos、MySQL)的路由信息即可。

简单的 Redis 动态路由思路

  1. 存储:设计一个管理后台,把路由配置(JSON 格式)存入 Redis Hash 结构。
  2. 读取:编写一个 RedisRouteDefinitionLocator 实现 RouteDefinitionLocator 接口,从 Redis 读取 JSON 并反序列化为 RouteDefinition 对象。
  3. 刷新:当 Redis 数据变更时,发布一个 RefreshRoutesEvent 事件,通知网关重新加载路由。
java
@Component
public class RedisRouteDefinitionLocator implements RouteDefinitionLocator {
    @Override
    public Flux<RouteDefinition> getRouteDefinitions() {
        // 伪代码:从 Redis 获取所有路由配置
        return redisTemplate.opsForHash().values("gateway_routes")
                .map(json -> parse(json)); 
    }
}

掌握 RouteDefinitionLocator,你就掌握了网关定制化的核心钥匙。

Based on Spring Framework.