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

1.应用场景

见: 消息队列必知必会 - 学习/实践_william_n的博客-CSDN博客

2.学习/操作

02 | 该如何选择消息队列?_第1张图片1. 文档

02 | 该如何选择消息队列?-极客时间

文章内容

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

作为一个程序员,相信你一定听过“没有银弹”这个说法,这里面的银弹是指能轻松杀死狼人、用白银做的子弹,什么意思呢?

我对这句话的理解是说,在软件工程中,不存在像“银弹”这样可以解决一切问题的设计、架构或软件,每一个软件系统,它都是独一无二的,你不可能用一套方法去解决所有的问题。

在消息队列的技术选型这个问题上,也是同样的道理。并不存在说,哪个消息队列就是“最好的”。

常用的这几个消息队列,每一个产品都有自己的优势和劣势,你需要根据现有系统的情况,选择最适合你的那款产品。

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

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

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

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

其次,这个产品必须是近年来比较流行并且有一定社区活跃度的产品。流行的好处是,只要你的使用场景不太冷门,你遇到 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. 整理输出

TBD

后续补充

...

3.问题/补充

1. 内卷深井冰

仔细阅读了三遍,每一字都是精华
选择中间件的考量维度:可靠性,性能,功能,可运维行,可拓展性,是否开源及社区活跃度
rabbitmq:
优点:轻量,迅捷,容易部署和使用,拥有灵活的路由配置
缺点:性能和吞吐量较差,不易进行二次开发
rocketmq:
优点:性能好,稳定可靠,有活跃的中文社区,特点响应快
缺点:兼容性较差,但随着影响力的扩大,该问题会有改善
kafka:
优点:拥有强大的性能及吞吐量,兼容性很好
缺点:由于“攒一波再处理”导致延迟比较高
pulsar:
采用存储和计算分离的设计,是消息队里产品中黑马,值得持续关注

02 | 该如何选择消息队列?_第2张图片

2. 请问一下老师rocketMQ是怎么做到低延时的?

作者回复: 主要是设计上的选择问题,Kafka中到处都是“批量和异步”设计,它更关注的是整体的吞吐量,而RocketMQ的设计选择更多的是尽量及时处理请求。

比如发消息,同样是用户调用了send()方法,RockMQ它会直接把这个消息发出去,而Kafka会把这个消息放到本地缓存里面,然后择机异步批量发送。

所以,RocketMQ它的时延更小一些,而Kafka的吞吐量更高。

网友补充:

1. batch.size和linger.ms都是可以通过调节来平衡吞吐量和延时的;

2. 消费端消费消息的时候,kafka是client采取轮询,拉的方式,rocketmq的是消费端与broker之间的配合实现推拉结合的方式;

3. 一套架构中是否可能存在多套中间件?在线的生产业务使用rockmq,运维/监控方面使用kafka。

作者回复: 当然可以,架构无所谓好坏,关键是适合。用多套MQ好处是发挥各自的长处,代价是维护成本比较高。具体是不是适合,还是要架构师根据各种实际情况来权衡。

网友补充:

1. 非常正常。涉及到大数据之间计算的kafka,业务rocketmq,数据之间可以通过bridge flow即可;

2. 某母婴产品的一个同事跟我说,他们公司就是这样处理的,用Rocket处理订单,用kafka处理埋点和日志,看来还是对kafka的稳定性不是那么的肯定;

4. 我所在公司用rabbitmq也遇到消息的有序性无法保证的问题,通过在业务层面去弥补,终究不是种好方案。请问老师在保证有序性消费上有什么好的方案?

作者回复: 正确的使用RabbitMQ是可以保证严格有序的,你在学习完“03 消息模型:主题和队列有什么区别?”之后,再看一下RabbitMQ的配置应该就会知道该如何解决你的问题了。

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

老师,批次的大小是可配置的,在我们的使用场景中,如果消息没有积压的情况下,延迟基本上小于10ms,我想问一下rocketmq的延迟一般是多少?

