02 | 该如何选择消息队列?

1.应用场景

见: https://blog.csdn.net/william_n/article/details/104025408

2.学习/操作

2.1 阅读文档

02 | 该如何选择消息队列?

李玥 2020-01-14

00:00

13:59

讲述:李玥 大小:12.81M

你好,我是李玥。这节课我们来聊一下几个比较常见的开源的消息队列中间件。如果你正在做消息队列技术选型,不知道该选择哪款消息队列,你一定要先听一下这节课的内容。

作为一个程序员,相信你一定听过“没有银弹”这个说法,这里面的银弹是指能轻松杀死狼人、用白银做的子弹,什么意思呢?我对这句话的理解是说,在软件工程中,不存在像“银弹”这样可以解决一切问题的设计、架构或软件,每一个软件系统,它都是独一无二的,你不可能用一套方法去解决所有的问题。

在消息队列的技术选型这个问题上,也是同样的道理。并不存在说,哪个消息队列就是“最好的”。常用的这几个消息队列,每一个产品都有自己的优势和劣势,你需要根据现有系统的情况,选择最适合你的那款产品。

选择消息队列产品的基本标准

虽然这些消息队列产品在功能和特性方面各有优劣,但我们在选择的时候要有一个最低标准,保证入选的产品至少是及格的。

接下来我们先说一下这及格的标准是什么样的。

首先,必须是开源的产品,这个非常重要。开源意味着,如果有一天你使用的消息队列遇到了一个影响你系统业务的 Bug,你至少还有机会通过修改源代码来迅速修复或规避这个 Bug,解决你的系统火烧眉毛的问题,而不是束手无策地等待开发者不一定什么时候发布的下一个版本来解决。

其次,这个产品必须是近年来比较流行并且有一定社区活跃度的产品。流行的好处是,只要你的使用场景不太冷门,你遇到 Bug 的概率会非常低,因为大部分你可能遇到的 Bug,其他人早就遇到并且修复了。你在使用过程中遇到的一些问题,也比较容易在网上搜索到类似的问题,然后很快的找到解决方案。

还有一个优势就是,流行的产品与周边生态系统会有一个比较好的集成和兼容,比如,Kafka 和 Flink 就有比较好的兼容性,Flink 内置了 Kafka 的 Data Source,使用 Kafka 就很容易作为 Flink 的数据源开发流计算应用,如果你用一个比较小众的消息队列产品,在进行流计算的时候,你就不得不自己开发一个 Flink 的 Data Source。

最后,作为一款及格的消息队列产品,必须具备的几个特性包括:

消息的可靠传递:确保不丢消息;

Cluster:支持集群,确保不会因为某个节点宕机导致服务不可用,当然也不能丢消息;

性能:具备足够好的性能,能满足绝大多数场景的性能要求。

接下来我们一起看一下有哪些符合上面这些条件,可供选择的开源消息队列产品。

可供选择的消息队列产品

1. RabbitMQ

首先,我们说一下老牌儿消息队列 RabbitMQ,俗称兔子 MQ。RabbitMQ 是使用一种比较小众的编程语言:Erlang 语言编写的,它最早是为电信行业系统之间的可靠通信设计的,也是少数几个支持 AMQP 协议的消息队列之一。

RabbitMQ 就像它的名字中的兔子一样:轻量级、迅捷,它的 Slogan,也就是宣传口号,也很明确地表明了 RabbitMQ 的特点:Messaging that just works,“开箱即用的消息队列”。也就是说,RabbitMQ 是一个相当轻量级的消息队列,非常容易部署和使用。

另外 RabbitMQ 还号称是世界上使用最广泛的开源消息队列,是不是真的使用率世界第一,我们没有办法统计,但至少是“最流行的消息中间之一”,这是没有问题的。

RabbitMQ 一个比较有特色的功能是支持非常灵活的路由配置,和其他消息队列不同的是,它在生产者(Producer)和队列(Queue)之间增加了一个 Exchange 模块,你可以理解为交换机。

