首先,MQ其实就是消息队列,队列我们可以理解为管道,以管道的方式做消息传递。
在本篇博客中,我们先来简单学习一下几种MQ,之后对他们进行对比。
ActiveMQ、RabbitMQ、kafka、RocketMQ

1. 介绍一下ActiveMQ /ApolloMQ

老牌的消息队列,使用Java语言编写。
  优点:老牌的消息队列,使用Java语言编写。对JMS(Java Message Service)支持最好,采用多线程并发,资源消耗比较大。如果你的主语言是Java,可以重点考虑。
  缺点:由于历史悠久,历史包袱较多,版本更新很缓慢。集群模式需要依赖Zookeeper实现。最新架构的产品被命名为Apollo,号称下一代ActiveMQ,目前案例较少。

JMS消息通常有两种类型:
  • 点对点(Point-to-Point):在点对点的消息系统中,消息分发给一个单独的使用者,点对点消息往往与队列相关联。
  • 发布/订阅(Publish/Subscribe):发布/订阅消息系统支持一个事件驱动模型,消息生产者和消费者都参与消息的传递。该类消息一般与特定的主题关联。
ActiveMQ的特点:
  1. 多种语言和协议编写客户端。语言:Java,C,C++,C#,Ruby,Perl,Python,PHP。应用协议: OpenWire,Stomp REST,WS Notification,XMPP,AMQP;
  2. 完全支持JMS和J2EE 1.4规范 (持久化,XA消息,事务);
  3. 对Spring的支持:activeMQ很容易内嵌到使用Spring的系统里,而且也支持Spring2.0的特性;
  4. 通过了常见的J2EE服务器的测试(J2EE服务器(如 Geronimo,JBoss 4,GlassFish,WebLogic))。其中通过JCA 1.5 resource adaptors的配置,可以让ActiveMQ可以自动的部署到任何兼容J2EE 1.4 商业服务器上;
  5. 支持多种传送协议:in-VM,TCP,SSL,NIO,UDP,JGroups,JXTA
  6. 支持通过JDBC和journal提供高速的消息持久化;
  7. 从设计上保证了高性能的集群,客户端-服务器,点对点;
  8. 支持Ajax
  9. 支持与Axis的整合
  10. 可以很容易得调用内嵌JMS provider,进行测试

AMQP 高级消息队列协议

AMQP,(Advanced Message Queueing Protocol 高级消息队列协议),是应用层协议的一个开放标准,为面向消息的中间件设计。
消息中间件主要用于组件之间的解耦,消息的发送者无需知道消息使用者的存在,反之亦然。 AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全

AMQP协议主要有3个组件:

  • 交换器(Exchange):它是发送消息的实体
  • 队列(Queue):它是接收消息的实体
  • 绑定器(Bind):将交换器和队列连接起来,并且封装消息的路由信息

2. 介绍一下RabbitMQ

RabbitMQ生态丰富,使用者众多。AMQP协议的领导实现,支持多种场景。 淘宝的MySQL集群内部有使用它进行通讯,OpenStack开源云平台的通信组件,最先在金融行业得到运用。

服务端语言:Erlang 天然集群化的。支持多种客户端,如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等,支持AJAX。用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。

接下来 我们来从以下几个方面介绍一下RabbitMQ:

  1. ConnectionFactory、Connection、Channel,连接和Channel接口;
  2. Queue 队列作为RabbitMQ的内部对象,用于存储消息;
  3. Message Acknowledgement 消费完消息之后进行一个发送消息回执的操作;
  4. Message durability 我们一般都对RabbitMQ中的消息设置为可持久化的
  5. Prefetch count 限制Queue给每一个消费者发送的消息数,消费者消费完了Queue再给他发
  6. Exchange 作为生产者和Queue之间的交换器(消息路由)
  7. routing key 指定消息的路由规则
  8. Binding 连接Exchange和Queue
  9. Binding key 在Binding Exchange和Queue的时候指定Binding key用于和Routing key匹配,才能将消息成功路由到对应的Queue中。
  10. Exchange Types 有fanout、direct、topic、headers四种类型(还有两个:system和自定义)
  11. RPC Remote Procedure Call 远程过程调用。consumer和producer之间进行同步,判断消息是否被执行等。

1. ConnectionFactory、Connection、Channel

