消息队列(MQ,Message Queue)是阿里巴巴集团中间件技术部自主研发的专业消息中间件。

分布式消息系统作为实现分布式系统可扩展、可伸缩性的关键组件,需要具有高吞吐量、高可用等特点。

目前使用较多的消息队列有:ActiveMQ、RabbitMQ、RocketMQ、ZeroMQ、MetaMQ、Kafka

 

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

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

RocketMQ 官网:http://rocketmq.apache.org  (阿里巴巴开源

ZeroMQ 官网:https://zeromq.org

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

MSMQ 官网:MSMQ ,MSMQ(消息队列)  (微软MQ)

 

各种主流的MQ中间件:

ZeroMQ

推特的Distributedlog

ActiveMQ:Apache旗下的老牌消息引擎

RabbitMQ、Kafka:AMQP(高级消息队列协议)的默认实现。

RocketMQ:阿里巴巴开源的消息队列

Artemis:Apache的ActiveMQ下的子项目

Apollo:同样为Apache的ActiveMQ的子项目的号称下一代消息引擎

商业化的消息引擎IronMQ

以及实现了JMS(Java Message Service)标准的OpenMQ。

 

 

一、消息队列概述

消息队列中间件是分布式系统中重要的组件

主要解决应用解耦,异步消息,消息通讯,流量削锋,日志处理等问题,

实现高性能,高可用,可伸缩和最终一致性架构。

 

二、消息队列应用场景

消息队列在实际应用中常用的使用场景,包含异步处理、应用解耦、流量削锋、消息通讯、日志处理等

1、异步处理

场景说明:用户注册后,需要发注册邮件和注册短信。

传统的做法有两种 1. 串行的方式;2. 并行方式

a、串行方式:将注册信息写入数据库成功后,发送注册邮件,再发送注册短信。以上三个任务全部完成后,返回给客户端。

b、并行方式:将注册信息写入数据库成功后,发送注册邮件的同时,发送注册短信。以上三个任务完成后,返回给客户端。与串行的差别是,并行的方式可以提高处理的时间

假设三个业务节点每个使用50毫秒钟,不考虑网络等其他开销,则串行方式的时间是150毫秒,并行的时间可能是100毫秒。

因为CPU在单位时间内处理的请求数是一定的,假设CPU1秒内吞吐量是100次。则串行方式1秒内CPU可处理的请求量是7次(1000/150)。并行方式处理的请求量是10次(1000/100)

小结:如以上案例描述,传统的方式系统的性能(并发量,吞吐量,响应时间)会有瓶颈。如何解决这个问题呢?

引入消息队列,将不是必须的业务逻辑,异步处理。

改造后的架构如下:

按照以上约定,用户的响应时间相当于是注册信息写入数据库的时间,也就是50毫秒。注册邮件,发送短信写入消息队列后,直接返回,因此写入消息队列的速度很快,5ms基本可以忽略,因此用户的响应时间可能是50毫秒。因此架构改变后,系统的吞吐量提高到每秒20 QPS。比串行提高了3倍,比并行提高了2倍

 

2、应用解耦

场景说明:用户下单后,订单系统需要通知库存系统。

传统的做法是,订单系统调用库存系统的接口。

如下图:

传统模式的缺点:假如库存系统无法访问,则订单减库存将失败,从而导致订单失败,订单系统与库存系统耦合太紧了

如何解决以上问题呢?引入应用消息队列后的方案,如下图:

订单系统:用户下单后,订单系统完成持久化处理,将消息写入消息队列,返回用户订单下单成功

库存系统:订阅下单的消息,采用拉/推(pull / push)的方式,获取下单信息,库存系统根据下单信息,进行库存操作

假如:在下单时库存系统不能正常使用,也不影响正常下单,因为下单后,订单系统写入消息队列就不再关心其他的后续操作了。实现订单系统与库存系统的应用解耦(有个问题:若没库存了,订单成功了,没货发了,咋办?)

 

3、流量削锋