这个 Exchange 模块的作用和交换机也非常相似,根据配置的路由规则将生产者发出的消息分发到不同的队列中。路由的规则也非常灵活,甚至你可以自己来实现路由规则。基于这个 Exchange,可以产生很多的玩儿法,如果你正好需要这个功能,RabbitMQ 是个不错的选择。

RabbitMQ 的客户端支持的编程语言大概是所有消息队列中最多的,如果你的系统是用某种冷门语言开发的,那你多半可以找到对应的 RabbitMQ 客户端。

接下来说下 RabbitMQ 的几个问题。

第一个问题是,RabbitMQ 对消息堆积的支持并不好,在它的设计理念里面,消息队列是一个管道,大量的消息积压是一种不正常的情况,应当尽量去避免。当大量消息积压的时候,会导致 RabbitMQ 的性能急剧下降。

第二个问题是,RabbitMQ 的性能是我们介绍的这几个消息队列中最差的,根据官方给出的测试数据综合我们日常使用的经验,依据硬件配置的不同,它大概每秒钟可以处理几万到十几万条消息。其实,这个性能也足够支撑绝大多数的应用场景了,不过,如果你的应用对消息队列的性能要求非常高,那不要选择 RabbitMQ。

最后一个问题是 RabbitMQ 使用的编程语言 Erlang,这个编程语言不仅是非常小众的语言,更麻烦的是,这个语言的学习曲线非常陡峭。大多数流行的编程语言,比如 Java、C/C++、Python 和 JavaScript,虽然语法、特性有很多的不同,但它们基本的体系结构都是一样的,你只精通一种语言,也很容易学习其他的语言,短时间内即使做不到精通,但至少能达到“会用”的水平。

就像一个以英语为母语的人,学习法语、德语都很容易,但是你要是让他去学汉语,那基本上和学习其他这些语言不是一个难度级别的。很不幸的是,Erlang 就是编程语言中的“汉语”。所以如果你想基于 RabbitMQ 做一些扩展和二次开发什么的,建议你慎重考虑一下可持续维护的问题。

2. RocketMQ

RocketMQ 是阿里巴巴在 2012 年开源的消息队列产品,后来捐赠给 Apache 软件基金会,2017 正式毕业,成为 Apache 的顶级项目。阿里内部也是使用 RocketMQ 作为支撑其业务的消息队列,经历过多次“双十一”考验,它的性能、稳定性和可靠性都是值得信赖的。作为优秀的国产消息队列,近年来越来越多的被国内众多大厂使用。

我在总结 RocketMQ 的特点时,发现很难找出 RocketMQ 有什么特别让我印象深刻的特点,也很难找到它有什么缺点。

RocketMQ 就像一个品学兼优的好学生,有着不错的性能,稳定性和可靠性,具备一个现代的消息队列应该有的几乎全部功能和特性,并且它还在持续的成长中。

RocketMQ 有非常活跃的中文社区,大多数问题你都可以找到中文的答案,也许会成为你选择它的一个原因。另外,RocketMQ 使用 Java 语言开发,它的贡献者大多数都是中国人,源代码相对也比较容易读懂,你很容易对 RocketMQ 进行扩展或者二次开发。

RocketMQ 对在线业务的响应时延做了很多的优化,大多数情况下可以做到毫秒级的响应,如果你的应用场景很在意响应时延,那应该选择使用 RocketMQ。

RocketMQ 的性能比 RabbitMQ 要高一个数量级,每秒钟大概能处理几十万条消息。

RocketMQ 的一个劣势是,作为国产的消息队列,相比国外的比较流行的同类产品,在国际上还没有那么流行,与周边生态系统的集成和兼容程度要略逊一筹。

3. Kafka

最后我们聊一聊 Kafka。Kafka 最早是由 LinkedIn 开发,目前也是 Apache 的顶级项目。Kafka 最初的设计目的是用于处理海量的日志。

在早期的版本中,为了获得极致的性能,在设计方面做了很多的牺牲,比如不保证消息的可靠性,可能会丢失消息,也不支持集群,功能上也比较简陋,这些牺牲对于处理海量日志这个特定的场景都是可以接受的。这个时期的 Kafka 甚至不能称之为一个合格的消息队列。

