消息队列的流派之争

简介: MQ是什么Message Queue(MQ),消息队列中间件。很多人都说:MQ通过将消息的发送和接收分离来实现应用程序的异步和解偶,这个给人的直觉是——MQ是异步的,用来解耦的,但是这个只是MQ的效果而不是目的。

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的队列中”。

img_06e7d07444c3509b7d1cbf129f8982f5.jpe

如上图所示,Broker定义了三个队列,key1,key2,key3,生产者发送数据的时候会发送key1和data,Broker在推送数据的时候则推送data(也可能把key带上)。

虽然架构一样但是kafka的性能要比jms的性能不知道高到多少倍,所以基本这种类型的MQ只有kafka一种备选方案。如果你需要一条暴力的数据流(在乎性能而非灵活性)那么kafka是最好的选择。

轻Topic流

这种的代表是RabbitMQ(或者说是AMQP)。生产者发送key数据,消费者定义订阅的队列,Broker收到数据之后会通过一定的逻辑计算出key对应的队列,然后把数据交给队列

img_d851aa7fcedd6a7a0a66667b160a7e25.jpe

注意到了吗?这种模式下解耦了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的目的。


img_21d0ff374598c112fd897395d5704deb.jpe

节点之间通讯的消息都是发送到彼此的队列中,每个节点都既是生产者又是消费者。ZeroMQ做的事情就是封装出一套类似于scoket的API可以完成发送数据,读取数据。

如果你仔细想一下其实ZeroMQ是这样的


img_f6c20352ad793ed4adbec1c27108e1be.jpe

顿悟了吗?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实现分布式,那真的是难为它。

原文作者:写程序的康德     原文链接:https://mp.weixin.qq.com/s?__biz=MzIxMjAzMDA1MQ==&mid=2648945568&idx=1&sn=7eff16ee9dd40e6f9f90073c0ef90a9e&chksm=8f5b54acb82cddbaf80a1afd16d3222fed631d1ca1d78d84e9fce32bbed1fdcbecbd5d099c9d#rd

相关文章
|
消息中间件 网络协议 Kafka
|
2月前
|
消息中间件 网络性能优化 开发工具
消息队列 MQ使用问题之如何确保消息的唯一性
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
|
2月前
|
消息中间件 C语言 RocketMQ
消息队列 MQ操作报错合集之出现"Connection reset by peer"的错误,该如何处理
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
|
2月前
|
消息中间件 Java C语言
消息队列 MQ使用问题之在使用C++客户端和GBase的ESQL进行编译时出现core dump,该怎么办
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
|
2月前
|
消息中间件 Java 测试技术
消息队列 MQ使用问题之数据流出规则是否支持平台的云RabbitMQ
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
|
7天前
|
消息中间件
手撸MQ消息队列——循环数组
队列是一种常用的数据结构,类似于栈,但采用先进先出(FIFO)的原则。生活中常见的排队场景就是队列的应用实例。在数据结构中,队列通常用数组实现,包括入队(队尾插入元素)和出队(队头移除元素)两种基本操作。本文介绍了如何用数组实现队列,包括定义数组长度、维护队头和队尾下标(front 和 tail),并通过取模运算解决下标越界问题。此外,还讨论了队列的空与满状态判断,以及并发和等待机制的实现。通过示例代码展示了队列的基本操作及优化方法,确保多线程环境下的正确性和高效性。
16 0
手撸MQ消息队列——循环数组
|
1月前
|
消息中间件 存储 缓存
一个用过消息队列的人,竟不知为何要用 MQ?
一个用过消息队列的人,竟不知为何要用 MQ?
75 1
|
2月前
|
消息中间件 开发工具 RocketMQ
消息队列 MQ使用问题之一直连接master失败,是什么原因
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
|
2月前
|
消息中间件 Prometheus 监控
消息队列 MQ使用问题之如何将旧集群的store目录迁移到新集群
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
|
2月前
|
消息中间件 安全 PHP
消息队列 MQ使用问题之如何获取PHP客户端代码
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。