流量削锋,也是消息队列中的常用场景,一般在秒杀或团抢活动中使用广泛。

应用场景:秒杀活动,一般会因为流量过大,导致流量暴增,应用挂掉

为解决这个峰值问题,一般需要在应用前端加入消息队列。

a、可以控制活动的人数

b、可以缓解短时间内高流量压垮应用

用户的请求,服务器接收后,首先写入消息队列。

假如消息队列长度超过最大数量,则直接抛弃用户请求或跳转到错误页面。

秒杀业务根据消息队列中的请求信息,再做后续处理,例如下订单、减库存、支付等

 

4、消息通讯

消息通讯是指,消息队列一般都内置了高效的通信机制,因此也可以用在纯的消息通讯。

比如实现点对点消息队列,或者聊天室等,可以用 Redis 管道、Kafka等

点对点通讯:

客户端A和客户端B使用同一队列,进行消息通讯。

聊天室通讯:

客户端A,客户端B,客户端N订阅同一主题,进行消息发布和接收,实现类似聊天室效果。

以上实际是消息队列的两种消息模式,点对点或发布订阅模式

 

5、日志处理

日志处理是指将消息队列用在日志处理中,比如Kafka的应用,解决大量日志传输的问题。

架构简化如下

日志采集客户端,负责日志数据采集,定时写受写入Kafka队列

Kafka消息队列,负责日志数据的接收,存储和转发

日志处理应用:订阅并消费kafka队列中的日志数据 

 

三、消息中间件示例

3.1 电商系统

消息队列采用高可用、可持久化的消息中间件,比如 Active MQ,Rabbit MQ,Rocket Mq

1)应用将主干逻辑处理完成后,写入消息队列。消息发送是否成功可以开启消息的确认模式。(消息队列返回消息接收成功状态后,应用再返回,这样保障消息的完整性)

2)扩展流程(发短信,配送处理)订阅队列消息。采用推或拉的方式获取消息并处理。

3)消息将应用解耦的同时,带来了数据一致性问题,可以采用最终一致性方式解决。比如主数据写入数据库,扩展应用根据消息队列,并结合数据库方式实现基于消息队列的后续处理,最终实现数据的一致性。

 

3.2 日志收集系统

上图,分为Zookeeper注册中心,日志收集客户端logclient,Kafka集群和Storm集群(OtherApp)四部分组成。

1)Zookeeper注册中心,提出负载均衡和地址查找服务

2)日志收集客户端logclient,用于采集应用系统的日志,并将数据推送到kafka队列

3)Kafka集群:接收,路由,存储,转发等消息处理

4)Storm集群:与OtherApp处于同一级别,采用拉的方式消费队列中的数据

 

四、JMS消息服务

讲消息队列就不得不提JMS

JMS(Java Message Service,Java消息服务)API是一个消息服务的标准/规范,允许应用程序组件基于JavaEE平台创建、发送、接收和读取消息。它使分布式通信耦合度更低,消息服务更加可靠以及异步性。

在EJB架构中,有消息bean可以无缝的与JM消息服务集成。

在J2EE架构模式中,有消息服务者模式,用于实现消息与应用直接的解耦。

4.1 消息模型

在JMS标准中,有两种消息模型P2P(Point to Point), Publish/Subscribe(Pub/Sub)。

1)P2P模式

P2P模式包含三个角色:消息队列(Queue),发送者(Sender),接收者(Receiver)

每个消息都被发送到一个特定的队列,接收者从队列中获取消息。

队列保留着消息,直到他们被消费或超时。

P2P的特点

每个消息只有一个消费者(Consumer)(即一旦被消费,消息就不再在消息队列中)

发送者和接收者之间在时间上没有依赖性,也就是说当发送者发送了消息之后,不管接收者有没有正在运行,它不会影响到消息被发送到队列

接收者在成功接收消息之后需向队列应答成功

如果希望发送的每个消息都会被成功处理的话,那么需要P2P模式。

 

2)Pub/Sub模式

包含三个角色:主题(Topic),发布者(Publisher),订阅者(Subscriber)

