MQ的相关理论和思考

1. MQ的优缺点

优点:

  • 解耦:通过MQ解除上游系统和下游系统的调用耦合,下游系统只需要做消息的订阅和取消订阅,上游系统无需任何改动。(一生产,多消费的典型场景)
  • 异步:通过MQ将一些不需要同步获取执行的结果,并且非常耗时的调用操作通过MQ异步化。
  • 削峰:通过MQ将一些高峰期的高并发流量积压在MQ中,下游可以按自己的消费能力消费,不会出现过载消费的情况。

缺点:

  • 可用性降低:如果MQ出现了问题,依赖MQ环节的服务都会出现瘫痪
  • 复杂性提高:给系统引入额外的组件,调用链变长,变复杂。同时需要考虑的事情会变多(消息幂等,丢失,积压等等)
  • 数据一致性:下游服务执行部分失败,导致数据不一致  

2. MQ的选型

Kafka:

  • 吞吐量:10w级别,吞吐量是Kafka最大的优点。
  • 时效性:ms以内
  • Topic数量对吞吐量的影响:topic达到几百上千,吞吐量有较小幅度下降
  • 应用场景:主要用于大数据做日志采集,实时数据计算等场景。
  • 高可用性:分布式系统架构,
  • 优劣势:功能简单,但是吞吐量大,并且天然适合大数据采集和计算

RocketMQ:

  • 吞吐量:10w级别,
  • 时效性:ms
  • Topic数量对吞吐量的影响:topic达到几百上千,吞吐量有较小幅度下降
  • 应用场景:吞吐量大的业务场景
  • 高可用性:分布式系统架构,易扩展
  • 优劣势:接口移动,阿里开源,有大规模的应用,社区活跃度高,可靠性ok

RabbitMQ:

  • 吞吐量:万级,比kafka和RocketMQ低了一个量级
  • 时效性:微秒级别,延迟最低
  • 应用场景:
  • 高可用性:主从架构实现高可用
  • 优劣势:erlang开发,时效性极好,开源版本提供的管理页面友好,强大。实现的机制较重,吞吐量较低

ActiveMQ:

  • 吞吐量:万级,比kafka和RocketMQ低了一个量级
  • 时效性:ms
  • 应用场景:主要还是异步和削峰
  • 高可用性:主从架构实现高可用
  • 优劣势:较低概率可能会丢消息,同时开源社区不够活跃,目前更新较慢,假设遇到问题会很难解决。

3. 如何保证MQ的高可用 

RabbitMQ:

  单机模式,普通集群模式(中心化的),镜像集群模式(queue对等,实时性差,网络负载重,不可线性拓展)

 

Kafka:

  分布式架构,有多个broker(master,slave)。比如一个topic,数据不是分布在一台机器上,利于水平拓展。同时提供多副本机制保证高可用,针对一个topic下的副本,只能写入到leader,然后同步到follower。是中心化的。broker之间的协调是通过zk完成的,选出一个controller,然后决定每个partition的主从。

RocketMQ:

  分布式架构,有多个broker。和kafka不同,针对一个topic,在每个broker上会有多个queue,消息的消费是针对queue的,消息的冗余是通过主从复制,有同步复制和异步。broker的协调是通过nameServer来完成的,不同于kafka,RocketMQ没有选举机制,因为broker对等,一个broker挂了则由其他的broker处理请求,相当于剔除了这个broker。

4. 如何保证消息的幂等性

 产生重复消费的可能性:

  • 消费者重启前没提交消费到的数据index,可能会导致重复消费
  • 网络抖动导致消费确认消息没到达MQ,可能会导致重复消费

 保证幂等的手段:

  • 如果是mysql,可以通过主键或者唯一索引等保证。 如果是redis,可以通过key保证
  • 给每个消息增加一个全局唯一的id,然后通过redis做幂等性判断,这里可能会涉及到redis的事务原子性  

5. 如何保证消息的可靠性

RocketMQ

  1>从producer的角度

  • 默认是同步堵塞的方式,可以通过返回值确认消息投递到了broker
  • 如果是事务的方式,如果投递失败,会把消息存到commitLog中去
  • 支持日志索引,投递不成功的消息可以通过提供的API查询到

  2>从broker的角度

  • 消息是会同步到commitLog中的,就算broker宕机也是能加载出来的
  • broker支持同步刷盘和异步刷盘
  • broker支持主从部署

  3>从consumer的角度

  • consumer在消息消费的时候会记录成功消费消息或者已经发回到broker的offset
  • consumer维护的offset是会持久化的,就算consumer和broker都挂了,重启的时候,consumer会读取offset在发送给broker
  • consumer消费失败的时候会重试,然后更新offset

6. 如何保证消息的消费顺序

  顺序消息包含两种类型:

    分区顺序:一个Partition内所有的消息按照先进先出的顺序进行发布和消费

    全局顺序:一个Topic内所有的消息按照先进先出的顺序进行发布和消费

  RocketMQ:我们知道针对一个topic是会有多个queue的,所以首先需要保证顺序消费的消息是发到同一个queue中的,通过提供的分区函数保证消息能够丢到一个queue中就好。 但是这样只能保证分区顺序,全局顺序的话那就是只有一个分区。

7. 消息队列里积压了很多消息怎么办

  可以通过临时扩容,增加消费者数量,排查原先消费者出现的问题

    原文作者:学会沉淀自己
    原文地址: https://www.cnblogs.com/wpccc/p/12814502.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