作者回复: 配置得当的情况下,可以做到2-3ms。

6. 老师 exchange是rabbitmq独有的么?exchange好像属于amqp协议,看了看amqp似乎说到了。

作者回复: exchange确实是AMQP协议中定义的,RabbitMQ是AMQP的一个实现。

7. 老师, 能稍微讲下emq跟nsq 的优缺点跟性能吗?

作者回复:

emq是专注于MQTT场景的一个消息队列,如果你的使用场景是连接海量的IoT设备,可以考虑。
nsq使用Go语言开发,如果团队的技术栈是基于Go语言搭建的,nsq是一个很好的选择。
这两个消息队列我都没有深入的使用和测试过,所以没办法跟你分享它们的优缺点和性能。

网友补充:

emq 完全不适合消息积压,相信您看过emq的官方手册就知道了,每个topic可以配置保留最多保留几条消息,注意这个配置是全局配置,且对性能本身会有影响。。所以默认最多一条即可

8. 想问下老师,关于MQ丢消息是怎么看的。我在用MQ的时候一直没有办法放心,如果在每个发MQ的场景都加一个补偿任务来保证最终一致性,又觉得MQ本身解耦的特性就浪费了。

消息丢失主要有这么几个场景:
1.客户端在发MQ消息的时候,网络抖动timeout导致没有发出去。
2.客户端发MQ消息成功后,MQ本身有可能会丢消息。(虽然我看RocketMQ官方说不会丢,有持久化)
3.业务处理完后,准备发MQ消息的时候,系统崩溃或者重启,导致消息没有发出去。

作者回复:

2 这种情况你不用担心,无论从理论上,还是很多生产系统的实际验证,都不会丢消息的。
1、3 二种情况是一样的,就是没发消息或者发失败了,这种情况其实和你把数据往数据库里写失败了是类似的,具体怎么处理还是得看业务。
比如说,重要的业务可以用一主一备二个主题。

9. 老师好,rocket mq为何号称金融级的稳定性呢

作者回复: 金融级只是一种说法,并没有什么标准。但确实有很多涉及金融类的系统选择使用RocketMQ。

10. kafka如果凑不够一批,那等什么时候发送?

作者回复: 建议看一下batch.size和linger.ms这两个参数的含义

11. 流处理中消息延迟不能避免回溯处理,kafka如果消息已经不在内存里,访问性能会有影响,pulsar 可以很好解决这个问题吗?

作者回复:

挖坟的问题,受内存大小的限制,不太好解决。这和采用哪种消息队列关系不太大。

有条件的话,可以使用SSD结合Raid,消费速度基本上是可以打满万兆网卡的。

12. 一直不明白一个问题,每秒处理几万~几十万数据,这不应该是按照下游业务的消费能力来讲的吗,比如我们现在的服务tps就只能打到几百。还是说老师和网上讲的都是发送到消息队列的能力?又或是几万几十万只针下游业务只打个日志专门用来做性能测试的情况?希望解答下

作者回复:

我们提到的都是消息队列本身的性能,不包括生产者和消费者处理各自业务逻辑的时间。一般测试消息队列性能的时候,生产者和消费者是没有任何业务逻辑的。

个人补充:

确实不应该考虑上下游的生产和消费能力去测试消息队列的性能,因业务的不同,测试消息队列的结果自然也不同,但是自己结合自身业务,进行测试。从而得出自身业务系统能发挥出消息队列的性能的几层功力。另外,消息队列本身的性能涉及到两方面,即读写性能,或者说收发性能,至于存储,对上下游服务,本身应该是透明的,只要消息队列本身能够保证存储是没问题的,基本不需要去关注。

13. 老师您好,
请问是否有消息队列支持延时消息,并可以撤回延时消息的?

需求:物联网平台要对设备离线事件做监控,我想在每次设备上报数据时,发送一个延时判断离线的延时消息到MQ,如果设备正常再次上报数据,就取消上次的延时消息,并发送一个新的延时消息。
目的是不希望每次上报数据都会导致消费端做一次离线判断,只需要对最后一次上报做判断即可。

