2684 字
13 分钟
数据库流量过大:Spring Cloud Gateway 入口限流方案

方案一:Spring Cloud Gateway 限流#

1. 适用场景#

适用于基于 Spring Cloud 的微服务项目,尤其是多个业务服务共用一个入口、数据库查询压力较大的场景。

例如,商品查询、订单列表、报表查询等接口都需要访问数据库。当活动期间请求量突然增加时,如果所有请求都直接进入业务服务,可能导致数据库连接池耗尽、查询响应变慢,甚至影响其他正常业务。

因此,可以在网关层增加限流机制,在请求进入业务服务之前拦截超出阈值的流量,减少无效请求对下游服务和数据库的冲击。

需要注意,网关限流只能控制进入系统的请求量,不能直接保证数据库一定安全,还需要结合数据库连接池、慢查询治理和业务服务内部的并发控制。

2. 整体工程流程#

客户端请求 → Spring Cloud Gateway → 路由匹配 → Redis 限流检查 → 放行或拒绝 → 业务服务 → 数据库。

具体执行过程如下:

  1. 客户端请求首先进入 Gateway,网关根据请求路径匹配对应的路由规则。
  2. 匹配路由后,执行该路由配置的限流过滤器。
  3. Gateway 根据请求中的用户身份或接口标识生成限流 Key,并通过 Redis 限流器判断当前请求是否允许通过。
  4. 如果允许通过,网关将请求转发到对应的业务服务,由业务服务执行查询或其他业务逻辑。
  5. 如果超过限流阈值,网关直接拒绝请求,返回 HTTP 429,不再将该请求转发给业务服务。
  6. 记录请求总量、拒绝数量、响应时间等指标,结合数据库监控判断限流策略是否达到预期效果。

3. 具体实施步骤#

第一步:梳理接口并制定限流规则#

首先统计需要保护的接口,区分普通查询、核心业务和高成本查询,而不是给所有接口配置同一个限流阈值。

例如:

接口类型限流维度示例规则设计目的
普通商品查询接口全局每秒补充 200 个令牌控制整体请求量
用户查询接口用户维度每个用户每秒补充 10 个令牌防止单个用户频繁请求
复杂报表查询接口全局每秒补充 20 个令牌限制高成本数据库查询
核心下单接口用户及接口维度根据业务容量单独配置避免影响核心业务

这里的数值只是初始示例,不应直接作为生产配置。

实际确定阈值时,需要先通过压测测出接口的吞吐量、平均响应时间、P95/P99 延迟,以及数据库连接池的使用情况,再根据数据库可承受的负载设置安全阈值,并预留一定余量。

同时要明确两个概念:

  • 用户级限流:限制单个用户的请求频率,避免少数用户占用过多资源。
  • 接口级全局限流:限制所有用户访问某个接口的总请求量,直接控制进入下游的流量规模。

两种规则可以同时使用。仅设置用户级限流,无法防止大量用户同时请求导致数据库过载。

第二步:接入 Gateway 和 Redis 限流器#

在 Spring Cloud Gateway 中使用 RequestRateLimiter 过滤器,并通过 RedisRateLimiter 实现基于 Redis 的分布式令牌桶限流。

主要涉及三个部分:

  1. KeyResolver:确定限流对象。

    例如,从经过认证的请求中获取用户 ID,以 user:10001 作为限流 Key。对于接口全局限流,则使用固定的接口标识作为 Key,例如 api:product:list。

    这里不能简单地信任客户端自行传入的用户 ID,否则用户可以通过修改请求参数绕过限制。用户维度的 Key 应基于服务端验证过的身份信息生成。

  2. RedisRateLimiter:配置令牌桶。

    主要配置两个参数:

    • replenishRate:每秒补充的令牌数量。
    • burstCapacity:令牌桶的最大容量,决定允许的突发流量。

    例如,设置 replenishRate=200、burstCapacity=400,表示令牌以每秒 200 个的速度补充,桶最多容纳 400 个令牌。桶中有足够令牌时,请求可以通过;令牌不足时,请求被拒绝。

    这意味着限流并非简单地在每个自然秒内严格放行 200 次,而是允许在桶容量范围内出现突发流量。

  3. RequestRateLimiter:在路由转发前执行检查。

    将限流过滤器配置到指定路由。只有通过限流检查的请求才会继续转发到业务服务。

    使用 Redis 的好处是,多台 Gateway 实例可以共享限流状态,避免每台网关单独计数而导致整体限额失控。但 Redis 的可用性、网络延迟和访问开销也需要纳入考虑。

第三步:配置路由和限流策略#

