当前位置: 移动技术网 > IT编程>开发语言>Java > MQ的相关理论和思考

MQ的相关理论和思考

2020年05月02日  | 移动技术网IT编程  | 我要评论

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. 消息队列里积压了很多消息怎么办

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网