前言

在平时,服务 A 每秒发出 100 条请求,服务 B 每秒能处理 200 条,整个系统运行得游刃有余。但到了双十一大促,流量瞬间如洪水般涌进来!服务 A 的并发量直冲每秒 400 条。如果不加任何防护,服务 B 很快就会因为资源耗尽而被这股流量洪峰压垮。

为了应对这种突发的流量冲击,目前最标准的解法引入消息队列进行“削峰填谷”,将多余的请求存在消息队列中,再让服务 B 慢慢消化。

接下来,我将简要说下这个领域极为出色的消息队列中间件 —— Kafka。

Kafka 的系统架构

如上图所示,多个 Broker 服务进程共同组成了分布式的 Kafka Cluster,并依靠 ZooKeeper 在后台负责集群的元数据管理、Broker 节点存活的心跳检测以及 Leader 节点的选举。Producer 发送的消息会按照 Topic 进行逻辑分类,并物理分段存储在各个 Partition 中。最终,由一个或多个 Consumer 构成的 Consumer Group 以组为单位从 Broker 端拉取对应 Partition 的消息,协同且隔离地执行业务逻辑。

注意,Kafka 从 2.8 版本开始引入了 KRaft(Kafka Raft)协议,并在后续版本中移除了对 ZooKeeper 的依赖。Kafka 通过实现元数据的自管理,降低运维成本,大幅增强了集群的扩展性、稳定性与吞吐极限。

延伸思考

  1. 消息积压:如果下游消费太慢,队列里积压了上百万条数据该怎么办?
  2. 消息可靠:如何保证消息在发送、存储、消费的全链路中绝对不丢失?
  3. 幂等性:各种原因导致消息重复消费时,如何保证业务数据不重复插入?
  4. 顺序性:如何保证强相关消息(如订单状态更新)的绝对有序执行?
  5. 高性能与高可用:Kafka 是如何通过底层设计做到极高吞吐的?

极客时间的邓明老师对于这些问题的回答写的非常不错,推荐阅读。