但是,请注意,重点一般都在后面。随后的几年 Kafka 逐步补齐了这些短板,你在网上搜到的很多消息队列的对比文章还在说 Kafka 不可靠,其实这种说法早已经过时了。当下的 Kafka 已经发展为一个非常成熟的消息队列产品,无论在数据可靠性、稳定性和功能特性等方面都可以满足绝大多数场景的需求。

Kafka 与周边生态系统的兼容性是最好的没有之一,尤其在大数据和流计算领域,几乎所有的相关开源软件系统都会优先支持 Kafka。

Kafka 使用 Scala 和 Java 语言开发,设计上大量使用了批量和异步的思想,这种设计使得 Kafka 能做到超高的性能。Kafka 的性能,尤其是异步收发的性能,是三者中最好的,但与 RocketMQ 并没有量级上的差异,大约每秒钟可以处理几十万条消息。

我曾经使用配置比较好的服务器对 Kafka 进行过压测,在有足够的客户端并发进行异步批量发送,并且开启压缩的情况下,Kafka 的极限处理能力可以超过每秒 2000 万条消息。

但是 Kafka 这种异步批量的设计带来的问题是,它的同步收发消息的响应时延比较高,因为当客户端发送一条消息的时候,Kafka 并不会立即发送出去,而是要等一会儿攒一批再发送,在它的 Broker 中,很多地方都会使用这种“先攒一波再一起处理”的设计。当你的业务场景中,每秒钟消息数量没有那么多的时候,Kafka 的时延反而会比较高。所以,Kafka 不太适合在线业务场景。

第二梯队的消息队列

除了上面给你介绍的三大消息队列之外,还有几个第二梯队的产品,我个人的观点是,这些产品之所以没那么流行,或多或少都有着比较明显的短板,不推荐使用。在这儿呢,我简单介绍一下,纯当丰富你的知识广度。

先说 ActiveMQ,ActiveMQ 是最老牌的开源消息队列,是十年前唯一可供选择的开源消息队列,目前已进入老年期,社区不活跃。无论是功能还是性能方面,ActiveMQ 都与现代的消息队列存在明显的差距,它存在的意义仅限于兼容那些还在用的爷爷辈儿的系统。

接下来说说 ZeroMQ,严格来说 ZeroMQ 并不能称之为一个消息队列,而是一个基于消息队列的多线程网络库,如果你的需求是将消息队列的功能集成到你的系统进程中,可以考虑使用 ZeroMQ。

最后说一下 Pulsar,很多人可能都没听说过这个产品,Pulsar 是一个新兴的开源消息队列产品,最早是由 Yahoo 开发,目前处于成长期,流行度和成熟度相对没有那么高。与其他消息队列最大的不同是,Pulsar 采用存储和计算分离的设计,我个人非常喜欢这种设计,它有可能会引领未来消息队列的一个发展方向,建议你持续关注这个项目。

总结

在了解了上面这些开源消息队列各自的特点和优劣势后,我相信你对于消息队列的选择已经可以做到心中有数了。我也总结了几条选择的建议供你参考。

如果说,消息队列并不是你将要构建系统的主角之一,你对消息队列功能和性能都没有很高的要求,只需要一个开箱即用易于维护的产品,我建议你使用 RabbitMQ。

如果你的系统使用消息队列主要场景是处理在线业务,比如在交易系统中用消息队列传递订单,那 RocketMQ 的低延迟和金融级的稳定性是你需要的。

如果你需要处理海量的消息,像收集日志、监控信息或是前端的埋点这类数据,或是你的应用场景大量使用了大数据、流计算相关的开源产品,那 Kafka 是最适合你的消息队列。

如果我说的这些场景和你的场景都不符合,你看了我之前介绍的这些消息队列的特点后,还是不知道如何选择,那就选你最熟悉的吧,毕竟这些产品都能满足大多数应用场景,使用熟悉的产品还可以快速上手不是?

思考题

本节课的思考题也是围绕着消息队列的技术选型来设置的。