多个发布者将消息发送到Topic,系统将这些消息传递给多个订阅者。

Pub/Sub的特点

每个消息可以有多个消费者

发布者和订阅者之间有时间上的依赖性。针对某个主题(Topic)的订阅者,它必须创建一个订阅者之后,才能消费发布者的消息

为了消费消息,订阅者必须保持运行的状态

为了缓和这样严格的时间相关性,JMS允许订阅者创建一个可持久化的订阅。这样,即使订阅者没有被激活(运行),它也能接收到发布者的消息。

如果希望发送的消息可以不被做任何处理、或者只被一个消息者处理、或者可以被多个消费者处理的话,那么可以采用Pub/Sub模型。

 

4.2 消息消费

在JMS中,消息的产生和消费都是异步的

对于消费来说,JMS的消息者可以通过两种方式来消费消息。

1)同步

订阅者或接收者通过receive方法来接收消息,receive方法在接收到消息之前(或超时之前)将一直阻塞;

2)异步

订阅者或接收者可以注册为一个消息监听器。当消息到达之后,系统自动调用监听器的onMessage方法。

JNDI:Java命名和目录接口,是一种标准的Java命名系统接口,可以在网络上查找和访问服务。通过指定一个资源名称,该名称对应于数据库或命名服务中的一个记录,同时返回资源连接建立所必须的信息。

JNDI在JMS中起到查找和访问发送目标或消息来源的作用。

 

五、常用消息队列

一般商用的容器,比如 WebLogic,JBoss,都支持JMS标准,开发上很方便。

但免费的比如 Tomcat,Jetty 等则需要使用第三方的消息中间件,例如 Active MQ, Rabbit MQ,Zero MQ, Kafka等。

本部分内容介绍常用的消息中间件(Active MQ, Rabbit MQ,Zero MQ, Kafka)以及他们的特点。

5.1 ActiveMQ

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

Apache ActiveMQ™ is the most popular open source, multi-protocol, Java-based messaging server. It supports industry standard protocols so users get the benefits of client choices across a broad range of languages and platforms. Connectivity from C, C++, Python, .Net, and more is available. Integrate your multi-platform applications using the ubiquitous AMQP protocol. Exchange messages between your web applications using STOMP over websockets. Manage your IoT devices using MQTT. Support your existing JMS infrastructure and beyond. ActiveMQ offers the power and flexibility to support any messaging use-case.

ActiveMQ 是Apache出品,最流行的,能力强劲的开源消息总线。ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现,尽管JMS规范出台已经是很久的事情了,但是JMS在当今的J2EE应用中间仍然扮演着特殊的地位。

ActiveMQ有很长的历史,而且被广泛的使用,是Java世界的中坚力量。

ActiveMQ是跨平台的,给那些非微软平台的产品提供了一个天然的集成接入点。

ActiveMQ类似于ZemoMQ,它可以部署于代理模式和P2P模式

ActiveMQ类似于RabbitMQ,它易于实现高级场景,而且只需付出低消耗。

ActiveMQ被誉为消息中间件的“瑞士军刀”。

ActiveMQ特性如下:

⒈ 多种语言和协议编写客户端。语言: Java, C, C++, C#, Ruby, Perl, Python, PHP

     应用协议: OpenWire, Stomp REST, WS Notification, XMPP, AMQP

⒉ 完全支持JMS1.1和J2EE 1.4规范 (持久化,XA消息,事务)

⒊ 对Spring的支持,ActiveMQ可以很容易内嵌到使用Spring的系统里面去,而且也支持Spring2.0的特性

⒋ 通过了常见J2EE服务器(如 WebLogic, JBoss 4, Geronimo, GlassFish)的测试,其中通过JCA 1.5 resource adaptors的配置,可以让ActiveMQ可以自动的部署到任何兼容J2EE 1.4 商业服务器上

⒌ 支持多种传送协议:in-VM, TCP, UDP, SSL, NIO, JGroups, JXTA

