精华内容
下载资源
问答
  • 常见的消息队列中间件介绍 题目 为什么使用消息队列?...Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什么区别,以及适合哪些场景?...消息中间件面试题:消息中间件的高可用 消息中间件面试题:如何保证消...

    常见的消息队列中间件介绍

    题目

    • 为什么使用消息队列?
    • 消息队列有什么优点和缺点?
    • Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什么区别,以及适合哪些场景?

    消息中间件各种面试题:
    消息中间件面试题:消息丢失怎么办?
    消息中间件面试题:消息队列的优缺点,区别
    消息中间件面试题:消息中间件的高可用
    消息中间件面试题:如何保证消息的顺序性
    消息中间件面试题:如何保证消息不被重复消费
    消息中间件面试题:如何解决消息队列的延时以及过期失效问题?消息队列满了以后该怎么处理?有几百万消息持续积压几小时呢?
    消息中间件面试题:如果让你写一个消息队列,该如何进行架构设计?

    问题目录见简书转载博客:https://www.jianshu.com/p/eaafb1581e55

    面试题剖析

    为什么使用消息队列

    先说一下消息队列常见的使用场景吧,其实场景有很多,但是比较核心的有 3 个:解耦异步削峰

    解耦

    看这么个场景。A 系统发送数据到 BCD 三个系统,通过接口调用发送。如果 E 系统也要这个数据呢?那如果 C 系统现在不需要了呢?A 系统负责人几乎崩溃......

     
    mq-1

    在这个场景中,A 系统跟其它各种乱七八糟的系统严重耦合,A 系统产生一条比较关键的数据,很多系统都需要 A 系统将这个数据发送过来。A 系统要时时刻刻考虑 BCDE 四个系统如果挂了该咋办?要不要重发,要不要把消息存起来?头发都白了啊!

    如果使用 MQ,A 系统产生一条数据,发送到 MQ 里面去,哪个系统需要数据自己去 MQ 里面消费。如果新系统需要数据,直接从 MQ 里消费即可;如果某个系统不需要这条数据了,就取消对 MQ 消息的消费即可。这样下来,A 系统压根儿不需要去考虑要给谁发送数据,不需要维护这个代码,也不需要考虑人家是否调用成功、失败超时等情况。

     
    mq-2

    总结:通过一个 MQ,Pub/Sub 发布订阅消息这么一个模型,A 系统就跟其它系统彻底解耦了。

    面试技巧:你需要去考虑一下你负责的系统中是否有类似的场景,就是一个系统或者一个模块,调用了多个系统或者模块,互相之间的调用很复杂,维护起来很麻烦。但是其实这个调用是不需要直接同步调用接口的,如果用 MQ 给它异步化解耦,也是可以的,你就需要去考虑在你的项目里,是不是可以运用这个 MQ 去进行系统的解耦。在简历中体现出来这块东西,用 MQ 作解耦。

    异步

    再来看一个场景,A 系统接收一个请求,需要在自己本地写库,还需要在 BCD 三个系统写库,自己本地写库要 3ms,BCD 三个系统分别写库要 300ms、450ms、200ms。最终请求总延时是 3 + 300 + 450 + 200 = 953ms,接近 1s,用户感觉搞个什么东西,慢死了慢死了。用户通过浏览器发起请求,等待个 1s,这几乎是不可接受的。

     
    mq-3

    一般互联网类的企业,对于用户直接的操作,一般要求是每个请求都必须在 200 ms 以内完成,对用户几乎是无感知的。

    如果使用 MQ,那么 A 系统连续发送 3 条消息到 MQ 队列中,假如耗时 5ms,A 系统从接受一个请求到返回响应给用户,总时长是 3 + 5 = 8ms,对于用户而言,其实感觉上就是点个按钮,8ms 以后就直接返回了,爽!网站做得真好,真快!

     
    mq-4

    削峰

    每天 0:00 到 12:00,A 系统风平浪静,每秒并发请求数量就 50 个。结果每次一到 12:00 ~ 13:00 ,每秒并发请求数量突然会暴增到 5k+ 条。但是系统是直接基于 MySQL 的,大量的请求涌入 MySQL,每秒钟对 MySQL 执行约 5k 条 SQL。

    一般的 MySQL,扛到每秒 2k 个请求就差不多了,如果每秒请求到 5k 的话,可能就直接把 MySQL 给打死了,导致系统崩溃,用户也就没法再使用系统了。

    但是高峰期一过,到了下午的时候,就成了低峰期,可能也就 1w 的用户同时在网站上操作,每秒中的请求数量可能也就 50 个请求,对整个系统几乎没有任何的压力。

    [图片上传失败...(image-6444f7-1548645188187)]

    如果使用 MQ,每秒 5k 个请求写入 MQ,A 系统每秒钟最多处理 2k 个请求,因为 MySQL 每秒钟最多处理 2k 个。A 系统从 MQ 中慢慢拉取请求,每秒钟就拉取 2k 个请求,不要超过自己每秒能处理的最大请求数量就 ok,这样下来,哪怕是高峰期的时候,A 系统也绝对不会挂掉。而 MQ 每秒钟 5k 个请求进来,就 2k 个请求出去,结果就导致在中午高峰期(1 个小时),可能有几十万甚至几百万的请求积压在 MQ 中。

     
    mq-6

    这个短暂的高峰期积压是 ok 的,因为高峰期过了之后,每秒钟就 50 个请求进 MQ,但是 A 系统依然会按照每秒 2k 个请求的速度在处理。所以说,只要高峰期一过,A 系统就会快速将积压的消息给解决掉。

    消息队列有什么优缺点

    优点上面已经说了,就是在特殊场景下有其对应的好处解耦异步削峰

    缺点有以下几个:

    • 系统可用性降低

      系统引入的外部依赖越多,越容易挂掉。本来你就是 A 系统调用 BCD 三个系统的接口就好了,人 ABCD 四个系统好好的,没啥问题,你偏加个 MQ 进来,万一 MQ 挂了咋整,MQ 一挂,整套系统崩溃的,你不就完了?如何保证消息队列的高可用,可以点击这里查看

    • 系统复杂度提高

      硬生生加个 MQ 进来,你怎么[保证消息没有重复消费]?怎么[处理消息丢失的情况]?怎么保证消息传递的顺序性?头大头大,问题一大堆,痛苦不已。

    • 一致性问题

      A 系统处理完了直接返回成功了,人都以为你这个请求就成功了;但是问题是,要是 BCD 三个系统那里,BD 两个系统写库成功了,结果 C 系统写库失败了,咋整?你这数据就不一致了。

    所以消息队列实际是一种非常复杂的架构,你引入它有很多好处,但是也得针对它带来的坏处做各种额外的技术方案和架构来规避掉,做好之后,你会发现,妈呀,系统复杂度提升了一个数量级,也许是复杂了 10 倍。但是关键时刻,用,还是得用的。

    Kafka、ActiveMQ、RabbitMQ、RocketMQ 有什么优缺点?

    特性ActiveMQRabbitMQRocketMQKafka
    单机吞吐量 万级,比 RocketMQ、Kafka 低一个数量级 同 ActiveMQ 10 万级,支撑高吞吐 10 万级,高吞吐,一般配合大数据类的系统来进行实时数据计算、日志采集等场景
    topic 数量对吞吐量的影响     topic 可以达到几百/几千的级别,吞吐量会有较小幅度的下降,这是 RocketMQ 的一大优势,在同等机器下,可以支撑大量的 topic topic 从几十到几百个时候,吞吐量会大幅度下降,在同等机器下,Kafka 尽量保证 topic 数量不要过多,如果要支撑大规模的 topic,需要增加更多的机器资源
    时效性 ms 级 微秒级,这是 RabbitMQ 的一大特点,延迟最低 ms 级 延迟在 ms 级以内
    可用性 高,基于主从架构实现高可用 同 ActiveMQ 非常高,分布式架构 非常高,分布式,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用
    消息可靠性 有较低的概率丢失数据 基本不丢 经过参数优化配置,可以做到 0 丢失 同 RocketMQ
    功能支持 MQ 领域的功能极其完备 基于 erlang 开发,并发能力很强,性能极好,延时很低 MQ 功能较为完善,还是分布式的,扩展性好 功能较为简单,主要支持简单的 MQ 功能,在大数据领域的实时计算以及日志采集被大规模使用

    综上,各种对比之后,有如下建议:

    一般的业务系统要引入 MQ,最早大家都用 ActiveMQ,但是现在确实大家用的不多了,没经过大规模吞吐量场景的验证,社区也不是很活跃,所以大家还是算了吧,我个人不推荐用这个了;

    后来大家开始用 RabbitMQ,但是确实 erlang 语言阻止了大量的 Java 工程师去深入研究和掌控它,对公司而言,几乎处于不可控的状态,但是确实人家是开源的,比较稳定的支持,活跃度也高;

    不过现在确实越来越多的公司,会去用 RocketMQ,确实很不错(阿里出品),但社区可能有突然黄掉的风险,对自己公司技术实力有绝对自信的,推荐用 RocketMQ,否则回去老老实实用 RabbitMQ 吧,人家有活跃的开源社区,绝对不会黄。

    所以中小型公司,技术实力较为一般,技术挑战不是特别高,用 RabbitMQ 是不错的选择;大型公司,基础架构研发实力较强,用 RocketMQ 是很好的选择。如果是大数据领域的实时计算、日志采集等场景,用 Kafka 是业内标准的,绝对没问题,社区活跃度很高,绝对不会黄,何况几乎是全世界这个领域的事实性规范。



    转载于:https://www.cnblogs.com/wuzm/p/11105176.html

    展开全文
  • 本文将从Kafka、RabbitMQ、ZeroMQ、RocketMQ、ActiveMQ这几个常见的消息中间件中进行选型对比。 一、各消息中间件介绍 Kafka: Kafka 是由 Apache 软件基金会开发一个开源流处理平台,由Scala和Java编写。...

    目录

    概述

    项目中消息中间件的选型

    一、消息中间件概述

    二、消息中间件区别及定义速览表

    三、存储方式概述

    四、负载均衡概述

    五、集群方式概述

    六、消息的订阅与发布概述

    七、消息确认机制概述

    八、消息重试概述

    九、消息中间件并发度概述

    十、管理界面友好程度


    概述

    在进行大型的、复杂的项目建设中,往往会涉及模块与模块之前的消息通信的问题,消息通信可以通过硬件设施或者软件设施来实现,通过硬件设施进行消息通信的就涉及比较高度安全和高度机密的政府及军用的通信了(通信成本高、时间长等特点),一般大、中、小型企业系统模块之前的通信都是通过消息中间件来实现的,如果再往高出走一点,就是企业自己根据业务需求,自己写一套复合自生业务发展的消息通信中间见咯。

    本文将从 Kafka、RabbitMQ、ZeroMQ、RocketMQ、ActiveMQ这几个常见的消息中间件中进行选型对比。

     

    项目中消息中间件的选型

    一、消息中间件概述

    Kafka

    Kafka 是由 Apache软件基金会开发的一个开源流处理平台,由 Scala语言和 Java语言编写。Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者在网站中的所有动作流数据。 这种动作(网页浏览,搜索和其他用户的行动)是在现代网络上的许多社会功能的一个关键因素。 这些数据通常是由于吞吐量的要求而通过处理日志和日志聚合来解决。 对于像Hadoop一样的日志数据和离线分析系统,但又要求实时处理的限制,这是一个可行的解决方案。Kafka的目的是通过Hadoop的并行加载机制来统一线上和离线的消息处理,也是为了通过集群来提供实时的消息。

    官网:http://kafka.apache.org/

     

    RabbitMQ

    RabbitMQ是实现了高级消息队列协议(AMQP)的开源消息代理软件(亦称面向消息的中间件)。RabbitMQ服务器是用Erlang语言编写的,而集群和故障转移是构建在开放电信平台框架上的。所有主要的编程语言均有与代理接口通讯的客户端库。

    官网:https://www.rabbitmq.com/

     

    ZeroMQ

    ZeroMQ(简称ZMQ)是一个基于消息队列的多线程网络库,是一个非常轻量级的消息中间件,其对套接字类型、连接处理、帧、甚至路由的底层细节进行抽象,提供跨越多种传输协议的套接字。

    ZMQ是网络通信中新的一层,介于应用层和传输层之间(按照TCP/IP划分),ZMQ是一个可伸缩层,可并行运行,分散在分布式系统间。

    ZMQ不是单独的服务,而是一个嵌入式库,它封装了网络通信、消息队列、线程调度等功能,向上层提供简洁的API,应用程序通过加载库文件,调用API函数来实现高性能网络通信。   

    官网:http://api.zeromq.org/

     

    RocketMQ

    RocketMQ是一款分布式、队列模型的消息中间件,是阿里巴巴集团自主研发的专业消息中间件,借鉴参考了 JMS规范的MQ实现,参考了优秀的开源消息中间件Kafka,实现了业务削峰,分布式事务的优秀框架。

    官网:http://rocketmq.apache.org/

     

    ActiveMQ

    ActiveMQ是 Apache软件基金会研发的开源消息中间件;由于 ActiveMQ是一个纯Java程序,因此只需要操作系统支持 Java虚拟机,ActiveMQ便可执行。

    官网:http://activemq.apache.org/

     

    二、消息中间件区别及定义速览表

     

    功能 Kafka RabbitMQ ZeroMQ RocketMQ ActiveMQ
    支持的协议 自己定义的一套(基于TCP的协议) AMQP TCP/UDP 自己定义的一套 OpenWire、STOMP、REST、XMPP、AMQP
    存储方式 内存、磁盘、数据库。支持大量堆积。 内存、磁盘。支持少量堆积。 消息发送端的内存或者磁盘中。不支持持久化。 磁盘。支持大量堆积。 内存、磁盘、数据库。支持少量堆积。
    事务支持 支持 支持,使用事务会使性能有所下降 不支持 支持 支持
    负载均衡 支持负载均衡 对负载均衡的支持不好 去中心化,不支持负载均衡,本身只是一个多线程网络库 支持负载均衡 支持负载均衡,需要通过集成zookeeper来实现负载均衡
    集群 天然的 Leader-Slave 无状态集群,每台服务器既是Master也是Slave。 支持简单集群,复制模式,对高级集群模式支持不好。 去中心化,不支持集群。 常用多对 Master-Slave 模式,开源版本需手动切换Slave变成Master。集群的slave会从master拉取数据备份,master分布在不同的broker上。 支持简单集群模式,比如'主-备',对高级集群模式支持不好。
    高可用 非常高(分布式) 高(主从) 非常高(分布式) 高(主从)
    消息重复 支持at least once、at most once 支持at least once、at most once 既不支持at least once、也不支持at most once、更不支持exactly only once 支持at least once 支持at least once

    吞吐量

    (TPS)

    灰常大,Kafka 按批次发送消息和消费消息 比较大 非常大 大,rocketMQ 接收端可以批量消费消息,可以配置每次消费的消息数,但是发送端不是批量发送。 比较大
    消息订阅与发布 基于topic以及按照topic进行正则匹配的发布订阅模式 提供了4种:direct, topic ,Headers和fanout 点对点(P2P) 基于topic/messageTag以及按照消息类型、属性进行正则匹配的发布订阅模式 点对点(P2P)、广播(发布-订阅)
    消息顺序支持 支持 不支持 不支持 支持 不支持
    消息确认支持 支持 支持 支持 支持 支持
    消息回溯支持 支持指定分区offset位置的回溯 不支持 不支持 支持指定时间点的回溯 不支持
    消息重试支持 不支持,但是可以实现 不支持,但是可以利用消息确认机制实现 不支持 支持 不支持
    并发度 极高
    管理界面 一般 一般

     

    三、存储方式概述

    Kafka

    内存、磁盘、数据库。支持大量堆积。

    Kafka 的最小存储单元是分区,一个 topic 包含多个分区,Kafka 创建 topic时,这些分区会被分配在多个服务器上,通常一个broker 一台服务器。 分区首领会均匀地分布在不同的服务器上,分区副本也会均匀的分布在不同的服务器上,确保负载均衡和高可用性,当新的 broker 加入集群的时候,部分副本会被移动到新的broker上。 根据配置文件中的目录清单,Kafka 会把新的分区分配给目录清单里分区数最少的目录。 默认情况下,分区通过使用轮询算法把消息均衡地分布在同一个 topic的不同分区中,对于发送时指定了 key的情况,会根据key的 hashcode取模后的值存到对应的分区中。

     

    RabbitMQ

    内存、磁盘。支持少量堆积。

    RabbitMQ 的消息分为持久化的消息和非持久化消息,不管是持久化的消息还是非持久化的消息都可以写入到磁盘。 持久化的消息在到达队列时就写入到磁盘,如果可以,持久化的消息也会在内存中保存一份备份,这样可以提高一定的性能,当内存吃紧的时候会从内存中清除。非持久化的消息一般只存在于内存中,在内存吃紧的时候会被换入到磁盘中,以节省内存。

    引入镜像队列机制,可将重要队列“复制”到集群中的其他 broker上,保证这些队列的消息不会丢失。配置镜像的队列,都包含一个主节点 master和多个从节点 slave,如果 master失效,加入时间最长的 slave会被提升为新的 master,除发送消息外的所有动作都向 master发送,然后由 master将命令执行结果广播给各个 slave,RabbitMQ 会让 master均匀地分布在不同的服务器上,而同一个队列的 slave也会均匀地分布在不同的服务器上,保证负载均衡和高可用性。

     

    ZeroMQ

    消息发送端的内存或者磁盘中,不支持持久化。

     

    RocketMQ

    磁盘。支持大量堆积。

    commitLog 文件存放实际的消息数据,每个 commitLog上限是1G,满了之后会自动新建一个 commitLog文件保存数据。ConsumeQueue队列只存放offset、size、tagcode,非常小,分布在多个broker上。ConsumeQueue 相当于 CommitLog的索引文件,消费者消费时会从 consumeQueue中查找消息在 commitLog中的offset,再去 commitLog中查找元数据。

    ConsumeQueue存储格式的特性,保证了写过程的顺序写盘(写CommitLog文件),大量数据IO都在顺序写同一个commitLog,满1G了再写新的。加上 RocketMQ是累计4K才强制从 PageCache中刷到磁盘(缓存),所以高并发写性能突出。

     

    ActiveMQ

    内存、磁盘、数据库。支持少量堆积。

     

    四、负载均衡概述

    Kafka

    支持负载均衡。

    1、一个 broker通常就是一台服务器节点。对于同一个 Topic的不同分区,Kafka会尽力将这些分区分布到不同的 Broker服务器上,zookeeper 保存了broker、Topic和分区的元数据信息。分区 Leader会处理来自客户端的生产请求,kafka分区 Leader会被分配到不同的 broker服务器上,让不同的 broker服务器共同分担任务。每一个 broker都缓存了元数据信息,客户端可以从任意一个 broker获取元数据信息并缓存起来,根据元数据信息知道要往哪里发送请求。

    2、kafka的消费者组订阅同一个Topic,会尽可能地使得每一个消费者分配到相同数量的分区,分摊负载。

    3、当消费者加入或者退出消费者组的时候,还会触发再均衡,为每一个消费者重新分配分区,分摊负载。kafka的负载均衡大部分是自动完成的,分区的创建也是自动完成的,隐藏了很多细节,避免了繁琐的配置和人为疏忽造成的负载问题。

    4、发送端由 Topic和 Key来决定消息发往哪个分区,如果 Key为null,那么会使用轮询算法将消息均衡地发送到同一个 Topic的不同分区中。如果 Key不为null,那么会根据 Key的hashcode取模计算出要发往的分区。

     

    RabbitMQ

    对负载均衡的支持不好。

    1、消息被投递到哪个队列是由 exchang和 key决定的,exchang、key、queue都需要手动创建。

    RabbitMQ客户端发送消息要和 broker建立连接,需要事先知道 broker上有哪些 exchang,有哪些 queue。通常要声明要发送的目标 queue,如果没有目标 queue,会在 broker上创建一个 queue,如果有,就什么都不处理,接着往这个 queue中发送消息。假设大部分繁重任务的 queue都创建在同一个broker上,那么这个 broker的负载就会过大。(可以在上线前预先创建队列,无需声明要发送的队列,但是发送时不会尝试创建队列,可能出现找不到队列的问题,RabbitMQ 的备份 exchang会把找不到队列的消息保存到一个专门的队列中,以便以后查询使用)

    使用镜像队列机制建立 RabbitMQ集群可以解决 broker的负载就会过大的问题,形成 master-slave的架构,master节点会均匀分布在不同的服务器上,让每一台服务器分摊负载。slave节点只是负责转发,在 master失效时会选择加入时间最长的 slave成为master。

    当新节点加入镜像队列的时候,队列中的消息不会同步到新的slave中,除非调用同步命令,但是调用命令后,队列会阻塞,不能在生产环境中调用同步命令。

    2、当 RabbitMQ队列拥有多个消费者的时候,队列收到的消息将以轮询的分发方式发送给消费者。每条消息只会发送给订阅列表里的一个消费者,不会重复。这种方式非常适合扩展,而且是专门为并发程序设计的。如果某些消费者的任务比较繁重,那么可以设置 basicQos限制信道上消费者能保持的最大未确认消息的数量,在达到上限时,RabbitMQ不再向这个消费者发送任何消息。

    3、对于 RabbitMQ而言,客户端与集群建立的 TCP连接不是与集群中所有的节点建立连接,而是挑选其中一个节点建立连接。但是 RabbitMQ集群可以借助 HAProxy、LVS技术,或者在客户端使用算法实现负载均衡,引入负载均衡之后,各个客户端的连接可以分摊到集群的各个节点之中。

     

    RabbitMQ Client均衡算法:

    1. 轮询法。按顺序返回下一个服务器的连接地址;
    2. 加权轮询法。给配置高、负载低的机器配置更高的权重,让其处理更多的请求;而配置低、负载高的机器,给其分配较低的权重,降低其系统负载;
    3. 随机法。随机选取一个服务器的连接地址;
    4. 加权随机法。按照概率随机选取连接地址;
    5. 源地址哈希法。通过哈希函数计算得到的一个数值,用该数值对服务器列表的大小进行取模运算;
    6. 最小连接数法。动态选择当前连接数最少的一台服务器的连接地址;

     

    ZeroMQ

    去中心化,不支持负载均衡。本身只是一个多线程网络库。

     

    RocketMQ

    支持负载均衡。一个 broker通常是一个服务器节点,broker 分为 master和 slave,master和 slave存储的数据一样,slave从master同步数据。

    1、nameserver与每个集群成员保持心跳,保存着 Topic-Broker路由信息,同一个 Topic的队列会分布在不同的服务器上。

    2、发送消息通过轮询队列的方式发送,每个队列接收平均的消息量。发送消息指定 Topic、Tags、Keys,无法指定投递到哪个队列(没有意义,集群消费和广播消费跟消息存放在哪个队列没有关系)。

    Tags 选填,类似于 Gmail 为每封邮件设置的标签,方便服务器过滤使用。目前只支持每个消息设置一个 tag,所以,也可以类比为 Notify 的 MessageType 概念。

    Keys 选填,代表这条消息的业务关键词,服务器会根据 Keys 创建哈希索引,设置后, 可以在 Console 系统根据 Topic、Keys 来查询消息,由于是哈希索引,所以尽可能保证 Key唯一。

    3、RocketMQ的负载均衡策略规定:Consumer数量应该小于等于 Queue数量,如果 Consumer超过 Queue数量,那么多余的 Consumer 将不能消费消息。这一点和 Kafka是一致的,RocketMQ会尽可能地为每一个 Consumer分配相同数量的队列,分摊负载。

     

    ActiveMQ

    支持负载均衡。基于 zookeeper实现负载均衡。

     

    五、集群方式概述

    Kafka

    天然的 Leader-Slave 无状态集群,每台服务器既是Master 也是Slave。

    分区首领均匀地分布在不同的kafka服务器上,分区副本也均匀地分布在不同的kafka服务器上,所以每一台kafka服务器既含有分区首领,同时又含有分区副本,每一台kafka服务器是某一台kafka服务器的Slave,同时也是某一台kafka服务器的leader。

    kafka的集群依赖于zookeeper,zookeeper支持热扩展,所有的broker、消费者、分区都可以动态加入移除,而无需关闭服务,与不依靠zookeeper集群的mq相比,这是最大的优势。但是现在最新的 kafka版本已经有了自己的一套zk,如果在项目中使用kafka时,如果没有硬性的要求,可以使用kafka中的zk,功能和目的都是一样的。

     

    RabbitMQ

    支持简单集群,复制模式,对高级集群模式支持不好。

    rabbitmq的每一个节点,不管是单一节点系统或者是集群中的一部分,要么是内存节点,要么是磁盘节点,集群中至少要有一个是磁盘节点。

    在rabbitmq集群中创建队列,集群只会在单个节点创建队列进程和完整的队列信息(元数据、状态、内容),而不是在所有节点上创建。

    引入镜像队列,可以避免单点故障,确保服务的可用性,但是需要人为地为某些重要的队列配置镜像。

     

    ZeroMQ

    去中心化,不支持集群。

     

    RocketMQ

    常用多对 Master-Slave 模式,开源版本需手动切换Slave变成Master。集群的slave会从master拉取数据备份,master分布在不同的broker上。

    Name Server是一个几乎无状态节点,可集群部署,节点之间无任何信息同步。

    Broker部署相对复杂,Broker分为Master与Slave,一个Master可以对应多个Slave,但是一个Slave只能对应一个Master,Master与Slave的对应关系通过指定相同的BrokerName,不同的BrokerId来定义,BrokerId为0表示Master,非0表示Slave。Master也可以部署多个。每个Broker与Name Server集群中的所有节点建立长连接,定时注册Topic信息到所有Name Server。

    Producer与Name Server集群中的其中一个节点(随机选择)建立长连接,定期从Name Server取Topic路由信息,并向提供Topic服务的Master建立长连接,且定时向Master发送心跳。Producer完全无状态,可集群部署。

    Consumer与Name Server集群中的其中一个节点(随机选择)建立长连接,定期从Name Server取Topic路由信息,并向提供Topic服务的Master、Slave建立长连接,且定时向Master、Slave发送心跳。Consumer既可以从Master订阅消息,也可以从Slave订阅消息,订阅规则由Broker配置决定。

    客户端先找到NameServer, 然后通过NameServer再找到 Broker。

    一个topic有多个队列,这些队列会均匀地分布在不同的broker服务器上。rocketmq队列的概念和kafka的分区概念是基本一致的,kafka同一个topic的分区尽可能地分布在不同的broker上,分区副本也会分布在不同的broker上。

     

    ActiveMQ

    支持简单集群模式,比如'主-备',对高级集群模式支持不好。

     

    六、消息的订阅与发布概述

    Kafka

    Kafka是基于 topic以及按照 topic进行正则匹配的发布订阅模式。

    消息发送:

    发送端由 topic和 key来决定消息发往哪个分区,如果 key为null,那么会使用轮询算法将消息均衡地发送到同一个 topic的不同分区中。如果 key不为null,那么会根据 key的 hashcode取模计算出要发往的分区。

    消息接收:

    1、consumer向组协调器 broker发送心跳来维持和组的从属关系以及对分区的所有权关系,所有权关系一旦被分配就不会改变,除非发生再均衡(比如有一个consumer加入或者离开consumer group),consumer只会从对应的分区读取消息;

    2、kafka限制 consumer个数要少于分区个数,每个消息只会被同一个 consumer group的一个consumer消费(非广播);

    3、kafka的 consumer group订阅同一个topic,会尽可能地使得每一个 consumer分配到相同数量的分区,不同 consumer group订阅同一个 topic相互独立,同一个消息会被不同的 consumer group处理;

     

    RabbitMQ

    RabbitMQ提供了4种模式,即:direct、topic 、Headers和fanout。

    消息发送:

    首先,声明一个队列(新创建或已经存在的队列),队列是RabbitMQ基本存储单元,由 exchange和 key决定消息存储放在哪个队列中。

    • direct,发送到和 bindingKey完全匹配的队列;
    • topic,路由 key是含有"."的字符串,会发送到含有“*”、“#”进行模糊匹配的 bindingKey对应的队列;
    • headers,与 key无关,是消息内容的 headers属性(一个键值对)和绑定键值对完全匹配时,才会发送到此队列。此方式性能极低一般不使用;
    • fanout,与 key无关,消息会发送到所有和 exchange绑定的队列中;

    消息接收:

    RabbitMQ 的队列是基本存储单元,不再被分区或者分片,对于已经创建了的队列,消费端要指定从哪一个队列接收消息。

    当 RabbitMQ队列拥有多个消费者的时候,队列收到的消息将以轮询的方式分发给消费者。每条消息只会发送给订阅列表里的一个消费者,不会重复发送,这种方式非常适合扩展,而且是专门为并发程序设计的。

    如果某些消费者的任务比较繁重,那么可以设置 basicQos限制信道上消费者能保持的最大未确认消息的数量,在达到上限时,RabbitMQ不再向这个消费者发送任何消息。

     

    ZeroMQ

    ZeroMQ的消息发布与订阅是点对点(p2p)的方式。

     

    RocketMQ

    RocketMQ是基于topic、messageTag以及按照消息类型、属性进行正则匹配的发布订阅模式。

    消息发送:

    发送消息通过轮询队列的方式发送,每个队列接收平均的消息量。发送消息需要依赖于topic、tags、keys,无法指定投递到哪个具体的队列,指定了也没有意义,集群消费和广播消费跟消息存放在哪个队列没有任何关系。

    tags可以不指定,tag类似于 Gmail为每封邮件设置的标签,方便服务器过滤使用。目前只支持每个消息设置一个 tag,所以也可以类比为 Notify 的 MessageType 概念。

    keys可以不指定,key代表这条消息的业务关键词,服务器会根据 keys创建哈希索引,设置后,可以在 Console系统根据 Topic、Keys 来查询消息,由于是哈希索引,所以需要尽可能保证 key唯一性。

    消息接收:

    1、广播消费,一条消息被多个 consumer消费,即使 consumer属于同一个 consumer group,消息也会被 consumer group中的每个 consumer都消费一次。

    2、集群消费,一个 consumer group中的 consumer实例平均分摊消费消息。例如某个topic有 9 条消息,其中一个 consumer group有3个实例,那么每个实例只消费其中的 3 条消息。即每一个队列都把消息轮流分发给每个 consumer。

     

    ActiveMQ

    ActiveMQ是点对点(p2p)、广播(发布-订阅)的发布订阅模式。点对点模式,即每个消息对应1个消费者;发布/订阅模式,每个消息对应多个消费者。

    消息发送:

    1. 点对点模式,先要指定一个队列,这个队列已经存在或者新创建;
    2. 发布/订阅模式,先要指定一个 topic,这个topic已经存在或者新创建;

    消息接收:

    1. 点对点模式:对于已经创建了的队列,消费端要指定从哪一个队列接收消息;
    2. 发布/订阅模式:对于已经创建了的topic,消费端要指定订阅哪一个topic的消息;

     

    七、消息确认机制概述

    Kafka

    Kafka支持消息确认,Kafka的消息确认分为两方面,一个是消息发送方确认,一个是消息接收方确认:

    1、发送方确认机制

    • ack=0,不管消息是否成功写入分区;
    • ack=1,消息成功写入首领分区后,返回成功;
    • ack=all,消息成功写入所有分区后,返回成功;

    2、接收方确认机制

    通过自动或者手动提交分区偏移量来实现,早期版本的 Kafka偏移量是提交给 Zookeeper的,这样使得 Zookeeper的压力比较大,现在新版本的 Kafka的偏移量都是提交给 Kafka服务器端的,不再依赖于 Zookeeper,这样以来 Kafka集群的性能会更加稳定。

     

    RabbitMQ

    RabbitMQ支持消息确认,RabbitMQ的消息确认分为两方面,一个是消息发送方确认,一个是消息接收方确认:

    1、发送方确认。消息被投递到所有匹配的队列后,返回成功。如果消息和队列是可持久化的,那么在写入磁盘后,返回成功。支持批量确认和异步确认。

    2、接收方确认机制,设置autoAck为false,需要显式确认,设置autoAck为true,自动确认。

    当autoAck为false的时候,rabbitmq队列会分成两部分,一部分是等待投递给consumer的消息,一部分是已经投递但是没收到确认的消息。如果一直没有收到确认信号,并且consumer已经断开连接,rabbitmq会安排这个消息重新进入队列,投递给原来的消费者或者下一个消费者。

    未确认的消息不会有过期时间,如果一直没有确认,并且没有断开连接,rabbitmq会一直等待,rabbitmq允许一条消息处理的时间可以很久很久。

     

    ZeroMQ

    ZeroMQ支持消息确认。

     

    RocketMQ

    RocketMQ支持消息确认。

     

    ActiveMQ

    ActiveMQ支持消息确认。

     

    八、消息重试概述

    Kafka:Kafka不支持消息重试,但是可以实现。kafka支持指定分区 offset位置的回溯,可以实现消息重试。

     

    RabbitMQ:RabbitMQ不支持消息重试,但是可以利用消息确认机制实现。RabbitMQ接收方确认机制,设置 autoAck为false来实现。当 autoAck设为false的时候,RabbitMQ队列会分成两部分,一部分是等待投递给 consumer的消息,一部分是已经投递但是没收到确认的消息。如果一直没有收到确认信号,并且 consumer已经断开连接,RabbitMQ会安排这个消息重新进入队列,投递给原来的消费者或者下一个消费者。

     

    ZeroMQ:ZeroMQ不支持消息重试。

     

    RocketMQ:RocketMQ支持消息重试。消息消费失败的大部分场景下,立即重试99%都会失败,所以RocketMQ的策略是在消费失败时定时重试,每次时间间隔相同。

    1、发送端的 send方法本身支持内部重试,重试逻辑如下:

    • 最多重试3次;
    • 如果发送失败,则轮转到下一个broker;
    • send方法的总耗时不超过 sendMsgTimeout设置的值,默认 10s,超过时间不再重试;

    2、接收端的 Consumer 消费消息失败后,要提供一种重试机制,使消息再消费一次。Consumer 消费消息失败通常可以分为以下两种情况:

    • 消息本身的原因。例如反序列化失败,消息数据本身无法处理等。定时重试机制,比如过 10s 秒后再重试。
    • 依赖的下游应用服务不可用,例如 DB连接不可用,系统外部网络不可达等。即使跳过当前失败的消息,消费其他消息同样也会失败。这种情况可以 sleep 30s 再消费下一条消息,减轻 Broker重试消息的压力。

     

    ActiveMQ:ActiveMQ不支持消息重试。

     

    九、消息中间件并发度概述

    Kafka

    高,一个线程一个消费者,kafka限制消费者的个数要小于等于分区数,如果要提高并行度,可以在消费者中再开启多线程,或者增加consumer实例数量。

     

    RabbitMQ

    极高,RabbitMQ本身是用 Erlang语言写的,并发性能高。

    可在消费者中开启多线程,最常见的做法是一个 channel对应一个消费者,每一个线程对应一个 channel,多个线程复用 connection的tcp连接,减少性能开销。

    当 RabbitMQ队列拥有多个消费者的时候,队列收到的消息将以轮询的方式发送给消费者。每条消息只会发送给订阅列表里的一个消费者,不会重复发送。

    如果某些消费者的任务比较繁重,那么可以设置 basicQos限制信道上消费者能保持的最大未确认消息的数量,在达到上限时,RabbitMQ不再向这个消费者发送任何消息。

     

    ZeroMQ

    ZeroMQ的并发度高。

     

    RocketMQ

    RocketMQ的并发度高RocketMQ限制消费者的个数少于等于队列数,但是可以在消费者中再开启多线程,这一点和 kafka是一致的,提高并行度的方法相同。

    同一个网络连接时,客户端多个线程可以同时发送请求,连接会被复用,减少系统性能开销。

    如何修改RocketMQ消费的并发度:

    1. 同一个 ConsumerGroup 下,通过增加 Consumer 实例数量来提高并发度,超过订阅队列数的 Consumer实例无效。
    2. 提高单个 Consumer 的消费并行线程,通过修改参数consumeThreadMin、consumeThreadMax

     

    ActiveMQ

    ActiveMQ并发度高。单个 ActiveMQ的接收和消费消息的速度在1万/秒(持久化一般为1-2万,非持久化2万以上),也就是说,如果部署 10个ActiveMQ就能达到10万/秒以上的并发度,部署越多的 ActiveMQ broker 在 MQ上 latency也就越低,系统吞吐量也就越高。

     

    十、管理界面友好程度

    Kafka:一般

    RabbitMQ:好

    ZeroMQ:无

    RocketMQ:无

    ActiveMQ:一般

     

     

     

     

     


     好了,关于 项目中如何选择消息中间件?消息中间件的选型? 就写到这儿了,如果还有什么疑问或遇到什么问题欢迎扫码提问,也可以给我留言哦,我会一一详细的解答的。 
    歇后语:“ 共同学习,共同进步 ”,也希望大家多多关注CSND的IT社区。


    作       者: 华    仔
    联系作者: who.seek.me@java98k.vip
    来        源: CSDN (Chinese Software Developer Network)
    原        文: https://blog.csdn.net/Hello_World_QWP/article/details/103628314
    版权声明: 本文为博主原创文章,请在转载时务必注明博文出处!
    展开全文
  • 面试题剖析为什么使用消息队列先说一下消息队列常见的使用场景吧,其实场景有很多,但是比较核心有 3 个:解耦、异步、削峰。解耦看这么个场景。A 系统发送数据到 BCD 三个系统,通过接口调用发送。如果 E 系统也...

    题目

    为什么使用消息队列?

    消息队列有什么优点和缺点?

    Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什么区别,以及适合哪些场景?

    面试题剖析

    为什么使用消息队列

    先说一下消息队列常见的使用场景吧,其实场景有很多,但是比较核心的有 3 个:解耦、异步、削峰。

    解耦

    看这么个场景。A 系统发送数据到 BCD 三个系统,通过接口调用发送。如果 E 系统也要这个数据呢?那如果 C 系统现在不需要了呢?A 系统负责人几乎崩溃......

    mq-1

    在这个场景中,A 系统跟其它各种乱七八糟的系统严重耦合,A 系统产生一条比较关键的数据,很多系统都需要 A 系统将这个数据发送过来。A 系统要时时刻刻考虑 BCDE 四个系统如果挂了该咋办?要不要重发,要不要把消息存起来?头发都白了啊!

    如果使用 MQ,A 系统产生一条数据,发送到 MQ 里面去,哪个系统需要数据自己去 MQ 里面消费。如果新系统需要数据,直接从 MQ 里消费即可;如果某个系统不需要这条数据了,就取消对 MQ 消息的消费即可。这样下来,A 系统压根儿不需要去考虑要给谁发送数据,不需要维护这个代码,也不需要考虑人家是否调用成功、失败超时等情况。

    mq-2

    总结:通过一个 MQ,Pub/Sub 发布订阅消息这么一个模型,A 系统就跟其它系统彻底解耦了。

    面试技巧:你需要去考虑一下你负责的系统中是否有类似的场景,就是一个系统或者一个模块,调用了多个系统或者模块,互相之间的调用很复杂,维护起来很麻烦。但是其实这个调用是不需要直接同步调用接口的,如果用 MQ 给它异步化解耦,也是可以的,你就需要去考虑在你的项目里,是不是可以运用这个 MQ 去进行系统的解耦。在简历中体现出来这块东西,用 MQ 作解耦。

    异步

    再来看一个场景,A 系统接收一个请求,需要在自己本地写库,还需要在 BCD 三个系统写库,自己本地写库要 3ms,BCD 三个系统分别写库要 300ms、450ms、200ms。最终请求总延时是 3 + 300 + 450 + 200 = 953ms,接近 1s,用户感觉搞个什么东西,慢死了慢死了。用户通过浏览器发起请求,等待个 1s,这几乎是不可接受的。

    mq-3

    一般互联网类的企业,对于用户直接的操作,一般要求是每个请求都必须在 200 ms 以内完成,对用户几乎是无感知的。

    如果使用 MQ,那么 A 系统连续发送 3 条消息到 MQ 队列中,假如耗时 5ms,A 系统从接受一个请求到返回响应给用户,总时长是 3 + 5 = 8ms,对于用户而言,其实感觉上就是点个按钮,8ms 以后就直接返回了,爽!网站做得真好,真快!

    mq-4

    削峰

    每天 0:00 到 12:00,A 系统风平浪静,每秒并发请求数量就 50 个。结果每次一到 12:00 ~ 13:00 ,每秒并发请求数量突然会暴增到 5k+ 条。但是系统是直接基于 MySQL 的,大量的请求涌入 MySQL,每秒钟对 MySQL 执行约 5k 条 SQL。

    一般的 MySQL,扛到每秒 2k 个请求就差不多了,如果每秒请求到 5k 的话,可能就直接把 MySQL 给打死了,导致系统崩溃,用户也就没法再使用系统了。

    但是高峰期一过,到了下午的时候,就成了低峰期,可能也就 1w 的用户同时在网站上操作,每秒中的请求数量可能也就 50 个请求,对整个系统几乎没有任何的压力。

    [图片上传失败...(image-6444f7-1548645188187)]

    如果使用 MQ,每秒 5k 个请求写入 MQ,A 系统每秒钟最多处理 2k 个请求,因为 MySQL 每秒钟最多处理 2k 个。A 系统从 MQ 中慢慢拉取请求,每秒钟就拉取 2k 个请求,不要超过自己每秒能处理的最大请求数量就 ok,这样下来,哪怕是高峰期的时候,A 系统也绝对不会挂掉。而 MQ 每秒钟 5k 个请求进来,就 2k 个请求出去,结果就导致在中午高峰期(1 个小时),可能有几十万甚至几百万的请求积压在 MQ 中。

    mq-6

    这个短暂的高峰期积压是 ok 的,因为高峰期过了之后,每秒钟就 50 个请求进 MQ,但是 A 系统依然会按照每秒 2k 个请求的速度在处理。所以说,只要高峰期一过,A 系统就会快速将积压的消息给解决掉。

    消息队列有什么优缺点

    优点上面已经说了,就是在特殊场景下有其对应的好处,解耦、异步、削峰。

    缺点有以下几个:

    系统可用性降低

    系统引入的外部依赖越多,越容易挂掉。本来你就是 A 系统调用 BCD 三个系统的接口就好了,人 ABCD 四个系统好好的,没啥问题,你偏加个 MQ 进来,万一 MQ 挂了咋整,MQ 一挂,整套系统崩溃的,你不就完了?如何保证消息队列的高可用,可以点击这里查看。

    系统复杂度提高

    硬生生加个 MQ 进来,你怎么[保证消息没有重复消费]?怎么[处理消息丢失的情况]?怎么保证消息传递的顺序性?头大头大,问题一大堆,痛苦不已。

    一致性问题

    A 系统处理完了直接返回成功了,人都以为你这个请求就成功了;但是问题是,要是 BCD 三个系统那里,BD 两个系统写库成功了,结果 C 系统写库失败了,咋整?你这数据就不一致了。

    所以消息队列实际是一种非常复杂的架构,你引入它有很多好处,但是也得针对它带来的坏处做各种额外的技术方案和架构来规避掉,做好之后,你会发现,妈呀,系统复杂度提升了一个数量级,也许是复杂了 10 倍。但是关键时刻,用,还是得用的。

    Kafka、ActiveMQ、RabbitMQ、RocketMQ 有什么优缺点?

    特性ActiveMQRabbitMQRocketMQKafka

    单机吞吐量

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

    同 ActiveMQ

    10 万级,支撑高吞吐

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

    topic 数量对吞吐量的影响

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

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

    时效性

    ms 级

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

    ms 级

    延迟在 ms 级以内

    可用性

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

    同 ActiveMQ

    非常高,分布式架构

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

    消息可靠性

    有较低的概率丢失数据

    基本不丢

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

    同 RocketMQ

    功能支持

    MQ 领域的功能极其完备

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

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

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

    综上,各种对比之后,有如下建议:

    一般的业务系统要引入 MQ,最早大家都用 ActiveMQ,但是现在确实大家用的不多了,没经过大规模吞吐量场景的验证,社区也不是很活跃,所以大家还是算了吧,我个人不推荐用这个了;

    后来大家开始用 RabbitMQ,但是确实 erlang 语言阻止了大量的 Java 工程师去深入研究和掌控它,对公司而言,几乎处于不可控的状态,但是确实人家是开源的,比较稳定的支持,活跃度也高;

    不过现在确实越来越多的公司,会去用 RocketMQ,确实很不错(阿里出品),但社区可能有突然黄掉的风险,对自己公司技术实力有绝对自信的,推荐用 RocketMQ,否则回去老老实实用 RabbitMQ 吧,人家有活跃的开源社区,绝对不会黄。

    所以中小型公司,技术实力较为一般,技术挑战不是特别高,用 RabbitMQ 是不错的选择;大型公司,基础架构研发实力较强,用 RocketMQ 是很好的选择。如果是大数据领域的实时计算、日志采集等场景,用 Kafka 是业内标准的,绝对没问题,社区活跃度很高,绝对不会黄,何况几乎是全世界这个领域的事实性规范。

    展开全文
  • Kafka、RabbitMQ、RocketMQ等消息中间件的对比 —— 消息发送性能和区别 那么,消息中间件性能究竟哪家强? 带着这个疑问,我们中间件测试组对常见的三类消息产品(Kafka、RabbitMQ、RocketMQ)做了性能比较。 Kafka是...

    Kafka、RabbitMQ、RocketMQ等消息中间件的对比 —— 消息发送性能和区别

    那么,消息中间件性能究竟哪家强?

    带着这个疑问,我们中间件测试组对常见的三类消息产品(Kafka、RabbitMQ、RocketMQ)做了性能比较。

    Kafka是LinkedIn开源的分布式发布-订阅消息系统,目前归属于Apache顶级项目。Kafka主要特点是基于Pull的模式来处理消息消费,追求高吞吐量,一开始的目的就是用于日志收集和传输。0.8版本开始支持复制,不支持事务,对消息的重复、丢失、错误没有严格要求,适合产生大量数据的互联网服务的数据收集业务。

    RabbitMQ是使用Erlang语言开发的开源消息队列系统基于AMQP协议来实现AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全。AMQP协议更多用在企业系统内,对数据一致性、稳定性和可靠性要求很高的场景,对性能和吞吐量的要求还在其次。

    RocketMQ是阿里开源的消息中间件,它是纯Java开发,具有高吞吐量、高可用性、适合大规模分布式系统应用的特点。RocketMQ思路起源于Kafka,但并不是Kafka的一个Copy,它对消息的可靠传输及事务性做了优化,目前在阿里集团被广泛应用于交易、充值、流计算、消息推送、日志流式处理、binglog分发等场景。

    测试目的

    对比Kafka、RabbitMQ、RocketMQ发送小消息(124字节)的性能。这次压测我们只关注服务端的性能指标,所以压测的标准是:

    不断增加发送端的压力,直到系统吞吐量不再上升,而响应时间拉长。这时服务端已出现性能瓶颈,可以获得相应的系统最佳吞吐量。

    测试场景

    在同步发送场景中,三个消息中间件的表现区分明显:

    Kafka的吞吐量高达17.3w/s,不愧是高吞吐量消息中间件的行业老大。这主要取决于它的队列模式保证了写磁盘的过程是线性IO。此时broker磁盘IO已达瓶颈。

    RocketMQ也表现不俗,吞吐量在11.6w/s,磁盘IO %util已接近100%。RocketMQ的消息写入内存后即返回ack,由单独的线程专门做刷盘的操作,所有的消息均是顺序写文件

    RabbitMQ的吞吐量5.95w/s,CPU资源消耗较高。它支持AMQP协议,实现非常重量级,为了保证消息的可靠性在吞吐量上做了取舍。我们还做了RabbitMQ在消息持久化场景下的性能测试,吞吐量在2.6w/s左右。

    测试结论 在服务端处理同步发送的性能上,Kafka>RocketMQ>RabbitMQ。

    附录:

    测试环境

    服务端为单机部署,机器配置如下:

    应用版本:

    测试脚本

    前面我们对比了最简单的小消息发送场景,Kafka暂时胜出。但是,作为经受过历次双十一洗礼的RocketMQ,在互联网应用场景中更有它优越的一面。

    RabbitMQ

    是使用Erlang编写的一个开源的消息队列,本身支持很多的协议:AMQP,XMPP, SMTP, STOMP,也正是如此,使的它变的非常重量级,更适合于企业级的开发。同时实现了一个经纪人(Broker)构架,这意味着消息在发送给客户端时先在中心队列排队。对路由(Routing),负载均衡(Load balance)或者数据持久化都有很好的支持。

    Redis

    是一个Key-Value的NoSQL数据库,开发维护很活跃,虽然它是一个Key-Value数据库存储系统,但它本身支持MQ功能,所以完全可以当做一个轻量级的队列服务来使用。对于RabbitMQ和Redis的入队和出队操作,各执行100万次,每10万次记录一次执行时间。测试数据分为128Bytes、512Bytes、1K和10K四个不同大小的数据。实验表明:入队时,当数据比较小时Redis的性能要高于RabbitMQ,而如果数据大小超过了10K,Redis则慢的无法忍受;出队时,无论数据大小,Redis都表现出非常好的性能,而RabbitMQ的出队性能则远低于Redis。

    ZeroMQ

    号称最快的消息队列系统,尤其针对大吞吐量的需求场景。ZMQ能够实现RabbitMQ不擅长的高级/复杂的队列,但是开发人员需要自己组合多种技术框架,技术上的复杂度是对这MQ能够应用成功的挑战。ZeroMQ具有一个独特的非中间件的模式,你不需要安装和运行一个消息服务器或中间件,因为你的应用程序将扮演了这个服务角色。你只需要简单的引用ZeroMQ程序库,可以使用NuGet安装,然后你就可以愉快的在应用程序之间发送消息了。但是ZeroMQ仅提供非持久性的队列,也就是说如果down机,数据将会丢失。其中,Twitter的Storm中使用ZeroMQ作为数据流的传输。

    ActiveMQ

    是Apache下的一个子项目。 类似于ZeroMQ,它能够以代理人和点对点的技术实现队列。同时类似于RabbitMQ,它少量代码就可以高效地实现高级应用场景。RabbitMQ、ZeroMQ、ActiveMQ均支持常用的多种语言客户端 C++、Java、.Net,、Python、 Php、 Ruby等。

    Jafka/Kafka

    Kafka是Apache下的一个子项目,是一个高性能跨语言分布式Publish/Subscribe消息队列系统,而Jafka是在Kafka之上孵化而来的,即Kafka的一个升级版。具有以下特性:快速持久化,可以在O(1)的系统开销下进行消息持久化;高吞吐,在一台普通的服务器上既可以达到10W/s的吞吐速率;完全的分布式系统,Broker、Producer、Consumer都原生自动支持分布式,自动实现复杂均衡;支持Hadoop数据并行加载,对于像Hadoop的一样的日志数据和离线分析系统,但又要求实时处理的限制,这是一个可行的解决方案。Kafka通过Hadoop的并行加载机制来统一了在线和离线的消息处理,这一点也是本课题所研究系统所看重的。Apache Kafka相对于ActiveMQ是一个非常轻量级的消息系统,除了性能非常好之外,还是一个工作良好的分布式系统。

    rabbitmq比kafka可靠,kafka更适合IO高吞吐的处理,比如ELK日志收集

    Kafka和RabbitMq一样是通用意图消息代理,他们都是以分布式部署为目的。但是他们对消息语义模型的定义的假设是非常不同的。我对”AMQP 更成熟”这个论点是持怀疑态度的。让我们用事实说话来看看用什么解决方案来解决你的问题。   a) 以下场景你比较适合使用Kafka。你有大量的事件(10万以上/秒)、你需要以分区的,顺序的,至少传递成功一次到混杂了在线和打包消费的消费者、你希望能重读消息、你能接受目前是有限的节点级别高可用或则说你并不介意通过论坛/IRC工具得到还在幼儿阶段的软件的支持。   b) 以下场景你比较适合使用RabbitMQ。你有较少的事件(2万以上/秒)并且需要通过复杂的路由逻辑去找到消费者、你希望消息传递是可靠的、你并不关心消息传递的顺序、你需要现在就支持集群-节点级别的高可用或则说你需要7*24小时的付费支持(当然也可以通过论坛/IRC工具)。

    redis 消息推送(基于分布式 pub/sub)多用于实时性较高的消息推送,并不保证可靠。

    redis 消息推送(基于分布式 pub/sub)多用于实时性较高的消息推送,并不保证可靠。其他的mq和kafka保证可靠但有一些延迟(非实时系统没有保证延迟)。redis-pub/sub断电就清空,而使用redis-list作为消息推送虽然有持久化,但是又太弱智,也并非完全可靠不会丢。另外一点,redis 发布订阅除了表示不同的 topic 外,并不支持分组,比如kafka中发布一个东西,多个订阅者可以分组,同一个组里只有一个订阅者会收到该消息,这样可以用作负载均衡。比如,kafka 中发布:topic = “发布帖子” data=”文章1” 这个消息,后面有一百台服务器每台服务器都是一个订阅者,都订阅了这个 topic,但是他们可能分为三组,A组50台,用来真的做发布文章,A组50台里所有 subscriber 都订阅了这个topic。由于在同一组,这条消息 (topic=”发布帖子”, data=”文章1”)只会被A组里面一台当前空闲的机器收到。而B组25台服务器用于统计,C组25台服务器用于存档备份,每组只有一台会收到。用不同的组来决定每条消息要抄送出多少分去,用同组内哪些订阅者忙,哪些订阅者空闲来决定消息会被分到哪台服务器去处理,生产者消费者模型嘛。redis完全没有这类机制,这两点是最大的区别。

    redis是内存数据库!redis他爹做了disque,你要不要试试。mq一般都采用订阅~发布模型,如果你考虑性能,主要关注点就放在消费模型是pull还是push。影响最大的,应该是存储结构。kafka的性能要在topic数量小于64的时候,才能发挥威力。partition决定的。极限情况下丢消息,例如:主写入消息后,主机器宕机,并硬盘损坏。review代码的时候发现的。rabbit不知道,但是rocket的性能是(万条每秒),并且能够横向无限扩展,单机topic数量在256时,性能损失较小。rocket可以说是kafka的变种,是阿里在充分reviewkafka代码后,开发的metaQ。在不断更新,修补以后,阿里把metaQ3.0更名为rocket,并且rocket是java写的易于维护。另外就是rocket和kafka有类似无限堆积的能力。想想,断电不丢消息,积压两亿条消息毫无压力,niubilitykafka和rocket性能根本不是你需要考虑的问题。

    在应用场景方面,

    RabbitMQ,遵循AMQP协议,由内在高并发的erlanng语言开发,用在实时的对可靠性要求比较高的消息传递上。

    kafka是Linkedin于2010年12月份开源的消息发布订阅系统,它主要用于处理活跃的流式数据,大数据量的数据处理上。

    在架构模型方面,

    RabbitMQ遵循AMQP协议,RabbitMQ的broker由Exchange,Binding,queue组成,其中exchange和binding组成了消息的路由键;客户端Producer通过连接channel和server进行通信,Consumer从queue获取消息进行消费(长连接,queue有消息会推送到consumer端,consumer循环从输入流读取数据)。rabbitMQ以broker为中心;有消息的确认机制

    kafka遵从一般的MQ结构,producer,broker,consumer,以consumer为中心,消息的消费信息保存的客户端consumer上,consumer根据消费的点,从broker上批量pull数据;无消息确认机制

    在吞吐量,

    kafka具有高的吞吐量,内部采用消息的批量处理,zero-copy机制,数据的存储和获取是本地磁盘顺序批量操作,具有O(1)的复杂度,消息处理的效率很高。

    rabbitMQ在吞吐量方面稍逊于kafka,他们的出发点不一样,rabbitMQ支持对消息的可靠的传递,支持事务不支持批量的操作;基于存储的可靠性的要求存储可以采用内存或者硬盘。

    在可用性方面,

    rabbitMQ支持miror(镜像)的queue,主queue失效,miror queue接管。

    kafka的broker支持主备模式

    在集群负载均衡方面,

    kafka采用zookeeper对集群中的broker、consumer进行管理,可以注册topic到zookeeper上;通过zookeeper的协调机制,producer保存对应topic的broker信息,可以随机或者轮询发送到broker上;并且producer可以基于语义指定分片,消息发送到broker的某分片上。

    rabbitMQ的负载均衡需要单独的loadbalancer进行支持。

    Kafka是可靠的分布式日志存储服务。用简单的话来说,你可以把Kafka当作可顺序写入的一大卷磁带, 可以随时倒带,快进到某个时间点重放。先说下日志的定义:日志是数据库的核心,是对数据库的所有变更的严格有序记录,“表”是变更的结果。

    日志的其他名字有: Changelog, Write Ahead Log, Commit Log, Redo Log, Journaling.Kafka的特征如下:高写入速度:Kafka能以超过1Gbps NIC的速度写这盘磁带(实际可以到SATA 3速度,参考Benchmarking Apache Kafka: 2 Million Writes Per Second (On Three Cheap Machines)),充分利用了磁盘的物理特性,即,随机写入慢(磁头冲停),顺序写入快(磁头悬浮)。高可靠性: 通过zookeeper做分布式一致性,同步到任意多块磁盘上,故障自动切换选主,自愈。高容量:通过横向扩展,LinkedIn每日通过Kafka存储的新增数据高达175TB,8000亿条消息,可无限扩容,类似把两条磁带粘到一起。传统业务数据库的根本缺陷在于:1. 太慢,读写太昂贵,无法避免的随机寻址。(磁盘最快5ms寻址,固态又太昂贵。)2. 根本无法适应持续产生的数据流,越用越慢。(索引效率问题)3. 无法水平scale。(多半是读写分离,一主多备。另: NewSQL通过一致性算法,有多主。)针对这些问题,Kafka提出了一种方法: “log-centric approach(以日志为中心的方法)。”将传统数据库分为两个独立的系统,即日志系统和索引系统。“持久化和索引分开,日志尽可能快的落地,索引按照自己的速度追赶。”在数据可靠性在得到Kafka这种快速的,类似磁带顺序记录方式保障的大前提下。数据的呈现,使用方式变得非常灵活,可以根据需要将数据流同时送入搜索系统,RDBMS系统,数据仓库系统, 图数据库系统,日志分析等这些各种不同的数据库系统。 这些不同的系统只不过是一种对Kafka磁带数据的一种诠释,一个侧面,一个索引,一个快照。数据丢了,没关系,重放一遍磁带即可,更多的时候,对这些各式数据库系统的维护只是需要定期做一个快照,并拷贝到一个安全的对象存储(如S3) 而已。 一句话:“日志都是相同的日志,索引各有各的不同。”关于流计算:在以流为基本抽象的存储模型下,数据流和数据流之间,可以多流混合处理,或者流和状态,状态和状态的JOIN处理,这就是Kafka Stream提供的功能。 一个简单的例子是,在用户触发了某个事件后,和用户表混合处理,产生数据增补(Augment),再进入数据仓库进行相关性分析,一些简单的窗口统计和实时分析也很容易就能满足,比如 在收到用户登录消息的时候,在线人数+1, 离线的时候-1,反应出当前系统的在线用户总数。这方面可以参考PipelineDB https://www.pipelinedb.com/Kafka会让你重新思考系统的构建方式,使以前不可能的事变为可能,是一个系统中最重要的最核心的部分,不夸张的说,系统设计都需要围绕Kafka做。

    转载于:https://www.cnblogs.com/itxiaok/p/10356644.html

    展开全文
  • 消息中间件

    多人点赞 2019-08-07 20:05:15
    消息中间件,也可以叫做消息队列(区别于本地消息队列,本地消息队列指是JVM内队列实现),是一种独立队列系统,消息中间件经常被用来解决内部服务间异步调用问题 。请求服务方把请求放到队列中即可返回,然后...
  • 先说一下消息队列常见的使用场景吧,其实场景有很多,但是比较核心有 3 个:解耦、异步、削峰。 解耦 看这么个场景。A 系统发送数据到 BCD 三个系统,通过接口调用发送。如果 E 系统也要这个数据呢?那如...
  • 先说一下消息队列常见的使用场景吧,其实场景有很多,但是比较核心有 3 个:解耦、异步、削峰。 解耦 看这么个场景。A 系统发送数据到 BCD 三个系统,通过接口调用发送。如果 E 系统也要这...
  • 消息中间件小结

    2019-10-11 15:30:39
    文章目录消息中间件小结消息中间件概述什么是消息中间件消息中间件核心设计本质5大核心组成持久化消息分发高可用高可靠消息中间件的应用场景削峰限流解耦分布式事务的解决方案使用消息中间件带来的问题常见的消息...
  • 消息中间件,也可以叫做中央消息队列或者是消息队列(区别于本地消息队列,本地消息队列指是JVM内队列实现),是一种独立队列系统,消息中间件经常用来解决内部服务之间 异步调用问题 。请求服务方把请求...
  • 引言分布式系统中,我们广泛运用消息中间件进行系统间数据交换,便于异步解耦。现在开源的消息中间件有很多,前段时间我们自家产品 RocketMQ (MetaQ内核) 也顺利开源,得到大家关注。那么,消息中间件性能究竟...
  • 为什么使用消息队列? 消息队列有什么优点和缺点? Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什么区别,以及适合哪些场景? ...为什么使用消息队列 ...其实就是问问你消息队列都...先说一下消息队列常见的使用场..
  • 你们公司生产环境用是什么消息中间件?Kafka、ActiveMQ、RabbitMQ、RocketMQ 有什么优缺点?MQ 有哪些常见问题?如何解决这些问题?什么是RabbitMQ?rabbitmq 使用场景RabbitMQ基本概念RabbitMQ
  • 常见消息中间件的区别 AMQP的基本概念 RabbitMQ的消息模型 组件介绍 常用的5种消息模型 基本消息模型 work消息模型 订阅模型(三类) 订阅模型-Fanout 订阅模型-Direct 订阅模型-Topic RabbitMQ如何保证消息可靠性 ...
  • 对于消息中间件RabbitMQ,想必各位小伙伴并不陌生,其广泛应用程度不言而喻,此前我们也在许多课程以及诸多专栏文章中介绍了它应用,其应用场景也是相当广泛,像什么消息异步通信、服务模块解耦、高并发流量削峰...
  • 对于消息中间件RabbitMQ,想必各位小伙伴并不陌生,其广泛应用程度不言而喻,此前我们也在许多课程以及诸多专栏文章中介绍了它应用,其应用场景也是相当广泛,像什么消息异步通信、服务模块解耦、高并发流量削峰...
  • 对于消息中间件RabbitMQ,想必各位小伙伴并不陌生,其广泛应用程度不言而喻,此前我们也在许多课程以及诸多专栏文章中介绍了它应用,其应用场景也是相当广泛,像什么消息异步通信、服务模块解耦、高并发流量削峰...
  • 文章目录Redis是什么为什么使用Redis?Redis和mysql的区别Redis和memcached的对比为什么redis是 单线程模型也能效率...是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 ...
  • Redis是一个开源内存中数据结构存储系统,它可以用作:数据库、缓存和消息中间件。它支持多种类型数据结构,常见的数据结构类型有:字符串(Strings),散列(Hash),列表(List),集合(Set),有序集合...
  • 相关文章:Centos7.0 安装Redis 3.2.1详细过程和使用常见问题Redis简介Redis 是一个开源内存中数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型数据结构,如字符串(Strings),散列...
  • RPC和Http的区别

    2019-07-18 19:20:29
    什么是 RPC ? RPC (Remote Procedure Call)即远程过程...除 RPC 之外,常见的多系统数据交互方案还有分布式消息队列、HTTP 请求调用、数据库和分布式缓存等。 RPC 在我们熟知各种中间件中都有它身影。Nginx...
  • 一、Redis简介Redis 是一个开源内存中数据结构存储系统,它可以用作数据库、缓存和消息中间件。它支持多种类型数据结构,如字符串(Strings),散列(Hashes),列表(Lists),集合(Sets),有序集合(Sorted Sets...
  • 一、Redis简介Redis 是一个开源内存中数据结构存储系统,它可以用作数据库、缓存和消息中间件。它支持多种类型数据结构,如字符串(Strings),散列(Hashes),列表(Lists),集合(Sets),有序集合...
  • Redis 是一个开源内存中数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型数据结构,如字符串(Strings),散列(Hashes),列表(Lists),集合(Sets),有序集合(Sorted Sets或者是...

空空如也

空空如也

1 2 3
收藏数 55
精华内容 22
关键字:

常见消息中间件的区别