Skip to content
  • Overload Control for Scaling WeChat Microservices
    • 研究背景与问题 (BACKGROUND & OVERLOAD IN WECHAT)

      • 微信系统架构
        • 类型: 基于微服务架构,服务间关系构成有向无环图 (DAG)。
        • 服务分类:
          • 入口服务 (Entry Service): 用户请求的起点 (in-degree=0)。
          • 中间层服务 (Leap Service): 可调用其他服务 (out-degree>0)。
          • 基础服务 (Basic Service): 服务调用的终点 (out-degree=0),如账户、资料、消息收件箱等。
        • 系统规模:
          • 超过 3000 个服务,运行在超过 20000 台机器上。
          • 系统动态性强,平均每天近千次变更。
          • 工作负载波动大,节假日峰值可达日常平均的 10 倍。
      • 核心研究问题:大规模微服务下的过载控制
        • 关键挑战:后续过载 (Subsequent Overload)
          • 定义: 一个上游任务的成功,依赖于对下游过载服务的多次成功调用。
          • 具体场景:
            • 1: 多次调用同一个已过载的服务 (如 A 调用 M 两次)。
            • 2: 分别调用多个不同的已过载服务 (如 A 调用 M 和 N)。
          • 问题根源: 简单的随机丢弃策略会导致任务成功率急剧下降 (例如,若单次调用成功率为 50%,连续两次调用的成功率仅为 25%),造成资源浪费和“服务假死”现象。
        • 架构带来的挑战:
          • 无单一入口: 传统的网关集中式监控失效。
          • 调用路径复杂: 难以精确判断应丢弃哪类请求。
          • 协调成本高: 在快速演进的复杂系统中,服务间的强协调机制难以维护。
    • 核心方法 (DAGOR OVERLOAD CONTROL)

      • 设计原则
        • 服务无关 (Service Agnostic): 控制逻辑与业务逻辑解耦,普适于各类服务。
        • 独立但协作 (Independent but Collaborative): 各服务独立决策,但通过协作机制共同应对过载。
        • 高效且公平 (Efficient and Fair): 最小化失败任务的资源浪费,保证上游服务在下游过载时仍能维持饱和吞吐。
      • 1. 过载检测 (Overload Detection)
        • 机制: 在每个服务器上进行去中心化的本地监控。
        • 核心指标: 请求在等待队列中的平均时间 (Queuing Time)
        • 选择理由:
          • 相比响应时间 (Response Time):排队时间只反映本地服务器的处理能力,不受下游服务响应慢的影响,更准确,避免误报。
          • 相比CPU利用率:高CPU不一定等于过载,只要请求能被及时处理。
        • 实现细节: 采用窗口期(如每秒或每2000个请求)进行统计,微信实践中阈值设为 20ms。
      • 2. 服务准入控制 (Service Admission Control)
        • 基础:双层优先级系统
          • 业务优先级 (Business Priority):
            • 静态优先级,在入口服务层根据业务重要性分配 (如:登录 > 支付 > 发消息)。
            • 存储在可复制的哈希表中。
            • 在整个请求调用链中向下传递。
          • 用户优先级 (User Priority):
            • 动态优先级,用于在同业务优先级内进行细粒度控制,解决后续过载问题。
            • 通过 hash(用户ID) 生成。
            • 哈希函数每小时更换,以保证用户间的公平性。
            • 同样在整个调用链中传递。
        • 机制 A:自适应准入控制 (Adaptive Admission Control)
          • 目标: 根据负载动态调整服务器的准入优先级阈值 (α%, β%)
          • 方法: 基于直方图的高效调整算法。
            1. 服务器维护一个按 (业务优先级, 用户优先级) 索引的请求计数器直方图。
            2. 根据当前是否过载,计算下一个周期的目标接纳率(过载则降低 α%,不过载则提升 β%)。
            3. 利用直方图的累加和,一次性计算出能满足目标接納率的新的优先级阈值,避免了低效的线性或二分搜索。
        • 机制 B:协作式准入控制 (Collaborative Admission Control)
          • 目标: 在上游服务处提前拒绝注定会被下游丢弃的请求,节省网络和下游服务器资源。
          • 方法: 捎带 (Piggybacking) 机制。
            1. 下游服务 (M) 在其响应消息中,捎带上自己当前的准入优先级阈值。
            2. 上游服务 (A) 收到响应后,缓存下游服务 M 的准入门槛。
            3. 当 A 准备再次向下游 M 发送请求时,先使用缓存的阈值进行本地预检查,提前丢弃不满足条件的请求。
    • 实验设计 (EVALUATION)

      • 实验环境:
        • 模拟一个上游消息服务 A 和一个下游加密服务 M。
        • 服务 M 被部署在3台服务器上,处理能力上限为 750 QPS。
      • 工作负载 (Workloads):
        • M¹: 简单过载 (A 调用 M 一次)。
        • M², M³, M⁴: 后续过载 (A 分别调用 M 2, 3, 4 次)。
        • 混合负载: 均匀混合 M¹ 到 M⁴ 的请求。
      • 对比方案:
        • CoDel, SEDA, Naive (随机丢弃)。
        • DAGOR 的变种 (使用响应时间作为检测指标)。
    • 关键结果 (Key Results)

      • 检测指标对比: 使用排队时间比使用响应时间作为过载指标更精确,能更好地反映真实负载,避免过早地触发限流。
      • 后续过载下的性能:
        • 在后续过载场景 (M²) 下,DAGOR 的请求成功率比 CoDel 和 SEDA 高出约 50%,接近理论最优值。
        • 随着后续调用次数增加 (M³、M⁴),DAGOR 的优势愈发明显。
      • 公平性:
        • 在混合负载下,DAGOR 对不同类型的请求(简单 vs 后续过载)能保持大致相同的成功率,体现了公平性。
        • 相比之下,CoDel 明显偏向于处理简单的 M¹ 请求,对复杂任务不友好。
    • 技术贡献 (Technical Contribution)

      • 首次识别并定义了微服务架构中的后续过载 (Subsequent Overload) 这一关键问题。
      • 提出使用 排队时间 (Queuing Time) 作为一种更鲁棒的本地化过载检测指标。
      • 设计了业务 + 用户双层优先级体系,确保同一请求在调用链中决策的一致性,从而有效解决了后续过载问题。
      • 实现了基于直方图的高效自适应算法,用于实时调整准入门槛。
      • 引入了通过捎带机制实现的轻量级协作控制,实现了负载的早期丢弃。

原文: 《Overload Control for Scaling WeChat Microservices》