ConnectionFactory、Connection、Channel都是RabbitMQ对外提供的API中最基本的对象。

  1. Connection是RabbitMQ的socket链接,它封装了socket协议相关部分逻辑。
  2. ConnectionFactory为Connection的制造工厂。
  3. Channel是我们与RabbitMQ打交道的最重要的一个接口,我们大部分的业务操作是在Channel这个接口中完成的,包括定义Queue、定义Exchange、绑定Queue与Exchange、发布消息等。

2.Queue

Queue(队列)是RabbitMQ的内部对象,用于存储消息,用下图表示。

RabbitMQ中的消息都只能存储在Queue中。生产者(下图中的P)生产消息并最终投递到Queue中,消费者(下图中的C)可以从Queue中获取消息并消费。

RabbitMQ中的消息都只能存储在Queue中,生产者生产消息投给Queue,消费者从Queue中获取消息并消费。
多个消费者订阅同一个消息服务(即订阅同一个Queue),Queue中的消息会被均分给多个消费者进行处理,而不是每一个消费者都收到所有的消息并处理

3. Message acknowledgment消息回执

在实际的应用中,可能会发生consumer收到Queue中的消息,但是没有处理完成就宕机或者发生其他异常,这种情况就可能导致消息丢失。
为了避免这种情况发生,我们可以要求消费者在消费完消息之后发送一个回执给RabbitMQ,RabbitMQ收到消息回执,之后才将该消息从Queue中移除;如果RabbitMQ没有收到一个回执并检测到消费者已经连接断开了,RabbitMQ就会将该消息发送给其他消费者进行处理。

这里不存在timeout的概念,一个consumer的消息处理的时间再长也不会导致该消息被发送给其他消费者,除非他的RabbitMQ的连接断开。
so,这样有一个缺点:如果消费者忘记了发送消息回执,那么Queue中的堆积的消息会more and more,消费者重启后还需要重复消费这些消息并重复执行业务逻辑。

pub message是没有ack的。

4.Message durability 消息持久化

我们希望在RabbitMQ重启之后依然不会丢失消息,我们可以将Queue与Message都设置为可持久化的(durable),这样可以保证绝大部分情况下我们的RabbitMQ消息不会丢失。

当然,还是会有小概率丢失事件:RabbitMQ服务器已经收到了生产者的消息,但是还没有来得及持久化该消息时RabbitMQ服务器就断电了。

5.Prefetch count

前面我们讲到如果有多个消费者同时订阅同一个Queue中的消息,Queue中的消息会被平摊给多个消费者。这时如果每个消息的处理时间不同,就有可能会导致某些消费者一直在忙,而另外一些消费者很快就处理完手头工作并一直空闲的情况。我们可以通过设置prefetchCount来限制Queue每次发送给每个消费者的消息数,比如我们设置prefetchCount=1,则Queue每次给每个消费者发送一条消息;消费者处理完这条消息后Queue会再给该消费者发送一条消息。

6.Exchange

在上一节我们看到生产者将消息投递到Queue中,实际上这在RabbitMQ中这种事情永远都不会发生。实际的情况是,生产者将消息发送到Exchange(交换器,下图中的X),由Exchange将消息路由到一个或多个Queue中(或者丢弃)。

Exchange是按照什么逻辑将消息路由到Queue的?这个将在Binding一节介绍。 RabbitMQ中的Exchange有四种类型,不同的类型有着不同的路由策略,这将在Exchange Types一节介绍。

routing key

生产者在将消息发送给Exchange的时候,一般会指定一个routing key,来指定这个消息的路由规则,而这个routing key需要与Exchange Type及binding key联合使用才能最终生效。 在Exchange Type与binding key固定的情况下(在正常使用时一般这些内容都是固定配置好的),我们的生产者就可以在发送消息给Exchange时,通过指定routing key来决定消息流向哪里。
RabbitMQ为routing key设定的长度限制为255 bytes

Binding

RabbitMQ中通过Binding将Exchange与Queue关联起来,这样RabbitMQ就知道如何正确地将消息路由到指定的Queue了。

Binding key

在绑定(Binding)Exchange与Queue的同时,一般会指定一个binding key;消费者将消息发送给Exchange时,一般会指定一个routing key;当binding key与routing key相匹配时,消息将会被路由到对应的Queue中。
这个将在Exchange Types章节会列举实际的例子加以说明。

