RabbitMQ、RocketMQ、Kafka、ActiveMQ

RabbitMQ、RocketMQ、Kafka、ActiveMQ

注: 由于本猿键盘Q键坏了,时好时坏,所以下文中的 rabbitmq == rabbitm
参考与这位大佬

消息中间件:
消息中间件指的是利用高效可靠的消息传递机制进行跨进程、与平台无关的数据交流,可以在分布式环境下扩展进程的通信
目前主流的消息中间件有 ActiveMQ、Kafka、RabbitMQ、RocketMQ等

MQ使用场景:
mq使用场景很多,主要有三个: 解耦、异步、削峰

  • 解耦: 解耦主要指的是 A 系统需要与 B C D 系统实现数据交互(或者说通信),如果这时候使用常规方式(请求接口)的话可能会出现 B C D 系统挂掉或者其它原因导致通信失败。这时候就可以使用 mq,A 系统将产生的消息放在 mq 中,让 B C D 系统自己去拿,A 系统不用考虑 B C D 系统是否成功接受到消息,只需要将消息放入 mq 即可。
  • 异步: 异步主要指的是当用户发送给 A 系统一个请求后,A 系统处理完自己本地业务的同时还需要 B C D 系统处理业务,这样的话总耗时将是处理四个系统处理时间的总和,这时候就可以考虑将将三条信息放入 mq 中,让 B C D 系统自己处理,耗时将是 A 系统处理时间加上放入 mq 的时间。尤其是互联网业务中的用户直接操作部分,一般要求请求耗时小于 200ms 左右。
  • 削峰: 削峰一般指的是一个系统平时的的并发量只有100,但某一时刻内会直接暴涨到万级等级别,加入系统使用的是 mysql 数据库,那么数据库将直接崩溃,因为 mysql 最多每秒中处理 2k 个,对于万级别的完全扛不住,这时候就可以使用 mq。系统将请求先写入 mq,然后在每秒拉取数据库能承受住的数量的请求进行处理。高峰期一过,慢慢的就会消化掉 mq 中的请求。

优缺点:

  • 优点: 优点就是可以解决特殊场景下的问题,如上面提到的解耦、异步、削峰
  • 缺点: 系统可用性降低-系统引入外部依赖越来,出现的问题就会越多。比如 mq 也可能会挂掉,也就是 mq 的高可用性问题
    系统复杂度提高-引入 mq 后你需要解决消息重复消费问题、消息丢失问题、消息传递有序性问题等
    数据一致性-当一个请求涵盖多个系统时,会出现 A 系统业务处理成功,但 B C D 系统业务处理失败,这时候就会出现数据不一致情况

消息中间件四种投递模式:
PTP模式:
点对点模式,由消息生产者、队列和消费者组成。一个队列可以有多个生产者可多个消费者,生产者生产主消息后,消息服务器将接受的消息按顺序放入队列,队列中的 每一条消息只能有一个消费者去消费,被消费的消息将从队列中移除。(此处队列中的消息并不是先进先消费)
在这里插入图片描述

Pub/Sub模式:
发布订阅模式,消息生产者将消息发送到一个主题(topic)中,所有订阅该主题的消费者可以消费该主题中的所有消息
在这里插入图片描述

Partition模式:
分区模式中,生产者将消息发送到主题中,再由主题发送到不同的分区中(partition),每个分区存储的是主题中的部分消息,不同的消费者组成消费者组,分区与消费者组是多对一的关系,消费者组中的消费者消费自己对应分区内的消息。分区模式解决的是在点对点模式下,有序消息需要专有消费者消费而带来的性能问题
在这里插入图片描述

Transfer模式:
Partition 模式所展示出来的业务场景是同一个主题下的消息可以由不同类型的消费者消费,也就是消费者组,但是此模式有一个限制,那就是消费者的数量不能多于分片。于是就有了 transfer 模式。
transfer 模式指的是生产者将消息发送到主题中,每个主题可以创建多个通道(channel),主题将所有消息转发到每个通道中,消费者消费时必须指定消费那个通道中的消息,而且消费时也是每条消息只能由一个消费者消费,指定同一通道的消费者可以看成是消费者组。
在这里插入图片描述

四者之间的区别:

@单机吞吐量topic 数量对吞吐量的影响时效性可用性可靠性功能支持
ActiveMQ万级,比 rocket 和 kafka 低一个数量级别ms 级高,主从架构实现高可用有较低概率丢失数据mq 领域功能及其完善
RabbitMQ万级,比 rocket 和 kafka 低一个数量级别us 级,这是其优势点高,主从架构实现高可用基本不丢基于 erlang 语言开发,并发能力强,性能好,延时底
RocketMQ十万级,高吞吐量当 topic 达到几百几千时吞吐量会有小幅度下降,但也是其优势所在,同等机器下可支持大量 topicms 级非常高,分布式架构经过优化配置可达到零丢失mq 功能较为完善,分布式架构,扩展性强
Kafka十万级,高吞吐量当 topic 达到几百几千时吞吐量会有大幅度下降,同等机器下不能支持大量 topicms 级非常高,分布式架构经过参数配置可达到零丢失mq 功能不完善,只支持简单的功能,常用于大数据领域的实时计算和日志采集