作者回复: 但我个人的意见:这个需求不太适合用MQ来实现。

另外,是不是可以换个思路来考虑这个问题,你一定需要一个设备离线的通知来触发什么业务逻辑吗?还是只是需要查询设备的时候,能正确的给出设备是否在线就可以了?

如果是后者,实现代价要低很多。

02 | 该如何选择消息队列?_第3张图片

14. 我们的云平台有多个项目,每个项目用的消息中间件不同,有的用RabbitMQ, 有的用Kafka, 请教老师,这些消息中间件可以建设成一个统一的,集中式的架构吗?也就是建设成一个消息中间件平台,所有的项目来共用。

作者回复: 当然可以,在京东就是这样的集中式大集群,为所有业务提供消息服务。

02 | 该如何选择消息队列?_第4张图片

15. 1:该如何选择MQ?
多快好省,适合的既是最好的。
1-1:多——功能多,比如:保证不丢消息、保证不重复消费、支持顺序消费、支持集群、支持消息持久化,用的人多,支持的人多,兼容的产品多
1-2:快——跑的快,性能高,延迟底
1-3:好——好学习,好维护,好二次开发
1-4:省——开源省钱,易维护也省钱,性能稳定省心
多快好省能存在确实非常好,不过这只能是愿望,世间没有十全十美的解决方案,要一样往往需要舍一样。

2:根据老师的分析,我觉得基本的选择次序是
2-1:kafka
2-2:rocketMQ
2-3:rabbitMQ
2-4:pulsar
2-5:公司自研

疑问?
已经有如此之多的选择了,还要自研,难道没有一个合适的嘛?老师觉得自研的核心支撑点是什么?
另外,在学习kafka的时候,清楚的记得两点
一是:单分区才能保证顺序消费
二是:消息不能保证100%不丢失,这个和老师的描述有出入?假如某一时刻leader副本所在的broker都宕机了,那消息还能不丢嘛?或者某一时刻所有broker都宕机了?这样会丢消息吧?

作者回复: 自研的主要原因有二个:第一是规模足够大,能够负担得起自研的成本。第二是,每种消息队列都有它的优势和劣势,不能完全适合大厂的需求。

关于Kafka如何保证顺序消费,可以看一下08答疑这节课中的内容。

另外,当前版本的Kafka是可以保证完全不丢消息的,丢消息已经是n年前很老的版本时的旧黄历了。

16. Kafka 不太适合在线业务场景。这个我不同意,这些完全可以立即发送

作者回复: 技术有好坏,但架构设计上,特别是技术选择都没有绝对的对错,适合就好。

Kafka的时延虽然稍大一些,但也只是ms基本的差异,也不是完全不能用于在线业务。

17. redis不是也可做消息队列吗

作者回复: 是可以的。

不过作为一款消息队列来说,redis无论是功能还是性能,与真正的消息队列都有很大的差距。

网友补充:
redis做消息队列有两种玩法,一种是使用pub/sub,但是消息无法持久化;另一种使用list数据结构,消息可以持久化了,但性能堪忧。

问题:

用stream呢?
TBD

18. 我们是用户充值+积分业务。采取的RocketMQ。但是我想吐槽:Rocket MQ捐给apache后,apache把中文注释删的干干净净,问题来了:英文注释一个字没有。好难受呀。

20. 老师,在文章结尾地方提到了前端埋点这个名词,能帮忙解释一下这个名词吗?该怎么去理解呢?

作者回复:

这里面“埋点”指的是在APP、小程序和Web页面上的采集的数据,这些埋点数据记录用户的行为,比如你打开了哪个页面,点击了哪个按钮,在哪个商品上停留了多久等等这些用户行为信息。

21. 为什么因为 Kafka 有“微批”的机制就说 Kafka 不太适合在线业务场景呢?延迟也没有这么夸张吧,而且也可以通过将 linger.ms 调小尽快发布消息。
不太理解老师为什么这么说?