以商品查询接口为例,将 /api/products/** 路由到商品服务,并配置对应的限流规则。

工程上需要完成以下配置:

  • 配置商品服务的路由地址或服务发现名称。
  • 为商品查询路由绑定限流过滤器。
  • 指定限流 Key 的生成方式。
  • 配置令牌桶的补充速率和突发容量。
  • 配置 Redis 连接信息。
  • 为限流拒绝请求统一设置 HTTP 429 和业务错误码。

如果使用 Nacos 进行服务发现,路由也可以指向注册的服务名称,而不必将某台业务服务器的 IP 写死在配置中。

生产环境还需要考虑 Redis 故障时的处理策略。不能未经评估就默认放行所有请求,否则 Redis 不可用时,限流保护可能失效;也不能不加区分地拒绝所有请求,否则可能导致整个业务不可用。应根据接口重要性制定故障策略,并通过监控和告警及时发现问题。

第四步:处理超限请求和异常情况#

限流不仅要能拒绝请求,还要让客户端得到明确反馈。

  • 正常请求:继续转发到业务服务。
  • 超出限额:返回 HTTP 429,并提供统一的错误码和提示信息。
  • 客户端重试:对于允许重试的查询请求,可以结合退避策略,避免所有客户端同时重试造成流量再次集中。
  • 核心业务请求:不能仅依靠网关限流,还要考虑业务幂等、事务处理和失败补偿等机制。
  • Redis 异常:根据业务风险选择受控放行或拒绝策略,并对异常状态进行告警。

对于复杂报表等高成本接口,还可以单独设置更严格的限流规则,必要时配合请求排队、异步任务或查询结果缓存,避免少量高成本请求占满数据库资源。

第五步:压测验证与持续调优#

限流配置完成后,需要验证它是否真正保护了下游服务,而不只是观察网关是否返回了 429。

具体可以分为三组测试:

  1. 正常流量测试:在预期流量下检查接口响应时间、错误率和数据库连接池占用,确认限流不会明显影响正常用户。
  2. 超限测试:逐步提高并发和请求速率,观察 Gateway 的放行量、拒绝量及业务服务实际收到的请求量。
  3. 异常测试:模拟 Redis 暂时不可用、业务服务响应变慢等情况,验证系统是否按照预定策略处理。

重点观察以下指标:

  • 网关请求总量、放行量和限流拒绝量。
  • 接口平均响应时间以及 P95/P99 延迟。
  • 业务服务 CPU、线程池和请求队列情况。
  • 数据库 QPS、慢查询数量、连接池活跃连接数及等待情况。
  • Redis 响应延迟、错误率和可用性。

如果限流后网关拒绝量增加,但数据库连接池占用和查询延迟没有明显下降,就需要进一步检查是否存在其他流量入口、后台任务或慢 SQL 等问题。

最后根据压测结果调整令牌补充速率、桶容量和接口规则,并在上线后持续观察,避免限流过严影响正常业务。

4. 优缺点#

优点:

  • 在请求进入业务服务之前进行拦截,减少超限请求对下游服务和数据库的冲击。
  • 可以集中管理多个微服务的入口流量,避免每个业务服务重复实现入口限流。
  • 支持结合用户、接口等维度设计规则。
  • 配合 Redis 可以在多台网关实例之间共享限流状态。

缺点:

  • 需要部署和维护 Gateway、Redis,并处理相应的高可用和故障问题。
  • 网关限流无法识别所有数据库内部的资源消耗,复杂 SQL、后台任务等仍需要单独治理。
  • Redis 会引入额外的网络访问开销,其异常处理策略需要谨慎设计。
  • 令牌桶允许一定程度的突发流量,不能将其简单理解为严格的固定时间窗口计数。
  • 如果所有流量都经过同一网关,网关自身也需要进行容量规划和高可用设计。

5. 方案总结#

Spring Cloud Gateway 限流主要解决的是入口流量控制问题。工程落地时,需要先梳理接口和数据库承载能力,再通过 RequestRateLimiter、RedisRateLimiter 和 KeyResolver 配置限流规则,最后通过压测和线上监控持续调优。

对于数据库保护场景,推荐同时设置用户级限流和接口级全局限流,并结合连接池、慢 SQL 治理和数据库并发控制,形成从入口到数据库的多层保护机制。

相关文章#

数据库流量过大:Spring Cloud Gateway 入口限流方案
https://blog.xqcherry.top/posts/interview/scenarios/spring-cloud-gateway-rate-limiting/
作者
xqcherry
发布于
2026-10-23
许可协议
CC BY-NC-SA 4.0