面试官:我有一个a服务,现在部署在了三台服务器上面,前端请求a服务,我现在想进行限流,应该怎样做。
面试官问这个问题,是想考察你在分布式系统架构下对限流的理解深度。核心难点在于:服务部署在3台服务器上,限流策略是“各自为政”还是“统一管控”?
这道题没有标准答案,关键在于根据业务需求选择合适的方案。一个高水平的回答应该分层次展开,并明确指出每种方案的优劣。
下面我为你设计一套从基础到进阶的完整回答逻辑:
🎯 第一步:先明确“限流维度”与“限流目标”
在动手实现前,必须先和面试官确认清楚两个问题(这本身就是加分项):
-
限流粒度:是针对总调用量(例如:3台机器加起来每秒最多处理 1000 个请求),还是针对单机(每台机器每秒最多 400 个)?
-
限流对象:是针对全局限流(保护后端数据库),还是针对IP/用户(防止单个用户刷接口)?
通常,架构师会要求 “全局限流”(因为单机限流在扩容缩容时难以维护),但在高并发下,全局限流会有网络开销,需要权衡。
🧩 第二步:给出三种主流实现方案(由浅入深)
方案一:网关层集中式限流(最推荐,架构最清晰)
既然前端请求先打到网关(如 Spring Cloud Gateway 或 Nginx),限流最好在网关层做掉,避免流量打到业务机器内部。
-
实现方式:在网关层集成 Redis + Lua 脚本(令牌桶/滑动窗口)。所有3台机器共享同一个Redis计数器。
-
优点:数据集中,精准控制总量;网关层拦截无效流量,节省业务服务器CPU。
-
缺点:引入Redis依赖,增加一次网络调用,性能略逊于单机限流。
-
面试金句:“如果项目使用了Spring Cloud Alibaba,我会直接使用Gateway整合
RequestRateLimiter过滤器,配合Redis实现全局限流。”
方案二:业务层分布式限流(中间件方案)
如果不想在网关层处理,想在业务层(A服务自身)实现,最主流的是 Sentinel(哨兵)。
-
实现方式:
-
单机限流(降级):在3台机器上各自配置
QPS=300,总的极限是900。但这种方式不精准(如果负载不均,可能一台挂了,总QPS远低于预期)。 -
集群限流(生产推荐):Sentinel 支持 Token Server 模式。选一台机器作为 Token Server,另外两台作为 Token Client。请求到来时,Client 向 Server 请求令牌,Server 统一计算总量(比如限制1000),发放令牌。
-
-
优点:Sentinel 支持熔断、降级、热点参数限流,功能非常强大;集群模式解决了单机误差问题。
-
缺点:引入 Sentinel 集群部署,运维复杂度提升。
方案三:纯本地限流(并发极高,但牺牲精度)
如果业务对性能极其敏感(例如核心交易链路),且不需要精准控制总量,可以直接在每台机器内部使用 Guava 的 RateLimiter 或 Resilience4J。
-
实现方式:每台机器限制 QPS=400,三台理论能扛1200。
-
优点:性能最高(无网络IO,纯内存计算)。
-
致命缺点:如果负载均衡(Nginx)分发不均,或者某台机器重启,实际总限流值会波动。适合非核心、允许误差的场景。
🚀 第三步:进阶方案——自适应限流(体现技术深度)
如果面试官追问:“如果Redis挂了怎么办?限流规则需要动态调整吗?”
这时可以抛出 动态配置 + 自适应限流 的概念:
-
规则动态推送:使用 Nacos/Apollo 作为配置中心。运维可以在控制台动态修改 QPS 阈值(比如从1000改到2000),业务机器通过监听配置实时生效,无需重启。
-
热点参数限流:如果前端请求带了
userId,可以使用 Sentinel 的热点参数限流,防止单个大V用户瞬间流量打垮系统(@SentinelResource注解支持)。 -
兜底策略:当 Redis 或 Token Server 不可用时,自动降级为本地单机限流(Sentinel 支持这种退化策略),保证系统极端情况下的高可用。
💡 第四步:总结与代码化思维(送给面试官的最终回答)
“面试官,针对您提出的A服务部署在三台服务器上的场景,我的架构思路是分层治理:
第一层(网关层):在 Nginx 或 Spring Cloud Gateway 上,利用 Redis + Lua 脚本 实现分布式的滑动窗口限流。这样可以拦截掉 80% 的恶意刷量请求,保护内网带宽。
第二层(业务层):在 A 服务内部接入 Sentinel 的集群限流模式。将其中一台机器设为 Token Server,统一把控全局 QPS 总量,并利用 Nacos 动态调整阈值。
第三层(兜底):配置 Sentinel 的退化策略,如果 Token Server 网络抖动,自动降级为本地
RateLimiter,确保业务可用性高于一切。通过这种网关拦截 + 分布式限流 + 本地兜底的复合策略,既能精准控制流量,又能保证极致性能和最终可用性。”
📊 方案对比速查表(面试可能追问)
| 实现方案 | 精度 | 性能 | 复杂度 | 适用场景 |
|---|---|---|---|---|
| 网关 + Redis | 极高(全局限流) | 中(有网络开销) | 低 | 对外API、防刷 |
| Sentinel 集群 | 极高 | 较高 | 中 | 微服务内部核心接口 |
| 本地限流(Guava) | 低(单机误差) | 极高 | 低 | 非核心、高吞吐批处理 |
这样回答既有广度(考虑网关与业务层),又有深度(Sentinel集群原理、降级策略),面试官一定会满意。如果还想了解 Sentinel 集群模式的具体 Token Server 配置细节,或者网关层 Lua 脚本怎么写,随时告诉我,我可以继续展开。 😊
浙公网安备 33010602011771号