作者回复: 主要是发送性能的考虑。在线业务场景下,Kafka的发送时延是要明显高于其它MQ的。

22. 老师,用rabbitmq,kafka,rocketmq,你们线上消费消息都是用的推模式还是拉模式啊?

作者回复:

给用户提供的API一般都是推模式,比较易于使用。
大部分消息队列内部的实现都是拉模式,性能比较好。

23.  李老师所说的是不是可以按照CAP理论来讲,不同场景总要做出取舍对吧;
另外,目前在线业务使用RocketMQ,做了二次开发的,中文支持不错而且社区响应速度快

作者回复: 是的,架构设计很多情况下是在做取舍和选择。

24. 老师好,看了这节课感觉在线业务上rocketmq比较适合,但是我是php开发的,用rocketmq了解了一下,要装的扩展很多,很多都是第三方自己开发的,生产环境下可能要做很多调整。想请问一下有适合php开发的消息通道么

作者回复: 可以考虑一下RabbitMQ:https://www.rabbitmq.com/tutorials/tutorial-one-php.html

网友补充:

php还是用RabbitMQ方便些

25. 我们现在用的kafka,主要场景是做异步处理,我们做消息发送时,用的是异步去发送,通过定时到数据库去拉数据,然后发送!主要考虑的场景是,因为kafka现在用的异步刷盘方式,可能会丢失一个窗口内的数据,所以业务中做了一层包装!请问老师是怎么考虑这种场景的

作者回复: 正确使用Kafka是不会丢数据的,即使Kafka有异步发送、异步刷盘的机制,也可以通过一些配置确保不丢数据。

具体方法请看一下《05 | 如何确保消息不会丢失?》

26. 想咨询一下NSQ这个消息队列究竟怎么样,最近在选Kafka还是NSQ中纠结,golang做的后台是不是更适合选NSQ呢

作者回复: 如果你团队都是go语言技术栈,并且对消息队列没有特殊的需求,建议你选用NSQ,原因我在文中也提到过,选一个和自己团队技术栈相同的产品,后续维护成本相对低一些。

27. 在做银行项目,目前还没有引入消息队列,计划要有消息队列来提升性能,个人理解银行项目的可靠性要求高,消息不能丢失,不能重复消费,可回溯,什么队列合适呢?相对而言,是否rocketmq

作者回复: 可以在有消息堆积能力(支撑可回溯需求)的消息队列里面选择,Kafka和RocketMQ都可以满足这些要求。

关于重复消费的问题,后面我会专门讲到该如何处理。

28. 李老师,你是如何评价Disruptor这个MQ队列的?

作者回复: 这是一个队列的库,虽然功能有一些相似,但使用场景和消息队列是不一样的

网友补充:

disruptor是本地队列。

用于高吞吐量下的线程一致性, 性能优于JDK自带的Queue。但它本身不是消息队列。

29. 老师,新人想请问一下:redis跟消息队列的关系,redis不也是开源的吗?

作者回复: redis 是一个kv存储系统,和消息队列的功能是不一样的。

30. 老师, 能在资源占用方面讲一下rabbitmq、rocketmq、kafka的区别吗?比如1w tps, 大概要多少节点多少配置, 10w要多少

作者回复: 这个没法统一给出答案,涉及的变量太多,消息的大小,集群配置的方式、服务器的配置、同步异步发送、是否开启压缩、客户端的并发数量等等都会很大的影响实际的tps。

但一般来说,如果不考虑集群,10w以下tps,应该单个Broker就差不多可以满足。

31. AWS的SNS+SQS怎么样?对于使用AWS的系统,云端消息队列和开源消息队列怎么选择?

作者回复: 这个问题已经不是技术问题了,你更多的需要从成本,运维方便程度,后续是否有可能从AWS迁出,这些方面来考虑。

32. 请问老师有没有用c++的消息队列呢

作者回复: 你是指用C++实现的,还是支持C++客户端的消息队列呢?

