知识卡片

排队是限流的变种,及独立系统实现的必要性

结构图卡

内容

排队本质上是[[限流:基于请求限流与基于资源限流的对比,及阈值确定难点]]的一个变种:限流是直接拒绝超出承受能力的请求,排队则是让这些请求先排着、等一段时间再进系统(12306网站的排队是最典型的例子);但排队并不天然意味着更好的用户体验——用户排了很长时间才进来,体验未必比被限流直接拒绝好多少。由于排队需要临时缓存大量还没处理的业务请求,这个数据量单个系统内部通常撑不住,一般要用独立系统来实现,比如用Kafka这类消息队列专门缓存这些排队中的用户请求。以1号店”双11”秒杀排队系统为例,其架构由三个模块组成:排队模块负责接收用户的抢购请求,按先入先出的方式缓存下来,每个参与秒杀的商品单独维护一个队列,队列大小按参与秒杀的商品数量(外加一定余量)来定;调度模块负责在排队模块和服务模块之间做动态调度,不断检查服务模块是否还有处理能力空闲,一旦有空闲就从队头把请求调入服务模块,本质上不只是简单转发请求,还承担着根据服务模块实际处理能力来动态调节拉取速度这个更关键的职责;服务模块负责真正调用业务逻辑处理请求、产出结果,再回写给排队模块。这套架构的核心思路是把”瞬时涌入的海量请求”和”系统真正的处理能力”解耦开——排队模块负责削峰填谷式地暂存请求,调度模块负责按系统实际吞吐能力精确控制放行速度,而不是让所有请求一股脑同时冲击后端服务,这正是排队相比直接限流拒绝更”温和”的地方。

结构图

flowchart LR
  A["用户请求"] --> B["排队模块<br/>先入先出缓存,每商品独立队列"]
  B --> C["调度模块<br/>监测服务模块空闲情况<br/>按实际处理能力动态调节放行速度"]
  C --> D["服务模块<br/>真正处理业务,返回结果"]
  D --> B

参考来源

- 位置:《从零开始学架构》第31讲《如何应对接口级的故障?》"排队"(源文件:_epub-src/OEBPS/text00002.html) - 结论依据:原文说明"排队实际上是限流的一个变种,限流是直接拒绝用户,排队是让用户等待一段时间……由于排队需要临时缓存大量的业务请求,单个系统内部无法缓存这么多数据,一般情况下,排队需要用独立的系统去实现",并引用1号店"双11"秒杀排队系统的排队模块、调度模块、服务模块三部分具体职责,直接支撑本卡片结论与结构图。 - 原始内容:排队实际上是限流的一个变种,限流是直接拒绝用户,排队是让用户等待一段时间……【排队模块】负责接收用户的抢购请求……【调度模块】负责排队模块到服务模块的动态调度……【服务模块】负责调用真正业务来处理服务。