⒍ 支持通过JDBC和journal提供高速的消息持久化

⒎ 从设计上保证了高性能的集群,客户端-服务器,点对点

⒏ 支持Ajax

⒐ 支持与Axis的整合

⒑ 可以很容易得调用内嵌JMS provider,进行测试

 

5.2 Kafka

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

Kafka是一种高吞吐量的分布式、发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据。

这种动作(网页浏览,搜索和其他用户的行动)是在现代网络上的许多社会功能的一个关键因素。

这些数据通常是由于吞吐量的要求而通过处理日志和日志聚合来解决。

1、Kafka 不完全符合jms规范,注重吞吐量,类似udp 和 tcp;

2、一般做大数据吞吐的管道,主要用途就是负责在各个idc之间通信;

3、量大,对数据不是百分之百保证的,会有数据丢失,不是百分百送达(amq和rmq等有重发机制,而kafka没有,前者amq和rmq通过设置,可以有消息重新发送,可以查询得知消息是否送达;但是kafka不知道你发出去了,也不知道你消息送没送达);

Kafka在吞吐量有提升,但在保证100%不丢失这方面就得有牺牲, 所以kafka适合大数据量流转, 比如日志数据,统计的数据。

对于像Hadoop的一样的日志数据和离线分析系统,但又要求实时处理的限制,这是一个可行的解决方案。Kafka的目的是通过Hadoop的并行加载机制来统一线上和离线的消息处理,也是为了通过集群机来提供实时的消费。

Kafka是一种高吞吐量的分布式发布订阅消息系统,有如下特性:

1)通过 O(1) 的磁盘数据结构提供消息的持久化,这种结构对于即使数以TB的消息存储也能够保持长时间的稳定性能。文件追加的方式写入数据,过期的数据定期删除

2)高吞吐量:即使是非常普通的硬件,Kafka也可以支持每秒数百万的消息

3)支持通过Kafka服务器和消费机集群来分区消息

4)支持Hadoop并行数据加载

 

Kafka相关概念

1)Broker (服务器)

Kafka集群包含一个或多个服务器,这种服务器被称为broker

2)Topic

每条发布到Kafka集群的消息都有一个类别,这个类别被称为Topic。

物理上不同Topic的消息分开存储,逻辑上一个Topic的消息虽然保存于一个或多个broker上,但用户只需指定消息的Topic即可生产或消费数据,而不必关心数据存于何处brokers

3)Partition

Parition是物理上的概念,每个Topic包含一个或多个Partition.

4)Producer (生产者)

负责发布消息到Kafka broker

5)Consumer (消费者)

消息消费者,向Kafka broker读取消息的客户端。

6)Consumer Group

每个Consumer属于一个特定的Consumer Group(可为每个Consumer指定group name,若不指定group name则属于默认的group)。

一般应用在大数据日志处理或对实时性(少量延迟),可靠性(少量丢数据)要求稍低的场景使用。

 

5.3、RabbitMQ

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

With tens of thousands of users, RabbitMQ is one of the most popular open source message brokers. From T-Mobile to Runtastic, RabbitMQ is used worldwide at small startups and large enterprises.

RabbitMQ is lightweight and easy to deploy on premises and in the cloud. It supports multiple messaging protocols. RabbitMQ can be deployed in distributed and federated configurations to meet high-scale, high-availability requirements.

RabbitMQ是AMQP(Advanced Message Queuing Protocol,高级消息队列协议)协议领先的一个实现,它实现了代理(Broker)架构,意味着消息在发送到客户端之前可以在中央节点上排队。此特性使得RabbitMQ易于使用和部署,适宜于很多场景如路由、负载均衡或消息持久化等,用消息队列只需几行代码即可搞定

RabbitMQ支持开放的高级消息队列协议(AMQP,Advanced Message Queuing Protocol),从根本上避免了生产厂商的封闭,使用任何语言的各种客户都可以从中受益。这种协议提供了相当复杂的消息传输模式,所以基本上不需要 MassTransit或NServiceBus的配合。它还具有“企业级”的适应性和稳定性。这些东西对我的客户来说十分的有吸引力。