在绑定多个Queue到同一个Exchange的时候,这些Binding允许使用相同的binding key。 **binding key 并不是在所有情况下都生效,它依赖于Exchange Type,**比如fanout类型的Exchange就会无视binding key,而是将消息路由到所有绑定到该Exchange的Queue。

Exchange Types

RabbitMQ常用的Exchange Type有fanout、direct、topic、headers这四种(AMQP规范里还提到两种Exchange Type,分别为system与自定义,这里不予以描述),下面分别进行介绍。

1. fanout

fanout类型的Exchange路由规则非常简单,它会把所有发送到该Exchange的消息路由到所有与它绑定的Queue中。

上图中,生产者(P)发送到Exchange(X)的所有消息都会路由到图中的两个Queue,并最终被两个消费者(C1与C2)消费。

2.direct

direct类型的Exchange路由规则也很简单,它会把消息路由到那些binding key与routing key完全匹配的Queue中。

以上图的配置为例,我们以routingKey=”error”发送消息到Exchange,则消息会路由到Queue1(amqp.gen-S9b…,这是由RabbitMQ自动生成的Queue名称)和Queue2(amqp.gen-Agl…);如果我们以routingKey=”info”或routingKey=”warning”来发送消息,则消息只会路由到Queue2。如果我们以其他routingKey发送消息,则消息不会路由到这两个Queue中。

3.topic

前面讲到direct类型的Exchange路由规则是完全匹配binding key与routing key,但这种严格的匹配方式在很多情况下不能满足实际业务需求。topic类型的Exchange在匹配规则上进行了扩展,它与direct类型的Exchage相似,也是将消息路由到binding key与routing key相匹配的Queue中,但这里的匹配规则有些不同,它约定:

  1. routing key为一个句点号“. ”分隔的字符串(我们将被句点号“. ”分隔开的每一段独立的字符串称为一个单词),如“stock.usd.nyse”、“nyse.vmw”、“quick.orange.rabbit”
  2. binding key与routing key一样也是句点号“. ”分隔的字符串
  3. binding key中可以存在两种特殊字符“ * ”与“# ”,用于做模糊匹配,其中 “ * ”用于匹配一个单词“ #”用于匹配多个单词(可以是零个)

以上图中的配置为例,routingKey=”quick.orange.rabbit”的消息会同时路由到Q1与Q2,routingKey=”lazy.orange.fox”的消息会路由到Q1与Q2,routingKey=”lazy.brown.fox”的消息会路由到Q2,routingKey=”lazy.pink.rabbit”的消息会路由到Q2(只会投递给Q2一次,虽然这个routingKey与Q2的两个bindingKey都匹配);routingKey=”quick.brown.fox”、routingKey=”orange”、routingKey=”quick.orange.male.rabbit”的消息将会被丢弃,因为它们没有匹配任何bindingKey。

4.headers

headers类型的Exchange不依赖于routing key与binding key的匹配规则来路由消息,而是根据发送的消息内容中的headers属性进行匹配。 在绑定Queue与Exchange时指定一组键值对;当消息发送到Exchange时,RabbitMQ会取到该消息的headers(也是一个键值对的形式),对比其中的键值对是否完全匹配Queue与Exchange绑定时指定的键值对;如果完全匹配则消息会路由到该Queue,否则不会路由到该Queue。

该类型的Exchange没有用到过(不过也应该很有用武之地),所以不做介绍。

RPC

MQ本身是基于异步的消息处理,前面的示例中所有的生产者(P)将消息发送到RabbitMQ后不会知道消费者(C)处理成功或者失败(甚至连有没有消费者来处理这条消息都不知道)。 但实际的应用场景中,我们很可能需要一些同步处理,需要同步等待服务端将我的消息处理完成后再进行下一步处理。这相当于RPC(Remote Procedure Call,远程过程调用)。在RabbitMQ中也支持RPC。