如果是后者,很多消息队列都支持使用C++语言接入。

33. 您好,请问在mq中 最容易出问题或者是最重要的点应该在哪里

作者回复: 应该是丢消息的问题。后面我们会有专门的课程来讲如何确保不丢消息。

34. 老师,kafka是批量发送的话,对于处理多个消息处理一个业务的时候是不是会出现先后顺序的问题

作者回复: 批量也是保证顺序的。

35. 老师可以聊一下 Beanstalk 吗?任务队列和消息队列有哪些区别?

作者回复: beanstalkd主要的功能应该是做任务调度。

36. 之前使用rabbitmq,后来因为吞吐量的问题就换了,目前已经有90%迁移到rocketmq上来了。
当初考量rocketmq和kafka,最终选了rocketmq,主要是考虑rocketmq用java写的源码比较容易看懂,另外支持一些独特的功能比如事务消息,定时消息。
另外还有一点是被rocketmq的介绍打动,其宣称“kafka在topic特别多的情况下性能会有大幅度下降而rocketmq依然坚挺”,并附上很测试结果(全网可搜)。不知道老师对这个结论有什么看法?

作者回复: 和我们测试的结论差不多。

37. 这些消息队列丟消息的原因是啥,比如说kafka为啥会丟消息,又是怎么改进的?

作者回复: 早期的Kafka它是为处理海量日志而设计的,这个场景下,它注重的是吞吐量,少量的日志丢失对业务来说不是问题。所以它设计层面就没有可靠性保证,换取的是超高的吞吐量。

但是现在的Kafka已经有非常完善的数据可靠性保证机制,正确的配置和使用就不会丢消息。

38. 现在项目里主要还是使用 kafka,对 kafka 的访问接口进行了二次封装,便于业务团队使用。同时,在一些轻量级场景下,项目正在考虑使用 redis 提供的 mq 功能实现消息队列。老师能讲讲 redis mq 在使用上的优缺点不?

作者回复: 据我了解,新版的Redis支持 Pub/Sub功能,但它只是一个“支持Pub/Sub功能的KV Store”,对于消息这块儿,它和主流的消息队列比,无论是功能、性能还是扩展性方面都是有很多差异的。但也不意味着你不能选择Redis用于收发消息,比如你现在的业务重度依赖Redis,你正好有一些Pub/Sub的需求,Redis也能满足,那就没必要专门再上一套MQ集群。

02 | 该如何选择消息队列?_第5张图片

 

39. 请问rabbitmq的响应延时不是微秒级别吗?为啥考虑延时问题会选择rocketmq

作者回复:

这个是相对Kafka来说的。微妙级的响应时延基本上只存在于实验室里。真正在生产环境,在比较好的IDC内内网中,一般网络时延能做到500-1000us已经很不错了,再加上Broker本身处理的时延,能做到1ms左右的时延已经是非常理想了,所以,我的观点是,不用纠结到底是微妙级还是毫秒级。

网友补充:

网络通信本身就要占用几个ms 所以1ms在实际生产下没有必要特意要求 这种场景不是没有 只不过我们大多数不需要达到工业级标准。
其实50ms-100ms对用户来说响应是非常快的 而这个时间范围对我们来说刚刚好

40. 老师,我在使用kafka的时候,没有发现您说的“攒一会儿再发送”,而是生产者很快将消息发送出去,消费者每次只消费很少的数据,设置过几个参数都不起作用,怎么设置批量消费呢?

作者回复: Kafka内部采用的是批消息集群,每批中有多少条消息,是在Producer决定的,决定每批中有多少消息,主要是在Producer中的2个参数来控制的:linger.ms and batch.size

个人想法:

突然想到,生产者与消费者,都是相对而言,消息队列相对于消费者,可能也充当了生产者的角色。

同样消息队列相对于真正的消息生产者,就化身成了消费者。

4.参考

02 | 该如何选择消息队列?-极客时间

后续补充

...

你可能感兴趣的:(消息队列-MQ,DESIGN,消息队列,选择)