但是,这使得它的可扩展性差,速度较慢,因为中央节点增加了延迟,消息封装后也比较大。

ActiveMQ需要在目标机器上安装Java,RabbitMQ需要Erlang环境。

要注意一点,ActiveMQ的下一代产品为Apollo。

 

5.4、ZeroMQ

ZeroMQ 官网:https://zeromq.org

ZeroMQ (also known as ØMQ, 0MQ, or zmq) looks like an embeddable networking library but acts like a concurrency framework. It gives you sockets that carry atomic messages across various transports like in-process, inter-process, TCP, and multicast. You can connect sockets N-to-N with patterns like fan-out, pub-sub, task distribution, and request-reply. It's fast enough to be the fabric for clustered products. Its asynchronous I/O model gives you scalable multicore applications, built as asynchronous message-processing tasks. It has a score of language APIs and runs on most operating systems.

ZeroMQ是一个非常轻量级的消息系统,专门为高吞吐量/低延迟的场景开发,在金融界的应用中经常可以发现它

ZeroMQ与RabbitMQ相比,ZeroMQ支持许多高级消息场景,但是你必须实现ZeroMQ框架中的各个块(比如Socket或Device等)。

ZeroMQ非常灵活,但是你必须学习它的80页的手册(如果你要写一个分布式系统,一定要阅读它)

 

5.5、RocketMQ

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

RocketMQ 是一款开源的分布式消息系统,基于高可用分布式集群技术,提供低延时的、高可靠的消息发布与订阅服务。同时,广泛应用于多个领域,包括异步通信解耦、企业解决方案、金融支付、电信、电子商务、快递物流、广告营销、社交、即时通信、移动应用、手游、视频、物联网、车联网等。

RocketMQ前身叫做MetaQ, 在MetaQ发布3.0版本的时候改名为RocketMQ,其本质上的设计思路和Kafka类似,但是和Kafka不同的是其使用Java进行开发,由于在国内的Java受众群体远远多于Scala,所以RocketMQ是很多以Java语言为主的公司的首选。同样的RocketMQ和Kafka都是Apache基金会中的顶级项目,他们社区的活跃度都非常高,项目更新迭代也非常快。

具有以下特点:

  • 能够保证严格的消息顺序

  • 提供丰富的消息拉取模式

  • 高效的订阅者水平扩展能力

  • 实时的消息订阅机制

  • 亿级消息堆积能力

  • Metaq3.0 版本改名,产品名称改为RocketMQ

RocketMQ是阿里review kafka的java版,如果消息性能要求高,用rocketmq与kafka可以更优

MetaMQ RocketMQ的前世今生

公司一直用的消息中间件是MetaMQ现在,网上相关的资料也不是很多,今天去想淘宝为什会 把MetaMQ给替换成了RocketMQ。就网上搜索了一下,这两个居然是爷孙关系。

阿里巴巴消息中间件起源于2001年的五彩石项目,Notify在这期间应运而生,用于交易核心消息的流转。

至2010年,B2B开始大规模使用ActiveMQ作为消息内核,随着阿里业务的快速发展,急需一款支持顺序消息,拥有海量消息堆积能力的消息中间件,MetaQ 1.0在2011年诞生。

到2012年,MetaQ已经发展到了MetaQ 3.0,并抽象出了通用的消息引擎RocketMQ。随后,将RocketMQ进行了开源,阿里的消息中间件正式走入了公众的视野。

到2015年,RocketMQ已经经历了多年双十一的洗礼,在可用性、可靠性以及稳定性等方面都有出色的表现。与此同时,云计算大行其道,阿里消息中间件基于RocketMQ推出了Aliware MQ 1.0,开始为阿里云上成千上万家企业提供消息服务。

到今年,MetaQ在2016年双十一承载了万亿级消息的流转,跨越了一个新的里程碑,同时RocketMQ进入Apache 孵化。

 

