上周去苏州见个做电商中台的技术负责人,他抽着烟说上个月618差点把整个网关打挂。
没什么玄乎的故障。就是大促前配限流的时候,拍脑袋给每个实例设了1000QPS,12个实例凑出来12000的全局限流阈值,压根没算后面库存数据库的最大承载才8000QPS。结果零点刚过,请求直接冲穿网关,把数据库连接池占满,整个站卡了17分钟。
限流阈值拍脑袋定的代价
很多人一开始碰限流,都觉得这玩意简单。不就是设个数字,超过了就拦下来?
真不是。
你要是用本地令牌桶做限流,每个节点自己算自己的阈值,扩容的时候多开几个实例,总阈值就自动涨,缩容的时候就往下掉,不用改配置。快是真的快,不用跨节点调远程接口,请求处理延迟能压到1毫秒以内。
但坑也明摆着。

上次那个朋友就是吃了本地限流的亏。大促当天临时扩容了4个实例,没算准本地限流的总阈值,本来应该拦在8000QPS的请求,实际放进来12000多,直接把下游数据库打瘫。
后来他换成了Redis全局限流,所有节点的限流计数都存在同一个Redis里,阈值准了是准了,但是每个请求都要多跳一次Redis,整体延迟涨了3毫秒。
这就是取舍。
你要低延迟,就接受本地限流的阈值不准;你要阈值准,就得多付一点网络延迟的代价。没有什么完美方案,全看你业务能扛哪头的问题。
熔断不是断网是给系统留喘息的空间
很多人对熔断有误解,觉得配了熔断就是接口直接返回错误,把用户全赶跑。
大错特错。
还是那个苏州的朋友,之前给支付接口配熔断,错误率到10%才触发。结果去年双11,第三方支付通道抽风,错误率刚到6%的时候,整个支付线程池就被堵满了——所有请求都在等下游响应,网关的线程占满之后,连首页的静态资源都打不开。
熔断的本质,是在故障刚冒头的时候,就把有问题的链路掐断,不让小故障拖垮整个系统。不是等整个系统都瘫了再动手。

这里面的细碎坑多了去了。比如半开状态的探测请求,很多人就配1个,要是刚好赶上第三方抽风,那个探测请求失败,直接又把熔断打回关闭状态,等于之前的熔断白做。还有熔断之后的返回内容,你别硬邦邦弹个“服务暂不可用”,做电商的就说“当前下单人数过多,稍等再试”,甚至弹个小额优惠券,把用户流失率压到最低。
阈值的设定更没有标准答案。你要是把触发熔断的时间设成1秒,稍微有点网络抖动就触发,用户体验差到爆炸;要是设成10秒,等触发的时候系统已经被打挂了。得自己压测,摸清楚下游服务的最大容忍度,找那个刚好不踩两边坑的点。
别把限流和熔断做成两张皮
我见过太多团队,限流是运维配的,熔断是开发配的,两边压根不对账。
运维给网关配全局限流1万QPS,开发给下游服务配的熔断阈值才8000QPS。多出来的2000请求,刚到下游就被熔断,用户看到的全是报错。
上次那个朋友就是,大促前临时把库存接口的限流调到8000QPS,忘了同步改下游库存服务的熔断阈值——之前设的是1万。结果请求刚到8000,网关觉得还能扛,继续放,下游库存服务直接被打挂,半天没缓过来。
说白了,限流和熔断本来就是一套防护体系的两个环节。你限流拦下来的请求,本来就不该到下游去;你熔断的阈值,本来就应该比限流的阈值低一截,给系统留够冗余空间。
要是这俩配置各管各的,那你装网关的防护能力,还不如在前端加个倒计时弹窗靠谱。
现在很多云厂商把网关的限流熔断做成了可视化拖拽配置,拖几下就能生成规则。
但工具再好用,你也得知道每个参数背后的代价。
不然下次线上出故障,你还是得抱着电脑在机房蹲到凌晨三点。