ActiveMQ、RocketMQ、RabbitMQ、Kafka区别

一、三大应用场景(优点)

解耦、异步、削峰

  • 解耦:只需要将消息写入消息队列,需要消息的去消息队列中订阅就好
  • 异步:一些非必要的逻辑可以采用异步来完成,从而提升响应速度
  • 削峰:某个时间段并发量特别大的时候可以将消息发送到消息队列中,然后从消息队列中慢慢拉取进行消费

解耦

传统模式:


image.png

传统模式缺点:
系统间耦合性太强,如上图所示,系统A在代码中直接调用系统B和系统C,如果将来系统D要接入,系统A还要修改代码,过于麻烦!


image.png

中间件模式优点:
将消息写入消息队列,要消息的系统自己从消息队列中订阅,从而系统A不再需要做任何修改

异步

传统模式:


image.png

一些非必要的业务逻辑以同步的方式运行,太耗费时间。

中间件模式:


image.png

中间件模式的优点:
将消息写入消息队列,非必要的业务逻辑以异步的方式运行,加快响应速度

削峰

传统模式:


image.png

传统模式缺点:
并发量大的时候,所有的请求直接怼到数据库,造成数据库连接异常

中间件模式:


image.png

中间件模式的优点:
系统A慢慢的按照数据库能处理的并发量,从消息队列中慢慢拉取消息。在生产中,这个短暂的高峰期积压是允许的。

二、消息队列的缺点

  1. 系统可用性降低:如系统原本运行的好好的,加入消息队列后一旦消息队列挂掉,系统直接就over了
  2. 增加系统的复杂度:采用消息队列后要考虑好多问题,如一致性、如何保证消息不被重复消费、消息的可靠传输

三、消息队列的选型

1、ActiveMQ:更新比较慢、java开发的、万级吞吐量
2、RabbitMQ:相对ActiveMQ来说更新较快、erlang语言开发(erlang语言天生具有高并发的特效,但是熟悉erlang的人相对较少,好在社区比较活跃)
3、RocketMQ:支持分布式架构、Java语言开发可以定制化开发
4、Kafka:支持分布式架构、吞吐量十万级


image.png

使用场景:
在我们的电商中,在发送短信和商品上下架的时候使用了rebbitMQ

四、保证消息队列的高可用

分析:在第二点说过了,引入消息队列后,系统可用性下降,在生产中,没人使用单机模式的消息队列,因为作为一个合格的程序员,应该对消息队列的高可用有很深刻的了解。
如果面试时问如何保证高可用?你的回答只是表明自己只会订阅和发布消息,面试官就会怀疑你是不是只是自己搭着玩,没有生产使用过。
以RCOKETMQ为例,它的集群就有多master模式、多master多slave异步复制模式、多master多slave同步双写模式。多master多slave模式部署架构图:


image.png

其实博主第一眼看到这个图,就觉得和kafka好像,只是NameServer集群,在kafka中用zookeeper代替,都是用来保存和发现master和slave用的,通信过程如下:
Producer与NameServer集群中的其中一个节点(随机)建立长连接,定期从NameServer获取Topic路由信息,并向提供Topic服务的Broker Master和Slave建立长连接,即可以从Broker Master订阅消息,也可以从Broker Slave订阅消息。

那么kafka呢,为了对比说明直接上kafka拓补结构:


image.png

如上图所示,一个典型的Kafka集群中包含若干Producer(可以是web前端产生的page view,或者是服务器日志,系统cpu,memory等),若干broker(Kafka支持水平扩展,一般broker数量越多,集群吞吐率越高),若干Consumer Group,以及一个Zookeeper集群。Kafka通过broker,Consumer使用pull模式从broker订阅并消费消息。
至于rabbitMQ也有普通集群和镜像集群模式,自行去了解,比较简单。

五、如何保证不会重复消费

1、RabbitMQ会发生一个ACK确认消息
2、RocketMQ会返回一个CONSUME_SUCCESS成功标志
3、Kafka每条消息会有一个offset,在消费后需要提交offset,让消息队列知道已经消费

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