5.6、MSMQ (微软MQ)

MSMQ 官网:MSMQ ,MSMQ(消息队列) 

MSMQ是微软产品里唯一被认为有价值的东西。对我的客户来说,如果MSMQ能证明可以应对这种任务,他们将选择使用它。关键是这个东西并不复杂,除了 接收和发送,没有别的;它有一些硬性限制,比如最大消息体积是4MB。然而,通过和一些像MassTransit或NServiceBus这样的软件的连接,它完全可以解决这些问题。

 

 

总结

1、性能小,量小,用什么都没有关系,性质是一样的,

如果消息性能要求高,用RocketMQ与Kafka可以更优

rocketmq与kafka 比较就看技术选型了,各有利弊,看业务需要。

2、ActiveMQ、RabbitMQ 与 Kafka、RocketMQ有很大的区别,就是前2个只支持主从模式,后2个是分布式消息系统,支持分布式。

3、持久化消息比较: ZeroMQ轻量级,不支持持久化,ActiveMQ和RabbitMQ都支持持久化。

持久化消息主要是指:MQ down或者MQ所在的服务器down了,消息存入了磁盘,重启后消息数据不会丢失的机制。

4、其中包括持久化消息和瞬时消息的测试。注意这篇文章里面提到的MQ,都是采用默认配置的,并无调优。

ZeroMq 最好,RabbitMq 次之, ActiveMq 最差,这个结论来自于以下这两篇文章。

A quick message queue benchmark: ActiveMQ, RabbitMQ, HornetQ, QPID, Apollo (2013-04-10)

消息队列软件产品大比拼 (2011-08-31)

其中包括持久化消息和瞬时消息的测试。注意这篇文章里面提到的MQ,都是采用默认配置的,并无调优。

显示的是发送和接受的每秒钟的消息数,整个过程共产生1百万条1K的消息。测试的执行是在一个Windows Vista上进行的。

如上图,就像你看到的,ZeroMQ和其它的不是一个级别,它的性能惊人的高。公平的说,ZeroMQ跟其它几个比起来像头巨兽,尽管这样,结论很清楚:如果你希望一个应用程序发送消息越快越好,你选择ZeroMQ。当你不太在意偶然会丢失某些消息的情况下更有价值。

老实讲,我更希望使用Rabbit。但这种事情是应该做更多的测试,你最终会有一个最爱,我所听到的、读到的各种关于Rabbit的事情让我觉得它应该是最佳选择。但使用这个测试结果,我很难说服他们不去使用MSMQ。

如果你想自己跑一下这些测试,我的测试代码都放在了 GitHub

 

5、技术点

可靠性、灵活的路由、集群、事务、高可用的队列、消息排序、问题追踪、可视化管理工具、插件系统、社区。RabbitMq最好,ActiveMq次之,ZeroMQ最差。当然ZeroMQ也可以做到,不过自己必须手动写代码实现,代码量不小。尤其是ZeroMQ可靠性中的:持久性、投递确认、发布者证实和高可用性。所以,在可靠性和可用性上,RabbitMQ是首选,虽然ActiveMQ也具备,但是它性能不及RabbitMQ。

6、高并发

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

7、Kafka 和 RabbitMQ 比较

如何保证kafka的高容错性?

1)producer不使用批量接口,并采用同步模型持久化消息。

2)consumer不采用批量化,每消费一次就更新offset

