
1) 【一句话结论】采用基于分布式消息中间件(如Kafka)的推送系统,通过消费者拉取模式、消息持久化、幂等处理及多副本高可用设计,实现毫秒级延迟、99.9%以上可用性,支持千万级用户。
2) 【原理/概念讲解】高并发消息推送的核心是“低延迟”与“高可用”。对于毫秒级延迟,传统推送(如轮询)效率低,故采用消息队列的消费者拉取模式——客户端(消费者)主动从队列拉取消息,避免推送延迟。高可用需消息中间件支持多副本(如Kafka的副本机制),主节点故障时副本自动切换,保证服务不中断。数据一致性采用最终一致性:消息持久化(如Kafka日志持久化)确保不丢失,消费端通过幂等处理(消息ID+业务逻辑)避免重复消费。大规模用户支持通过水平扩展消息队列节点(增加Broker),客户端订阅多个Broker实现负载均衡。
类比:消息队列像快递站,生产者(发消息)把包裹放快递站,消费者(客户端)去取包裹,快递站有多个分站(副本),即使某个分站坏,还能从其他分站取包裹,保证包裹不丢。
3) 【对比与适用场景】
| 特性 | Kafka | RabbitMQ | 适用场景 |
|---|---|---|---|
| 事务支持 | 事务消息(Exactly-Once) | 简单事务 | 需强一致性场景 |
| 吞吐量 | 高(百万级QPS) | 中(万级QPS) | 大规模高并发推送 |
| 延迟 | 毫秒级(拉取模式) | 毫秒级(推送模式) | 低延迟消息 |
| 持久化 | 日志持久化,高可靠性 | 队列持久化 | 需消息不丢失 |
| 扩展性 | 水平扩展Broker节点 | 水平扩展队列节点 | 千万级用户 |
注意点:Kafka适合高吞吐、持久化,但消费端需处理大量消息(需批量处理);RabbitMQ适合点对点,但扩展性不如Kafka。
4) 【示例】(伪代码)
生产者发送消息:
producer = KafkaProducer(bootstrap_servers=['broker1:9092', 'broker2:9092'])
topic = "chat_message"
message = {"user_id": 1001, "msg": "hello", "timestamp": 1670000000}
producer.send(topic, value=message)
producer.flush()
消费者拉取消息(幂等+持久化):
consumer = KafkaConsumer(
"chat_message",
bootstrap_servers=['broker1:9092', 'broker2:9092'],
group_id="chat_group",
auto_offset_reset='earliest',
enable_auto_commit=False
)
for message in consumer:
if not is_message_processed(message.value["msg_id"]):
process_message(message.value)
commit_message(message) # 提交偏移量
5) 【面试口播版答案】
“设计一个高并发消息推送系统,核心是采用分布式消息中间件(如Kafka),通过消费者拉取模式实现毫秒级延迟。系统架构包括:生产者(客户端发送消息)、消息队列(Kafka集群,多副本保证高可用)、消费者(客户端拉取消息并处理)。消息持久化确保不丢失,幂等处理避免重复消费。高可用通过副本自动切换,扩展性通过增加Broker节点支持千万级用户。具体来说,生产者将消息写入Kafka主题,消费者以拉取方式从队列获取消息,批量处理减少延迟,消息ID+业务逻辑实现幂等,副本机制保证99.9%可用性。”
6) 【追问清单】
7) 【常见坑/雷区】