分析:在使用消息队列过程中,应该做到消息不能多消费,也不能少消费。如果无法做到可靠性传输,可能给公司带来千万级别的财产损失。同样的,如果可靠性传输在使用过程中,没有考虑到,这不是给公司挖坑么。还是那句话,认真对待每一个项目,不要给公司挖坑。

三个角度:生产者弄丢数据消息队列弄丢数据消费者弄丢数据

RabbitMQ

  1. RabbitMQ提供transaction和confirm来保证生产者不丢消息
    1.1 transaction机制就是说在发送消息的时候开启事务<channel.txSelect()>,然后再发送消息,若发送过程中发生异常则会滚<channel.txRollback()>,成功则提交<channel.txCommit()>,缺点就是吞吐量下降
    1.2 confirm模式生产上用的居多,一旦channel进入confirm模式,所有在该信道上的消息都会被指派一个唯一ID(从1开始),一旦消息投递到所匹配的队列都,RabbitMQ会发送一个Ack(包含消息的唯一ID)给生产者,这就知道已经消费处理了,如果RabbitMQ没有处理这条消息,则会发送一个Nack消息给你,这就知道消费失败,然后就可以重试了。

  2. RabbitMQ消息队列丢数据
    2.1 处理消息队列丢数据的情况,一般是开启持久化磁盘的配置。这个持久化配置可以和confirm机制配合使用,你可以在消息持久化磁盘后,再给生产者发送一个Ack信号。这样,如果消息持久化磁盘之前,rabbitMQ阵亡了,那么生产者收不到Ack信号,生产者会自动重发。
    2.11 那么如何持久化呢,这里顺便说一下吧,其实也很容易,就下面两步
    2.11 1. 将queue的持久化标识durable设置为true,则代表是一个持久的队列
    2.11 2. 发送消息的时候将deliveryMode=2
    这样设置以后,rabbitMQ就算挂了,重启后也能恢复数据

  3. RabbitMQ消费者丢数据
    3.1 消费者丢数据一般是因为采用了自动确认消息模式(采用手动提交即可)

Kafka

这里先引用一张kafka replication的效果图


image.png

Producer在发布消息到某个Partition时,先通过zookeeper找到该partition的leader,然后无论该topic的replication factor为多少(也即该partition有多少个replication),Producer只将该消息发送到该Partition的leader,leader会将该消息写入本地log,每个Follower都从Leader中pull数据。

  1. Kafka生产丢失数据
    4.1 在kafka生产中,基本都有一个leader和多个follwer。follwer会去同步leader的信息。因此,为了避免生产者丢数据,做如下两点配置
    第一个配置要在producer端设置acks=all。这个配置保证了,follwer同步完成后,才认为消息发送成功。
    在producer端设置retries=MAX,一旦写入失败,这无限重试

  2. Kafka消息队列丢数据
    5.1 针对消息队列丢数据的情况,无外乎就是,数据还没同步,leader就挂了,这时zookpeer会将其他的follwer切换为leader,那数据就丢失了。针对这种情况,应该做两个配置。
    replication.factor参数,这个值必须大于1,即要求每个partition必须有至少2个副本
    min.insync.replicas参数,这个值必须大于1,这个是要求一个leader至少感知到有至少一个follower还跟自己保持联系。这两个配置加上上面生产者的配置联合起来用,基本可确保kafka不丢数据

  3. Kafka消费者丢数据
    6.1 这种情况一般是自动提交了offset,然后你处理程序过程中挂了。kafka以为你处理好了。解决方案也很简单,改成手动提交即可。
    6.2 offset介绍:
    6.21 offset:指的是kafka的topic中的每个消费组消费的下标。简单的来说就是一条消息对应一个offset下标,每次消费数据的时候如果提交offset,那么下次消费就会从提交的offset加一那里开始消费。
    比如一个topic中有100条数据,我消费了50条并且提交了,那么此时的kafka服务端记录提交的offset就是49(offset从0开始),那么下次消费的时候offset就从50开始消费。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,843评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,538评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,187评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,264评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,289评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,231评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,116评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,945评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,367评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,581评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,754评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,458评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,068评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,692评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,842评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,797评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,654评论 2 354

推荐阅读更多精彩内容