特性 ActiveMq RabbitMq Kafka
producer容错,是否会丢数据   有ack模型,也有事务模型,保证至少不会丢数据。ack模型可能会有重复消息,事务模型则保证完全一致 批量形式下,可能会丢数据。
非批量形式下:
1. 使用同步模式,可能会有重复数据
2. 异步模式,则可能会丢数据
consumer容错,是否会丢数据   有ack模型,数据不会丢,但可能会重复处理数据。 批量形式下,可能会丢数据。非批量形式下,可能会重复处理数据。(ZK写offset是异步的)
架构模型 基于JMS协议 基于AMQP模型,比较成熟,但更新超慢。RabbitMQ的broker由Exchange, Binding, queue组成,其中exchange和binding组成了消息的路由键;客户端Producer通过连接channel和server进行通信,Consumer从queue获取消息进行消费(长连接,queue有消息会推送到consumer端,consumer循环从输入流读取数据)。rabbitMQ以broker为中心;有消息的确认机制 producer,broker,consumer,以consumer为中心,消息的消费信息保存的客户端consumer上,consumer根据消费的点,从broker上批量pull数据;无消息确认机制。
吞吐量   rabbitMQ在吞吐量方面稍逊于kafka,他们的出发点不一样,rabbitMQ支持对消息的可靠的传递,支持事务,不支持批量的操作;基于存储的可靠性的要求存储可以采用内存或者硬盘。 kafka具有高的吞吐量,内部采用消息的批量处理,zero-copy机制,数据的存储和获取是本地磁盘顺序批量操作,具有O(1)的复杂度,消息处理的效率很高,每秒数百万次
可用性   rabbitMQ支持miror的queue,主queue失效,miror queue接管 kafka的broker支持主备模式
集群负载均衡   rabbitMQ的负载均衡需要单独的loadbalancer进行支持 kafka采用zookeeper对集群中的broker、consumer进行管理,可以注册topic到zookeeper上;通过zookeeper的协调机制,producer保存对应topic的broker信息,可以随机或者轮询发送到broker上;并且producer可以基于语义指定分片,消息发送到broker的某分片上

里面提到的要点:

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

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

3)Kafka的性能(吞吐量、tps)比RabbitMQ要强,这篇文章的作者认为,两者在这方面没有可比性。

 

两者对比后,我仍然是选择RabbitMQ,性能其实是很强劲的,

同时,RabbitMQ具备了一个成熟的MQ应该具有的特性,我们无需重新发明轮子。

按照目前网络上的资料,RabbitMQ、ActiveMQ、ZeroMQ三者中,综合来看,RabbitMQ是首选

 

MQ消息队列的优劣比较

