MQ消息队列——使用场景分析

编程

MQ(消息队列

1、为什么使用MQ

  • MQ可以解耦异步削峰

  • 解耦场景:使用Pub/Sub 发布订阅模型,可以一个系统发布消息,多个系统订阅消费。

  • 异步场景:用户一个请求,后台需要调用多个服务完成,可以将每一个服务放入一个队列,分别异步执行。

  • 削峰:一般Mysql 每次可处理2k左右请求,如果请求量突然暴增,DB将承受不住,甚至宕机,将请求放入队列,根据DB处理能力,排队消费。

  • 引入MQ面对的问题:

    系统可用性降低:MQ服务挂了,系统也就挂了

    系统复杂度提高:如何保证消费不重复,消息不丢失,消息传递的顺序行,都需要解决

    一致性问题出现:A系统处理成功,B系统没有处理成功,咋办

  • 各消息队列对比:

    特性

    ActiveMQ

    RabbitMQ

    RocketMQ

    Kafka

    单机吞吐量

    万级,比 RocketMQ、Kafka 低一个数量级

    同 ActiveMQ

    10 万级,支撑高吞吐

    10 万级,高吞吐,一般配合大数据类的系统来进行实时数据计算、日志采集等场景

    topic 数量对吞吐量的影响

     

     

    topic 可以达到几百/几千的级别,吞吐量会有较小幅度的下降,这是 RocketMQ 的一大优势,在同等机器下,可以支撑大量的 topic

    topic 从几十到几百个时候,吞吐量会大幅度下降,在同等机器下,Kafka 尽量保证 topic 数量不要过多,如果要支撑大规模的 topic,需要增加更多的机器资源

    时效性

    ms 级

    微秒级,这是 RabbitMQ 的一大特点,延迟最低

    ms 级

    延迟在 ms 级以内

    可用性

    高,基于主从架构实现高可用

    同 ActiveMQ

    非常高,分布式架构

    非常高,分布式,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用

    消息可靠性

    有较低的概率丢失数据

    基本不丢

    经过参数优化配置,可以做到 0 丢失

    同 RocketMQ

    功能支持

    MQ 领域的功能极其完备

    基于 erlang 开发,并发能力很强,性能极好,延时很低

    MQ 功能较为完善,还是分布式的,扩展性好

    功能较为简单,主要支持简单的 MQ 功能,在大数据领域的实时计算以及日志采集被大规模使用

2、如何保证消息队列的高可用

  • RabbitMQ 的高可用模式:镜像集群

    镜像集群模式下,你创建的 queue,无论元数据还是 queue 里的消息都会存在于多个实例上,就是说,每个 RabbitMQ 节点都有这个 queue 的一个完整镜像,包含 queue 的全部数据的意思。然后每次你写消息到 queue 的时候,都会自动把消息同步到多个实例的 queue 上。RabbitMQ的集群模糊可以在后管管理中新增一个策略,这个策略是镜像集群模式的策略,指定的时候是可以要求数据同步到所有节点的,也可以要求同步到指定数量的节点,再次创建 queue 的时候,应用这个策略,就会自动将数据同步到其他的节点上去了。

3、如何保证消息不被重复消费

如何保证 MQ 的消费是幂等性的,需要结合具体的业务来

4、如何保证消息的可靠传输

RabbitMQ 生产者丢数据:

  • 选择用 RabbitMQ 提供的事务功能,就是生产者发送数据之前开启 RabbitMQ 事务 channel.txSelect ,然后发送消息,如果消息没有成功被 RabbitMQ 接收到,那么生产者会收到异常报错,此时就可以回滚事务 channel.txRollback ,然后重试发送消息;如果收到了消息,那么可以提交事务 channel.txCommit吞吐量会下来,因为太耗性能

  • 可以开启 confirm 模式,在生产者那里设置开启 confirm 模式之后,你每次写的消息都会分配一个唯一的 id,然后如果写入了 RabbitMQ 中,RabbitMQ 会给你回传一个 ack 消息,告诉你说这个消息 ok 了。如果 RabbitMQ 没能处理这个消息,会回调你的一个 nack 接口,告诉你这个消息接收失败,你可以重试。而且你可以结合这个机制自己在内存里维护每个消息 id 的状态,如果超过一定时间还没接收到这个消息的回调,那么你可以重发。

  • 事务机制和 confirm 机制最大的不同在于,事务机制是同步的,你提交一个事务之后会阻塞在那儿,但是 confirm 机制是异步的,你发送个消息之后就可以发送下一个消息,然后那个消息 RabbitMQ 接收了之后会异步回调你的一个接口通知你这个消息接收到了。(常用confirm机制)

5、如何保证消息的顺序

  • RabbitMQ : 一个队列对应一个消费者(消费者内部可以用内存队列做排队,然后分发给底层不同的 worker 来处理),或者多个队列对用多个消费者(这种情况队列多)。

6、如何解决消息队列延时以及过期,队列满,几百万消息持续积压问题

积压问题:

 

过期:重导

以上是 MQ消息队列——使用场景分析 的全部内容, 来源链接: utcz.com/z/519250.html

回到顶部