RabbitMQ 中实现RPC 的机制是:
  1. 客户端发送请求(消息)时,在消息的属性(MessageProperties ,在AMQP 协议中定义了14种properties ,这些属性会随着消息一起发送)中设置两个值replyTo (一个Queue 名称,用于告诉服务器处理完成后将通知我的消息发送到这个Queue 中)和correlationId (此次请求的标识号,服务器处理完成后需要将此属性返还,客户端将根据这个id了解哪条请求被成功执行了或执行失败)
  2. 服务器端收到消息并处理
  3. 服务器端处理完消息后,将生成一条应答消息到replyTo 指定的Queue ,同时带上correlationId 属性
  4. 客户端之前已订阅replyTo 指定的Queue ,从中收到服务器的应答消息后,根据其中的correlationId 属性分析哪条请求被执行了,根据执行结果进行后续业务处理

3. 介绍一下kafka

Kafka是一种分布式的,基于发布/订阅的消息系统。Kafka开发语言为Scala,支持跨平台。其设计主要目标如下:

  • 以时间复杂度为O(1)的方式提供消息持久化能力
  • 高吞吐率
  • 支持Kafka Server间的消息分区,及分布式消费,同时保证消息顺序传输
  • 支持离线数据处理和实时数据处理
  • 支持在线水平扩展
Kafka的优点:
  1. 分布式高可扩展。Kafka 集群可以透明的扩展,增加新的服务器进集群;
  2. 高性能。Kafka 的性能大大超过传统的ActiveMQ、RabbitMQ等MQ 实现,尤其是Kafka 还支持batch 操作;
  3. 容错。Kafka每个Partition的数据都会复制到几台服务器上。当某个Broker故障失效时,ZooKeeper服务将通知生产者和消费者,生产者和消费者转而使用其它Broker。
Kafka的不利:
  1. 重复消息。Kafka 只保证每个消息至少会送达一次,虽然几率很小,但一条消息有可能会被送达多次;
  2. 消息乱序。虽然一个Partition 内部的消息是保证有序的,但是如果一个Topic 有多个Partition,Partition 之间的消息送达不保证有序;
  3. 复杂性。Kafka需要zookeeper 集群的支持,Topic通常需要人工来创建,部署和维护较一般消息队列成本更高。

4. 介绍一下RocketMQ、Kafka

优点:专为海量消息传递打造,主张使用拉模式,天然的集群、HA、负载均衡支持。
缺点:所谓鱼和熊掌不可兼得,放弃了一些消息中间件的灵活性,使用的场景较窄,需关注你的业务模式是否契合,否则山寨变相使用很别扭。除此之外,RocketMQ没有.NET下的客户端可用。RocketMQ身出名门,但使用者不多,生态较小,毕竟消息量能达到这种体量的公司不多,你也可以直接去购买阿里云的消息服务。Kafka生态完善,其代码是用Scala语言写成,可靠性比RocketMQ低一些。

1. RabbitMQ,ActiveMq,ZeroMq比较

TPS比较:

ZeroMq 最好,RabbitMq 次之, ActiveMq 最差。

持久化消息:

ZeroMQ不支持。ActiveMQ和RabbitMQ都支持。

技术点:可靠性、灵活的路由、集群、事务、高可用的队列、消息排序、问题追踪、可视化管理工具、插件系统、社区活跃度

RabbitMq、kafka最好,ActiveMq次之,ZeroMq最差。当然ZeroMq也可以做到,不过自己必须手动写代码实现,代码量不小。尤其是可靠性中的:持久性、投递确认、发布者证实和高可用性。
所以在可靠性和可用性上,RabbitMQ是首选,虽然ActiveMQ也具备,但是它性能不及RabbitMQ。

高并发

从实现语言来看,RabbitMQ最高,原因是它的实现语言是天生具备高并发高可用的erlang语言。

2. RabbitMQ和kafka比较

1、 RabbitMq比kafka成熟,在可用性上,稳定性上,可靠性上,RabbitMq超过kafka

2、 Kafka设计的初衷就是处理日志的,可以看做是一个日志系统,针对性很强,所以它并没有具备一个成熟MQ应该具备的特性

3、 Kafka的性能(吞吐量、tps)比RabbitMq要强。

资料:https://www.sojson.com/blog/48.html
https://blog.csdn.net/qiqizhiyun/article/details/79848834

