MQ

190 阅读3分钟

MQ

用处

一、异步。可提高性能和吞吐量

二、解耦

三、削峰

四、可靠。常用消息队列可以保证消息不丢失、不重复消费、消息顺序、消息幂等

选型

一Kafak:吞吐量最大,性能最好,集群高可用。缺点:会丢数据,功能较单一。

二RabbitMQ:可靠性高,功能全面。缺点:吞吐量低,可能消息积累影响性能。

三RocketMQ:高吞吐、高性能、高可用、事务性消息。缺点:生态相对不成熟。

如何保证消息不丢失

可能会丢失消息的环节

生产者->MQ MQ主从复制 MQ存磁盘 MQ->消费者

依次解决

一、生产者发送消息到MQ:

Kafak:回调。RocketMQ:回调、事务性消息。RobbitMQ:回调、手动事务、事务性消息(不细腻)

回调:生产者发送消息之后会注册一个回调函数,MQ收到消息返回ack,表示已收到。

二、消息同步不丢失:

RocketMQ:

普通集群中,异步同步性能高,可能丢消息。同步同步相反。

同步同步是指master结点拿到消息后从节点发送消息,从节点存盘后返回生产者ack。

异步同步是指master结点收到消息后往从节点同步消息,并直接返回生产者ask。

Dledger集群-两阶段提交。类似于ZAB协议同步数据。

RabbitMQ:

普通集群中,消息分散存储,结点不主动进行消息同步,可能丢消息。

镜像集群中,会在集群之间主动进行消息同步,安全性较高。

Kafak:

通常用在允许消息少量丢失的场景。

三、MQ消息内存到磁盘消息不丢失:

RocketMQ:使用同步刷盘安全性高,性能低。异步刷盘相反。

broker收到消息后,消息在内存中,需要其他线程将消息刷新到磁盘。

RabbitMQ:将消息配置为持久化队列,新增的Quorum类型的队列,用Raft协议进行消息同步。

四、MQ消费者消费消息不丢失:

分析:消息队列中有消息的偏移量,一般是在本地事务执行完成后移动。异步可能会丢失消息

RocketMQ:使用默认方式消费即可,不要采用异步的方式。

RabbitMQ:autoCommit->手动提交offset。

Kakfa:手动提交offset

原则:采用同步的方式,在消息被消费完成,也就是本地事务执行完后提交消息,移动偏移量。

如何保证消息幂等

MQ产品并没有主动提供解决幂等的机制,需要由消费者自行控制。

RocketMQ中可以给每条消息分配一个ID,作为判断依据,但不保证全局唯一,不推荐。

建议使用带业务标识的ID,来进行幂等判断,如OrderID,统一ID分配。

如何保证消息有序

MQ只需保证局部有序,不需要保证全局有序。例如一个聊天窗口和整个QQ消息。

关键在于,单机下,队列可以先进先出保证有序,但在分布式状态下,有多个队列。

所以要保证生产者把一组消息放到同一个队列中,而消费者依次消费该消息组的所有消息

RockeMQ:

有完整设计,生产者中MessageSelevtor可保证,消费者需要注册一个registerMessageListener

RabbitMQ:要保证一组消息只对应一个队列,并且一个队列只对应一个消费者

Kafak:生产者可以将消息分配到同一个partition。Topic下只由同一个消费者消费