网关限流和服务内限流应该怎么选?
简化版
网关限流适合做入口层的粗粒度保护,比如按用户、IP、App、接口、租户限制请求量,挡住明显异常流量,避免流量直接打到内部服务。服务内限流适合做业务维度和资源维度的精细保护,比如按核心方法、下游依赖、数据库连接、线程池、库存 Key 限制并发或 QPS。
面试中可以这样回答:网关限流负责“挡在门口”,服务内限流负责“保护具体房间”。真实系统通常两者都要有:入口层先削峰和防滥用,服务内部再根据业务资源承载能力做兜底保护。
详细版
网关限流的优势是位置靠前、统一接入、规则集中,能在请求进入微服务集群之前就拦截一部分流量。它常用于开放 API、移动端接口、BFF、租户隔离、黑灰产防刷等场景。它的问题是离业务细节较远,通常不知道某个请求最终会打到哪个数据库分片、哪个热点商品、哪个下游接口,因此不能完全替代服务内限流。
服务内限流的优势是贴近业务和资源,可以根据接口内部的真实压力做控制。例如一个服务的总 QPS 不高,但其中某个查询会访问慢 SQL,或者某个下游依赖容量很小,这时只能在服务内部做更准确的保护。服务内限流的问题是规则分散、治理成本更高,而且如果入口层完全不控流,异常流量仍然会消耗网关到服务之间的网络、连接和线程资源。
工程上常用分层策略:网关做全局入口限流,服务做局部精细限流,下游客户端再做熔断、超时、重试和并发隔离。这样可以把风险拆开:恶意和突发流量先在入口拦住,业务热点由服务内部保护,下游故障由调用方隔离。
完整版教学
一、先明确两种限流的位置不同
网关限流发生在请求进入系统的第一道或前几道入口上,例如 Nginx、Envoy、Spring Cloud Gateway、Kong、APISIX、云厂商 API Gateway 等。它面对的是外部请求,目标是保护整个后端系统的入口容量。
服务内限流发生在业务服务进程内部,例如 Java 服务中的过滤器、拦截器、AOP、Sentinel 资源点、Guava RateLimiter、本地并发信号量等。它面对的是已经进入服务的请求,目标是保护某个服务、接口、方法、资源或下游依赖。
因此,两者不是竞争关系,而是防线关系:网关是外围防线,服务内限流是内部防线。
二、网关限流适合解决什么问题
网关限流最适合做统一、粗粒度、跨服务的入口控制。常见场景包括:
- 按用户限流:普通用户每分钟最多请求多少次,VIP 用户额度更高。
- 按 IP 限流:限制单个 IP 的请求频率,防止爬虫、扫描、暴力攻击。
- 按 AppKey 或租户限流:保护多租户系统中的公平性,避免一个租户吃掉全部容量。
- 按接口限流:例如登录、短信验证码、搜索、下单接口分别设置不同阈值。
- 按地域或渠道限流:在活动期间对不同入口做流量分配。
网关的最大价值是“早拒绝”。请求越早被拒绝,浪费的系统资源越少。如果一个明显超额的请求被挡在网关,后面的应用线程、连接池、缓存、数据库都不会被占用。
三、服务内限流适合解决什么问题
服务内限流适合处理网关看不清的细节。例如:
- 某个接口内部调用了三个下游服务,其中一个下游只能承受 200 QPS。
- 某个查询接口大部分请求很轻,但带某些条件时会触发复杂聚合。
- 某个商品、用户、订单形成热点 Key,整体接口 QPS 不高但单个 Key 压力很大。
- 某个方法需要占用昂贵资源,比如大对象解析、文件导出、批量写入。
- 某个服务实例资源紧张,需要按实例状态动态控制并发。
这些场景如果只靠网关限流,很容易出现阈值设得过粗的问题。阈值高了挡不住热点,阈值低了又误伤正常流量。服务内限流能基于业务上下文做更准确的判断。
四、为什么真实系统通常需要分层限流
单层限流很容易有盲区。只有网关限流时,内部服务之间的调用、异步消费、定时任务、批处理流量可能完全绕过网关。只有服务内限流时,异常流量已经进入内网,会消耗连接、线程、序列化和路由资源。
更稳妥的架构是分层:
用户/客户端
↓
CDN / WAF / 负载均衡:抗攻击、基础防护
↓
API 网关:用户、IP、租户、接口级限流
↓
业务服务:方法、资源、热点参数、下游依赖限流
↓
缓存 / MQ / 数据库:连接池、队列、写入速率保护
每一层都不需要解决所有问题,只要承担自己最适合承担的那部分。这样系统不会把所有希望压在一个限流点上。
五、两者的典型权衡
面试中可以从几个维度比较:
| 维度 | 网关限流 | 服务内限流 |
|---|---|---|
| 位置 | 系统入口 | 服务内部 |
| 粒度 | 用户、IP、接口、租户 | 方法、资源、热点 Key、下游依赖 |
| 优点 | 统一、靠前、治理集中 | 精准、贴近业务、能保护具体资源 |
| 缺点 | 不了解内部业务细节 | 规则分散、治理复杂 |
| 典型目标 | 防滥用、削峰、入口保护 | 防过载、热点保护、依赖隔离 |
一个比较成熟的回答不是简单说“用网关”或“用服务内”,而是说明为什么要组合使用,以及每一层应该承担什么责任。
六、设计规则时要避免重复和冲突
分层限流容易出现一个问题:多个地方都限流,但规则互相打架。例如网关设置接口 1000 QPS,服务内设置 300 QPS,调用方看到大量 429 或业务失败,却不知道是哪一层拒绝的。
工程上要做好三件事:
- 规则命名清晰:区分
gateway.user.login.qps、service.order.create.concurrent这类资源名。 - 拒绝原因可观测:返回码、错误码、日志、指标要能看出是哪一层触发限流。
- 阈值有层次:入口层通常按总容量和公平性设置,服务内部按真实资源瓶颈设置。
如果系统支持动态规则,还要有灰度发布和回滚能力。限流规则配错可能直接造成大面积误拒绝,所以它和代码变更一样需要谨慎发布。
七、面试回答可以按防线组织
比较好的面试回答结构是:
- 先说结论:网关限流和服务内限流不是二选一,通常组合使用。
- 再说职责:网关做入口级、公平性和防滥用;服务内部做业务资源级保护。
- 接着举例:短信验证码适合网关按用户/IP 限流;库存扣减、下游支付调用适合服务内部限流。
- 最后补充工程点:动态规则、监控告警、拒绝码、降级兜底、灰度发布。
这样回答既有原则,又有落地细节,比只背概念更像真实做过系统。
八、常见误区与追问
这道题要紧扣「网关限流与服务限流」本身回答,不能把它混成泛泛的流量控制套话。面试官通常不是只听定义,而是看你能不能把适用场景、关键流程、失败边界和工程取舍串起来,尤其要说明限流位置、算法窗口、阈值来源、拒绝策略、退避降级和观测指标。
| 回答层次 | 要讲清的内容 | 容易漏掉的边界 |
|---|---|---|
| 核心结论 | 网关限流适合入口统一保护,服务限流适合按业务资源精细保护,两者经常配合使用 | 不要停在名词解释 |
| 流程机制 | 请求进入网关 -> 执行用户和 API 维度限流 -> 转发到服务 -> 服务按资源再限流 -> 触发降级或排队 -> 统一记录指标 | 要说清触发点、状态变化、确认点和失败兜底 |
| 工程取舍 | 网关给订单 API 限 5000 QPS,订单服务内部还要对创建订单、查库存等不同资源分别限流 | 限流保护系统稳定性,但会牺牲一部分请求成功率或响应实时性 |
网关限流与服务限流 面试拆解:
1. 请求进入网关
2. 执行用户和 API 维度限流
3. 转发到服务
4. 服务按资源再限流
5. 触发降级或排队
6. 统一记录指标
记忆钩子:先给结论,再拆流程,再讲数字例子和失败边界;回答「网关限流与服务限流」时要围绕题目问法收束,不要把相邻概念堆成一段没有重点的名词清单。
- 误区:限流就是简单拒绝请求。 合格答案要区分放行、排队、快速失败、降级、退避和熔断,而不是只说“挡住流量”。
- 误区:全局平均流量低就没有风险。 热点 key、单实例、单下游资源仍可能先被打满,所以要看局部水位。
- 误区:限流阈值可以拍脑袋配置。 阈值要来自压测容量、依赖水位、错误率、P99 延迟和业务优先级。
- 追问:限流应该放在哪里? 入口网关、服务内部、客户端和下游资源侧可以分层配置,分别保护不同边界。
- 追问:触发限流后怎么处理? 核心写请求可排队,非核心读请求可降级,用户侧要给明确失败或稍后重试。
- 追问:如何验证流控策略有效? 看 QPS、并发、延迟、拒绝率、队列长度、下游错误率和恢复时间。
九、加强记忆
可以把网关限流记成“门口保安”,负责看谁进来、进来多少、是否明显异常。把服务内限流记成“房间限员”,负责保护具体会议室、电梯、设备和工作人员。
如果面试官问“应该在哪一层限流”,优先回答:入口层先挡粗流量,服务层再保护细资源;核心链路一般两层都需要,只是限流维度和阈值不同。