各个MQ消息队列介绍以及区别比较(RabbitMq ActiveMQ、ZeroMQ、Kafka)相关推荐

  1. 从mq服务器中获取消息命令,MQ服务消息队列介绍

    MQ服务消息队列介绍 资源简介MQ服务器端和客户端通信浅谈 1. WebSphere MQ的服务端的安装和配置 (1)创建名为venus.queue.manager的默认队列管理器. 在DOS窗口命令 ...

  2. IM开发基础知识补课(五):通俗易懂,正确理解并用好MQ消息队列

    1.引言 消息是互联网信息的一种表现形式,是人利用计算机进行信息传递的有效载体,比如即时通讯网坛友最熟悉的即时通讯消息就是其具体的表现形式之一. 消息从发送者到接收者的典型传递方式有两种: 1)一种我 ...

  3. 阿里云ACE共创空间——MQ消息队列产品测试

    一.产品背景 消息队列是阿里巴巴集团自主研发的专业消息中间件. 产品基于高可用分布式集群技术,提供消息订阅和发布.消息轨迹查询.定时(延时)消息.资源统计.监控报警等一系列消息云服务,是企业级互联网架 ...

  4. Spring Boot:使用Rabbit MQ消息队列

    综合概述 消息队列 消息队列就是一个消息的链表,可以把消息看作一个记录,具有特定的格式以及特定的优先级.对消息队列有写权限的进程可以向消息队列中按照一定的规则添加新消息,对消息队列有读权限的进程则可以 ...

  5. MQ消息队列产品测试

    2019独角兽企业重金招聘Python工程师标准>>> 一.产品背景 消息队列是阿里巴巴集团自主研发的专业消息中间件. 产品基于高可用分布式集群技术,提供消息订阅和发布.消息轨迹查询 ...

  6. MQ(消息队列)常见的应用场景解析

    MQ(消息队列)常见的应用场景解析 原文:MQ(消息队列)常见的应用场景解析 前言 提高系统性能首先考虑的是数据库的优化,之前一篇文章<数据库的使用你可能忽略了这些>中有提到过开发中,针对 ...

  7. MQ消息队列的使用场景

    一.消息队列概述 消息队列中间件是分布式系统中重要的组件,主要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构.目前使用较多的消息队列有ActiveMQ,Rabbit ...

  8. MQ消息队列使用场景

    一.消息队列概述 消息队列中间件是分布式系统中重要的组件,主要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构.目前使用较多的消息队列有ActiveMQ,Rabbit ...

  9. java使用mq教程,Java语言快速实现简单MQ消息队列服务

    使用 JAVA 语言自己动手来写一个MQ (类似ActiveMQ,RabbitMQ) 主要角色 首先我们必须需要搞明白 MQ (消息队列) 中的三个基本角色 Producer Broker Consu ...

最新文章

  1. 开启JanusGraph中的监控功能
  2. CentOS 安全配置
  3. 20090701随笔
  4. Matlab并行编程函数cellfun arrayfun
  5. IntelliJ IDEA for Mac 如何设置 tab 键为 4 个空格?
  6. wikioi 1306 机智Trie树
  7. 推荐系统基础之介绍入门篇
  8. android人脸识别demo_C#开发实录:基于免费SDK实现人脸识别应用开发
  9. 关于cad2010的激活
  10. 最牛比的NBIOT芯片MDM9206
  11. 模仿腾讯QQ的web登陆面板
  12. odoo 重写unlink方法
  13. C++面试题总结,一篇就够了
  14. 脉冲式和相位式激光测距
  15. 在虚拟机端搭建lamp和通过docker技术在云服务器搭建lamp环境
  16. 低频RFID 底层编码
  17. 单片机蓝牙烧录_怎么样蓝牙模块给单片机烧程序?
  18. 【每日一篇】NIO学习【二】什么是Buffer
  19. 3DMax 常用快捷键
  20. 7.15亿元转让债转股 内蒙古建行拟退出包钢集团

热门文章

  1. 通过ActivityThread获取Context
  2. mysql 设置最大连接数
  3. opencv修改图片尺寸
  4. html位置插入透明动画文字,视频加移动水印 视频添加图片加文字水印 设置透明漂浮移动并控制显示时间...
  5. 印书体数字的识别项目
  6. VIM 将一个文件中的多行复制到另一个文件
  7. Qt下实现的炉石计算器
  8. [python opencv 计算机视觉零基础到实战] 十九、简易绘画板制作
  9. QT 软件中英文切换
  10. 安装gnome桌面教程