你开发过的或是正在开发的系统,对消息队列的需求是什么样的?现在选择的消息队列是哪款产品?

在学完了本节课后,你觉得当前选择的消息队列是否是最佳的选择?理由是什么?欢迎在留言区与我分享讨论。

感谢阅读,如果你觉得这篇文章对你有一些启发,也欢迎把它分享给你的朋友。

2.2 实践

TBD

 

 

 

 

 

后续补充

...

3.问题

TBD

4.参考

https://time.geekbang.org/column/article/189279

后续补充

...

热门文章

暂无图片
编程学习 ·

java 中的反射技术

java代码 @SpringBootTest(classes = {ShujiegouApplication.class}) @RunWith(SpringJUnit4ClassRunner.class) public class FansheTest {@Testpublic void test1() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {SysColumn sysColumn …
暂无图片
编程学习 ·

Python使用Request库实现PC端学小易(适用app版本1.0.6)

Python使用Request库实现PC端学小易app(适用app版本1.0.6)前言抓包登录操作抓包搜题操作抓包数据分析登录搜题重点代码实现导入库tkinter实现简易图形界面部分request库实现登录部分搜题部分整理输出至tkinter部分完整代码重点 前言 一直以来学小易只有安卓段与IOS端的app,在…
暂无图片
编程学习 ·

【Flutter 实战】简约而不简单的计算器

老孟导读:这是 【Flutter 实战】组件系列文章的最后一篇,其他组件地址:http://laomengit.com/guide/widgets/Text.html,接下来将会讲解动画系列,关注老孟,精彩不断。先看一下效果:大家学习UI编程语言时喜欢用哪个 App 当作第一个练手的项目呢?,我喜欢使用 计算器 ,可…
暂无图片
编程学习 ·

老鸟给予Java初学者的学习路线的一些建议

java学习这一部分其实也算是今天的重点,这一部分用来回答很多群里的朋友所问过的问题,那就是我你是如何学习Java的,能不能给点建议?今天我是打算来点干货,因此咱们就不说一些学习方法和技巧了,直接来谈每个阶段要学习的内容甚至是一些书籍。这一部分的内容,同样适用于一…
暂无图片
编程学习 ·

2020/7/1 方程根的存在性及个数/证明函数不等式

复习内容科目 内容 补充 时间数学 第九次课(83;148-151) 方程根的存在性及个数、证明函数不等式数学 题型三 方程的根的存在性及个数 1.存在性 方法1:零点定理; 方法2:罗尔定理。 2.根的个数 方法1:单调性 方法2:罗尔定理推论 推论:若在区间III上的f(n)(x)≠0f^{(n)}(…
暂无图片
编程学习 ·

RPC框架正确的使用姿势

RPC框架-Thrift介绍RPC(Remote Procedure Call)远程过程调用,简单的理解是一个节点请求另一个节点提供的服务;本地过程调用:如果需要将本地student对象的age+1,可以实现一个addAge()方法,将student对象传入,对年龄进行更新之后返回即可,本地方法调用的函数体通过函数指…
暂无图片
编程学习 ·

matlab的subplot中间添加ylable

根据图形的坐标轴的大小确定中间位置或者是想要的位置。如下图所示,横坐标师10^6为单位的坐标轴,左边一点的位置大概为-300000,纵坐标最下面一幅图的总高度为1,倒数第二幅图像总高度为0.4,加上下面的空白处,中间位置大概为3.5左右,所以代码为ylabel(Amplitude,position,…
暂无图片
编程学习 ·

组合数学4-全排列与算法

文章目录全排列与算法一 钟声里的全排列**思考**:生成算法二 字典序法1.递归2.字典序法例1:生成字母abc的全排列例2:生成123的全排列例3:生成839647521的全排列3.**思考**:局部连续变化三 SJT算法(Steinhaus–Johnson–Trotter algorithm)1. 引出思路2. 可移动数(mobil…
暂无图片
编程学习 ·

ssm 网上商店实训 部分内容

一、 基础的配置文件applicationContext.xml<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context=…
暂无图片
编程学习 ·

波段选择方法综述

Hyperspectral Band Selection A review 当前的高光谱波段选择方法,该方法可以分为六个主要类别:基于排序,基于搜索,基于聚类,基于稀疏性,基于嵌入学习和基于混合方案。 基于排序的方法根据预定义的频段优先级标准量化每个频谱带的重要性,并按排序的顺序选择排名靠前的频…
暂无图片
编程学习 ·

css3属性选择器

属性选择器 基本用法选择符 简介E[att] 选择具有att属性的E元素E[att=val] 选择具有att属性且属性值等于val的E元素E[att^=“val”] 匹配具有att属性、且值以val开头的E元素E[att$=“val”] 匹配具有att属性、且值以val结尾的E元素E[att*=“val”] 匹配具有att属性、且值中含有…
暂无图片
编程学习 ·

mysql5.7安装

本篇文章介绍的是mysql5.7安装教程! 环境:Windows 类型:msi Mysql安装包可以去官网下载 mysql官网下载 也可以加入我们群聊下载(群文件mysql文件夹下) 另外,加入群聊也可以远程安装 文章目录mysql 5.7安装 准备安装包安装步骤第一步同意协议第二步选择手动安装第三步选择…
暂无图片
编程学习 ·

Java数据结构--顺序栈

一、简介 1.1 概念栈:又称为堆栈,是限制在表的一端进行插入和删除的线性表。其限制是仅允许在表的一端进行插入和删除操作,不允许在其他任何位置进行插入、查找、删除等操作。 表中进行插入、删除操作的一端称为栈顶、栈顶保存的元素称为栈顶元素。相对的,表的另一端称为栈底…
暂无图片
编程学习 ·

TCP/IP协议基础知识笔记

1.TCP/IP协议包括FTP、SMTP、TCP、UDP、IP五中协议 。 2.TCP/IP四层体系结构:应用层、传输层、网络层、数据链路层。 3.TCP传输层协议,IP 网络层协议。 4.链路层:数据包必须是从一块网卡传送到另一块网卡。而网卡地址就是数据包的发送地址和接收地址 5.IP地址与域名均是一一…
暂无图片
编程学习 ·

esp8266 system_partition_table_regist fail 蓝灯闪一下就灭

在添加了如下函数后,蓝灯闪一下就灭,并且串口打印system_partition_table_regist fail: void ICACHE_FLASH_ATTR user_pre_init(void) {if(!system_partition_table_regist(at_partition_table, sizeof(at_partition_table)/sizeof(at_partition_table[0]),SPI_FLASH_SIZE_M…
暂无图片
编程学习 ·

centos自用命令备份

上传 scp -p E:\abc\requirement.txt root@132.232.10.218:/root/stock 下载 scp root@103.51.15.130:/root/project/log/2020-01-07-12-22-15.log D:\ ----------------------------------------- 启动多个脚本 python3 zmq.py & python3 open.py & python3 clos.py &…
暂无图片
编程学习 ·

网络安全技术及应用第3版 主编贾铁军等——教材习题 期末重点 复习题 知识提炼(第8章 防火墙应用技术)

参考教材:网络安全技术及应用 第3版 主编贾铁军等 第8章 防火墙应用技术填空题论述题1)==防火墙的 分类 及 主要技术 有哪些?==2)正确配置防火墙以后,是否能够必然保证网络安全?如果不是,试介绍防火墙的缺点。3) 防火墙阻止SYN Flood攻击,可使用SYN网关防护方式。说明S…
暂无图片
编程学习 ·

网络安全技术及应用第3版 主编贾铁军等——教材习题 期末重点 复习题 知识提炼 (第5章 密码与加密技术)

参考教材:网络安全技术及应用 第3版 主编贾铁军等 第5章 密码与加密技术选择题填空题简答题计算题1)凯撒密码:(将字母表示一个循环的表,再进行移位)2)单字母替换密码3)矩阵转置技术4)RSA算法论述题 选择题 张三给李四发信息,为了实现数据保密,加密秘钥是()————李…