特性 ActiveMQ RabbitMQ(erlang) RocketMQ(阿里巴巴) Kafka
单机吞吐量 万级,吞吐量比RocketMQ和Kafka要低了一个数量级 万级,吞吐量比RocketMQ和Kafka要低了一个数量级 10万级,RocketMQ也是可以支撑高吞吐的一种MQ 10万级,这是kafka最大的优点,就是吞吐量高。 一般配合大数据类的系统来进行实时数据计算、日志采集等场景
topic数量对吞吐量的影响     topic可以达到几百,几千个的级别,吞吐量会有较小幅度的下降。这是RocketMQ的一大优势,在同等机器下,可以支撑大量的topic topic从几十个到几百个的时候,吞吐量会大幅度下降。所以在同等机器下,kafka尽量保证topic数量不要过多。如果要支撑大规模topic,需要增加更多的机器资源
时效性 ms级 微秒级,这是rabbitmq的一大特点,延迟是最低的 ms级 延迟在ms级以内
可用性 高,基于主从架构实现高可用性 高,基于主从架构实现高可用性 非常高,分布式架构 非常高,kafka是分布式的,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用
消息可靠性 有较低的概率丢失数据   经过参数优化配置,可以做到0丢失 经过参数优化配置,消息可以做到0丢失
功能支持 MQ领域的功能极其完备 基于erlang开发,所以并发能力很强,性能极其好,延时很低 MQ功能较为完善,还是分布式的,扩展性好 功能较为简单,主要支持简单的MQ功能,在大数据领域的实时计算以及日志采集被大规模使用,是事实上的标准
优劣势总结 非常成熟,功能强大,在业内大量的公司以及项目中都有应用。偶尔会有较低概率丢失消息。而且现在社区以及国内应用都越来越少,官方社区现在对ActiveMQ 5.x维护越来越少,几个月才发布一个版本,而且确实主要是基于解耦和异步来用的,较少在大规模吞吐的场景中使用 erlang语言开发,性能极其好,延时很低;吞吐量到万级,MQ功能比较完备;而且开源提供的管理界面非常棒,用起来很好用;社区相对比较活跃,几乎每个月都发布几个版本分;在国内一些互联网公司近几年用rabbitmq也比较多一些;但是问题也是显而易见的,RabbitMQ确实吞吐量会低一些,这是因为他做的实现机制比较重。而且erlang开发,国内有几个公司有实力做erlang源码级别的研究和定制?如果说你没这个实力的话,确实偶尔会有一些问题,你很难去看懂源码,你公司对这个东西的掌控很弱,基本职能依赖于开源社区的快速维护和修复bug。而且rabbitmq集群动态扩展会很麻烦,不过这个我觉得还好。其实主要是erlang语言本身带来的问题。很难读源码,很难定制和掌控。 接口简单易用,而且毕竟在阿里大规模应用过,有阿里品牌保障。日处理消息上百亿之多,可以做到大规模吞吐,性能也非常好,分布式扩展也很方便,社区维护还可以,可靠性和可用性都是ok的,还可以支撑大规模的topic数量,支持复杂MQ业务场景,而且一个很大的优势在于,阿里出品都是java系的,我们可以自己阅读源码,定制自己公司的MQ,可以掌控。社区活跃度相对较为一般,不过也还可以,文档相对来说简单一些,然后接口这块不是按照标准JMS规范走的有些系统要迁移需要修改大量代码。还有就是阿里出台的技术,你得做好这个技术万一被抛弃,社区黄掉的风险,那如果你们公司有技术实力我觉得用RocketMQ挺好的 kafka的特点其实很明显,就是仅仅提供较少的核心功能,但是提供超高的吞吐量,ms级的延迟,极高的可用性以及可靠性,而且分布式可以任意扩展;同时kafka最好是支撑较少的topic数量即可,保证其超高吞吐量;而且kafka唯一的一点劣势是有可能消息重复消费,那么对数据准确性会造成极其轻微的影响,在大数据领域中以及日志采集中,这点轻微影响可以忽略,这个特性天然适合大数据实时计算以及日志收集

综上所述,各种对比之后,建议:

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

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

不过现在确实越来越多的公司,会去用RocketMQ,确实很不错,但是我提醒一下自己想好社区万一突然黄掉的风险,对自己公司技术实力有绝对自信的,我推荐用RocketMQ,否则回去老老实实用RabbitMQ吧,对应的活跃开源社区,一般不会黄;

所以中小型公司,技术实力较为一般,技术挑战不是特别高,用RabbitMQ是不错的选择;大型公司,基础架构研发实力较强,用RocketMQ是很好的选择

如果是大数据领域的实时计算、日志采集等场景,用Kafka是业内标准的,绝对没问题,社区活跃度很高,绝对不会黄,何况几乎是全世界这个领域的事实性规范

 

好资料推荐:

1、最全最给力的 Kafka 博客:apache kafka (CSDN 专栏)

2、淘宝对 RabbitMQ 的使用:我为什么要选择RabbitMQ

 

 

参考推荐:

Kafka 分布式消息系统架构

Kafka 分布式消息系统示例

Kafka:下一代分布式消息系统

消息队列总结:ActiveMQ、RabbitMQ、RocketMQ、ZeroMQ、MetaMQ、Kafka

运维人员常用软件总结

分布式系统事务一致性解决方案

大型网站技术架构的知识总结

大型网站架构技术知识点一览

大型网站技术架构:核心原理与案例分析

1亿qq在线背后的技术

阿里巴巴的海量数据技术架构

数据库分库分表解决方案汇总

数据库分库分表的解决方案比较

大型网站海量数据的业主拆分与高并发

MySQL 临时表,复制记录插入同一张表

Google、Facebook等技术发展历程

MySQL 中 InnoDB 和 MyISAM 小结

MySQL 事务隔离级别和实现原理

MySQL基于mysqldump快速搭建从库

淘宝分享:跳出MySQL的10个大坑