知识卡片
分布式限流的额度货币化改造如何用本地计算摊薄网络开销
内容
单机限流的统计数据都在本进程内存里,天然简单;微服务下要精细控制每个 内部服务节点的流量消耗,就必须让各节点共享统计数据,这类分布式限流最 直接的做法是把统计结果都存进集中式缓存(如Redis),配合分布式锁/信号量 解决并发读写问题——理论上单机限流模式都能这样搬到分布式场景,代价是 每次服务调用都要多一次网络开销,流量压力越大限流本身反而越拖累系统 处理能力,效率天然不高。为缓解这个问题,一种改造思路是把[[漏桶与令牌桶 方向相反的流量整形算法及令牌桶更受青睐的原因]]里的令牌桶”货币化”:令牌 不再是简单的”能不能通行”的二元通行证,而是可累加、可消耗的数值型 “货币额度”。请求进入集群时先在API网关领取一笔额度(可按用户等级差异化, VIP额度更高甚至无限),此后每访问一个服务就按该服务的固定成本从这笔 额度里扣减;只要剩余额度大于零,判断”还能不能继续访问下一个服务”这件事 完全可以在本地内存里完成,不需要额外网络请求;只有当额度耗尽时,才发生 一次网络请求向令牌桶重新申领额度,成功则继续、失败就进入降级逻辑。这个 方案牺牲了一定的限流精确度(可能一个业务操作已经完成了部分服务调用, 却因为申请不到新额度而在中途失败,白白浪费掉已完成部分的资源),换来的 是绝大多数时刻限流判断都不需要网络往返——这正是分布式限流”不追求越彻底 越好、要在代价和收益间权衡”这一原则的具体体现,与容错措施”无法妥协”的 定位形成对比。
参考来源
- 位置:《凤凰架构:构建可靠的大型分布式系统》第8章"流量治理"8.2.3节
"分布式限流"(源文件:_epub-src对应OEBPS/Text/chapter103.xhtml)
- 结论依据:原文说明集中式缓存方案每次调用都需额外网络开销、效率不高,
进而提出基于令牌桶的"货币化"额度方案,在API网关领取额度、本地扣减
判断,只在额度耗尽时才发起网络请求,并指出这种方案牺牲精确度换取
性能,限流不追求"越彻底越好",直接支撑本卡片结论。
- 原始内容:为了缓解这里产生的性能损耗,一种可以考虑的办法是在令牌桶
限流模式基础上进行"货币化改造"……当剩余额度不为零时,都无须额外的
网络访问……限流与容错不一样,做分布式限流从不追求"越彻底越好"。