结论:
一般业务需要接入 mq 时,最早都用 acticemq,但是其没经过大规模高吞吐量验证吗,且社区不活跃,所以不推荐
后来开始流行 rabbitmq,但是由于是 erlang 语言开发的所以组织了大量 java 程序员去深究它,不过其社区活跃、性能好且是开源的,所以推荐使用
所以对于小型公司,技术挑战不是特别高的可以使用 rabbitmq,对于大型公司,有着较强的基础架构研发能力,可选择 rocketmq
对于大数据领域的实时计算、日志收集等业务场景,则可使用 kafka,毕竟其是行业的标准,且社区稳定

mq 如何保证高可用性:
rabbitmq 为目前最流行的且是以主从架构来做高可用的,我们以 rabbitmq 为例子。rabbitmq 作用三种模式来实现高可用,分别是单机模式、普通集群模式、镜像集群模式

  • 单机模式: 单机模式指的就是小 demo,也就是本地测试,一般生产环境不会使用
  • 普通集群模式: 普通集群模式指的是在多台机器上创建 rabbitmq 实例,一台机器一个,然后将创建的队列放入其中一个实例,但是其它的实例都会同步队列元数据(也就是其它实例会根据队列元数据找到队列所在的实例,从而拉取到消息),生产的消息放入队列(实际上是队列所在的实例),消费时,如果连接的是队列所在的实例则直接消费消息,如果是其它是咧,则会根据元数据找到队列所在实例再消费消息。此模式主要作用是用来提高吞吐量的,也就是让集群中的多个节点来支持某个队列的读写操作
  • 镜像集群模式: 镜像集群模式可以说是真正意义上的高可用模式。在这种模式下,你创建的队列,无论是元数据还是队列中的消息都会存在每个实例上,也就是说每个实例都拥有队列的完整数据。当写入消息时,会自动把消息同步到所有实例的队列上。rabbitmq 有很好的管理控制台,可以在控制台通过新增策略来控制消息的同步,比如可以指定消息同步到所有节点上,也可以指定消息同步到指定数量的节点上。好处在于,当其中一个实例宕机了,消费这可以消费其它实例的消息,坏处是:一性能开销非常大;二是消息需要同步到所有实例上,对网络宽带的压力和消耗比较大。

如何保证消息的幂等性(重复消费消息):
mq 会出现重复发送消息的可能,这是无法保障的,但是出现重复消费消息是可以在系统中解决的

  • 唯一 id + 指纹码机制: 整体实现相对简单,需进行数据库写入,利用主键 id 去重
  • 利用 redis 的原子性实现: 会出现的问题:问题1:是否需要落库。如果落库,如何保证数据的一致性和原子性?
    问题2:如果不进行落库,缓存种的数据如果设置定时同步的策略?

如何保证消息可靠性:
在涉及到 mq 系统中,消息出现的地方是生产者、mq、消费者,所以这三个地方都可能出现消息丢失的情况。针对这三个地方的解决方案如下图:
在这里插入图片描述

  • producer: 开启 rabbitmq 事务后,当向 mq 中写入消息时,如果写入失败,发生异常,则事务回滚,生产者可尝试再次写入消息,等写入完成后则可提交事务,但是太消耗性能。在生产者中开启 confirm 后,每次写的消息都会分配配一个 id,当你写入成功后,mq 会回传一个 ack 消息(确认消息),告诉你这个消息写入成功了;当写入失败时回调你一个 nack 接口,告诉你写入失败了,这时候你可以重新写入,而且可以结合这个机制在自己内存中维护消息 id 的状态,即超过一定时间没接收到某个消息回调,那么你可以重试。这两种方式的最大区别在于事务是同步的,confirm 是异步,且事务耗费性能,一般使用 confirm。
  • mq: 开始 rabbitmq 持久化,也就是将将 队列数据(元数据和消息)持久化到磁盘,当 rabbitmq 挂掉重启时,会从磁盘里恢复数据。持久化一般分为两个步骤: 第一步是创建队列时将其设置为持久化,但是只是将队列元数据持久化到磁盘,并没有将消息数据持久化;第二步是将消息的 deliveryMode(传送方式)设置为 2,也就是将消息设置为持久化,当接收到消息后,会将其持久化到磁盘。这两种持久化必须同时设置才会实现真正的持久化。同时也可以结合此机制跟生产者的 confirm 模式共同作用,也就是消息成功持久化到磁盘了再发送 ack 消息,这样就可以保证消息从生产者到 mq 整个过程都不会丢失。
  • consumer: 关闭 rabbitmq 的 ack ,在 rabbitmq 中,当消息被消费者成功接收后,rabbitmq 会自动发送 ack ,直接默认你消费成功了。这时候就可以关闭自动 ack,在消费者本地手动 ack,也就是当消费者成功消费后调用接口发送 ack 来释放消息。

《You》

@

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值