【转】消息队列的流派之争

这篇文章的标题很难起,网上一翻全是各类MQ的性能比较,很容易让人觉得我也是这么“粗俗”的人(o(╯□╰)o)。我这篇文章想要表达的是—— 它们根本不是一个东西,有毛的性能比如较?  服务器

 

MQ是什么

Message Queue(MQ),消息队列中间件。不少人都说: MQ经过将消息的发送和接收分离来实现应用程序的异步和解偶 ,这个给人的直觉是——MQ是异步的,用来解耦的,可是这个只是MQ的效果而不是目的。MQ真正的目的是为了 通信 ,屏蔽底层复杂的通信协议,定义了一套应用层的、更加简单的通信协议。一个分布式系统中两个模块之间通信要么是HTTP,要么是本身开发的TCP,可是这两种协议其实都是原始的协议。HTTP协议很难实现两端通信——模块A能够调用B,B也能够主动调用A,若是要作到这个两端都要背上WebServer,并且还不支持长链接(HTTP 2.0的库根本找不到)。TCP就更加原始了,粘包、心跳、私有的协议,想想头皮就发麻。MQ所要作的就是 在这些协议之上构建一个简单的“协议”——生产者/消费者模型 。MQ带给个人“协议”不是具体的通信协议,而是更高层次 通信模型 。它定义了两个对象——发送数据的叫生产者;消费数据的叫消费者, 提供一个SDK让咱们能够定义本身的 生产者 和 消费者 实现消息通信而无视底层通信协议。架构

 

MQ的流派

列出功能表来比较MQ差别或者来一场“MQ性能大比武”的作法都是比较扯的,首先要作的事情应该是分类。我理解的MQ分为两个流派异步

 

有broker

这个流派一般有一台服务器做为Broker,全部的消息都经过它中转。生产者把消息发送给它就结束本身的任务了,Broker则把消息主动推送给消费者(或者消费者主动轮询)。分布式

  • 重Topic流性能

    kafka、JMS就属于这个流派,生产者会发送 key 和 数据 到Broker,由Broker比较key以后决定给那个消费者。这种模式是咱们最多见的模式,是咱们对MQ最多的印象。在这种模式下一个topic每每是一个比较大的概念,甚至一个系统中就可能只有一个topic,  topic某种意义上就是queue,生产者发送key至关于说:“hi,把数据放到 key 的队列中”。大数据

   

如上图所示,Broker定义了三个队列,key1,key2,key3,生产者发送数据的时候会发送key1和data,Broker在推送数据的时候则推送data(也可能把key带上)。    虽然架构同样可是kafka的性能要比jms的性能不知道高到多少倍,因此基本这种类型的MQ只有kafka一种备选方案。若是你须要 一条暴力的数据流 (在意性能而非灵活性)那么kafka是最好的选择。spa

  • 轻Topic流设计

这种的表明是RabbitMQ(或者说是AMQP)。生产者发送 key 和 数据 ,消费者定义订阅的 队列 ,Broker收到数据以后会经过 必定的逻辑计算出key对应的队列,而后把数据交给队列 。code

   

注意到了吗?这种模式下解耦了key和queue,在这种架构中queue是很是轻量级的(在RabbitMQ中它的上限取决于你的内存),消费者关心的只是本身的queue;生产者没必要关心数据最终给谁只要指定key就好了,中间的那层映射在AMQP中叫exchange(交换机)。AMQP中有四种种exchange——Direct exchange:key就等于queue;Fanout exchange:无视key,给全部的queue都来一份;Topic exchange:key能够用“宽字符”模糊匹配queue;最后一个厉害了Headers exchange:无视key,经过查看消息的头部元数据来决定发给那个queue(AMQP头部元数据很是丰富并且能够自定义)。    这种结构的架构给通信带来了很大的 灵活性 ,咱们能想到的通信方式均可以用这四种exchange表达出来。若是你须要一个 企业数据总线 (在意灵活性)那么RabbitMQ绝对的值得一用。中间件

 

无broker

此门派是AMQP的“叛徒”,某位道友嫌弃AMQP太“重”(那是他没看到用Erlang实现的时候是多么的行云流水) 因此设计了zeromq。这位道友很是睿智,他很是敏锐的意识到—— MQ是更高级的Socket,它是解决通信问题的。 因此ZeroMQ被设计成了一个“库”而不是一个中间件,这种实现也能够达到——没有broker的目的。

   

节点之间通信的消息都是发送到彼此的队列中,每一个节点都既是 生产者又是消费者 。ZeroMQ作的事情就是封装出一套相似于scoket的API能够完成发送数据,读取数据。    若是你仔细想一下其实ZeroMQ是这样的

   

顿悟了吗?Actor模型,ZeroMQ其实就是一个 跨语言的、重量级的Actor模型邮箱库 。你能够把本身的程序想象成一个actor,zeromq就是提供 邮箱 功能的库;zeromq能够实现同一台机器的IPC通信也能够实现不一样机器的TCP、UDP通信。    若是你须要一个强大的、灵活、野蛮的通信能力,别犹豫zeromq。

 

MQ只能异步吗

答案是否认了,首先ZeroMQ支持 请求->应答模式 ;其次RabbitMQ提供了 RPC 是地地道道的同步通信,只有JMS、kafka这种架构才只能作异步。咱们不少人第一次接触MQ都是JMS之类的这种因此才会产生这种 错觉 。

 

总结

kafka,zeromq,rabbitmq表明了三种彻底不一样风格的MQ架构;关注点彻底不一样:

  • kafka在意的是性能,速度

  • rabbitmq追求的是灵活

  • zeromq追求的是轻量级、分布式

若是你拿zeromq来作大数据量的传输功能,不是生产者的内存“爆掉”就是消费者被“压死”;若是你用kafka作通信总线那绝对的不会快只能更慢;你想要rabbitmq实现分布式,那真的是难为它。

相关文章
相关标签/搜索