高并发分布式队列设计

本文探讨了消息队列在分布式系统中的作用,如应用解耦、异步处理和流量控制,并详细介绍了如何设计消息队列,包括发布订阅模式、确保消息必达的策略、维护消息顺序、防止消息重复以及保障消息一致性。同时,文章举例说明了如RabbitMQ和Kafka在这些方面的不同实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是消息队列

消息队列提供了分布式集群系统架构中各个服务模块之间的消息通信,主
要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩
和最终一致性架构,其模型如下:
在这里插入图片描述

消息队列能做什么?

应用解耦
✓ 模块之间仅依赖“通知”,而没有直接的接口调用,所以不存在依赖
◼ 可扩展性
✓ 队列支持高可用部署,水平扩展容量和吞吐量
✓ 生产者和消费者都只关心“通知”,消息队列提供通知机制,业务众向扩展
◼ 异步处理
✓ 生产者只管保证把“通知”发送出去,并不关心下游处理结果,允许多个消费者同时消费
◼ 削峰填谷
✓ 消息队列“堆积”消息,只要不溢出就行

如何设计消息队列

发布订阅的两种模式
第一种:生产者发布给MQ,然后由MQ推送给订阅消息的消费者。
MQ不断主动把消息推送给消费者,如果消费者处理能力不高,有可能造成消费者本地缓存溢出,但是消息能及时被消费;例如RabbitMQ就支持这种模式。
模型如下:
在这里插入图片描述
第二种:消费者主动到MQ拉取消息,所以会造成消息并没有即时消费,但是能控制消费的速度,例如kafka支持这种模式。
模型如下:
在这里插入图片描述

如何做到消息必达?

可靠投递
✓ 事物机制
比如RabbitMQ中与事务机制有关的方法有三个: txSelect(), txCommit()以及txRollback(),
txSelect用于将当前channel设置成transaction模式, txCommit用于提交事务, txRollback用于回
滚事务,在通过txSelect开启事务之后,我们便可以发布消息给broker代理服务器了,如果
txCommit提交成功了,则消息一定到达了broker了,如果在txCommit执行之前broker异常崩溃
或者由于其他原因抛出异常,这个时候我们便可以捕获异常通过txRollback回滚事务了。
✓ 确认机制

  • 普通确认模式: 每发送一条消息后,调用waitForConfirms()方法,等待服务器端回复ACK。实
    际上是一种串行确认了。
  • 批量确认模式: 每发送一批消息后,调用waitForConfirms()方法,等待服务器端确认。
  • 异步确认模式: 提供一个回调方法,服务端确认了一条或者多条消息后Client端会回调这个方
    法。异步确认的投递效率最高,但是编程也更复杂一些。
    ◼ 可靠消费
    最大努力投递机制:未收到ack的消息放到重发队列,然后每隔1s, 5s, 20s, 40s….去投递
    ◼ 持久化存储

如何保证消息的顺序性

假如现在有M1,M2两个消息,为了能够让两个消息顺序被消费,那生产者需要顺序的往同一个route去发布消息。
在这里插入图片描述

消息去重

网络始终有时候是不可靠的,所以为了可靠投递和可靠消费,都会设计重发
某条没有收到ACK的消息,那么这就有可能导致消费端重复消费消息,那如何去
重?
✓ 幂等性
消费端处理业务消息要保持幂等性,也就是同一个东西执行多次会得到相同结果;
✓ 去重表
保证每条消息都有唯一编号且保证消息处理成功与去重表的日志同时出现;
有意思的是rocketMQ恰恰把这个问题丢给了用户,而rocketMQ本身没有实现。

消息的一致性

是指产生消息的业务动作、消息发送和消息消费的一致性,比如一笔订单
支付成功了,需要扣库存。
场景:

  1. 支付业务处理成功,执行发送消息的时候应用出现故障,导致没有发送消息(后续服务没有收到消息处
    理业务,结果数据不一致)
  2. 业务处理成功,执行发送消息的时候,消息系统(MQ)故障,导致消息发送失败(后续服务没有收到
    消息处理业务,结果数据不一致)
  3. 扣库存失败,导致数据不一致
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值