news 2026/7/2 4:56:34

分布式之消息队列复习精讲

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
分布式之消息队列复习精讲

为什么写这篇文章?

博主有两位朋友分别是小A和小B:

  1. 小A,工作于传统软件行业(某社保局的软件外包公司),每天工作内容就是和产品聊聊需求,改改业务逻辑。再不然就是和运营聊聊天,写几个SQL,生成下报表。又或者接到客服的通知,某某功能故障了,改改数据,然后下班部署上线。每天过的都是这种生活,技术零成长。
  2. 小B,工作于某国企,虽然能接触到一些中间件技术。然而,他只会订阅/发布消息。通俗点说,就是调调API。对为什么使用这些中间件啊?如何保证高可用啊?没有充分的认识。

庆幸的是两位朋友都很有上进心,于是博主写这篇文章,帮助他们复习一下关于消息队列中间件这块的要点

复习要点

本文大概围绕如下几点进行阐述:

  1. 为什么使用消息队列?
  2. 使用消息队列有什么缺点?
  3. 消息队列如何选型?
  4. 如何保证消息队列是高可用的?
  5. 如何保证消息不被重复消费?
  6. 如何保证消费的可靠性传输?
  7. 如何保证消息的顺序性?

我们围绕以上七点进行阐述。需要说明一下,本文不是《消息队列从入门到精通》这种课程,因此只是提供一个复习思路,而不是去教你们怎么调用消息队列的API。建议对消息队列不了解的人,去找点消息队列的博客看看,再看本文,收获更大

正文

1、为什么要使用消息队列?

分析:一个用消息队列的人,不知道为啥用,这就有点尴尬。没有复习这点,很容易被问蒙,然后就开始胡扯了。
回答:这个问题,咱只答三个最主要的应用场景(不可否认还有其他的,但是只答三个主要的),即以下六个字:解耦、异步、削峰

(1)解耦

传统模式:


传统模式的缺点

  • 系统间耦合性太强,如上图所示,系统A在代码中直接调用系统B和系统C的代码,如果将来D系统接入,系统A还需要修改代码,过于麻烦!

中间件模式:


中间件模式的的优点

  • 将消息写入消息队列,需要消息的系统自己从消息队列中订阅,从而系统A不需要做任何修改。
(2)异步

传统模式:


传统模式的缺点

  • 一些非必要的业务逻辑以同步的方式运行,太耗费时间。

中间件模式:


中间件模式的的优点

  • 将消息写入消息队列,非必要的业务逻辑以异步的方式运行,加快响应速度
(3)削峰

传统模式


传统模式的缺点

  • 并发量大的时候,所有的请求直接怼到数据库,造成数据库连接异常

中间件模式:


中间件模式的的优点

  • 系统A慢慢的按照数据库能处理的并发量,从消息队列中慢慢拉取消息。在生产中,这个短暂的高峰期积压是允许的。

2、使用了消息队列会有什么缺点?

分析:一个使用了MQ的项目,如果连这个问题都没有考虑过,就把MQ引进去了,那就给自己的项目带来了风险。我们引入一个技术,要对这个技术的弊端有充分的认识,才能做好预防。要记住,不要给公司挖坑!
回答:回答也很容易,从以下两个个角度来答

  • 系统可用性降低:你想啊,本来其他系统只要运行好好的,那你的系统就是正常的。现在你非要加个消息队列进去,那消息队列挂了,你的系统不是呵呵了。因此,系统可用性降低
  • 系统复杂性增加:要多考虑很多方面的问题,比如一致性问题、如何保证消息不被重复消费,如何保证保证消息可靠传输。因此,需要考虑的东西更多,系统复杂性增大。

但是,我们该用还是要用的。

3、消息队列如何选型?

先说一下,博主只会ActiveMQ,RabbitMQ,RocketMQ,Kafka,对什么ZeroMQ等其他MQ没啥理解,因此只能基于这四种MQ给出回答。
分析:既然在项目中用了MQ,肯定事先要对业界流行的MQ进行调研,如果连每种MQ的优缺点都没了解清楚,就拍脑袋依据喜好,用了某种MQ,还是给项目挖坑。如果面试官问:"你为什么用这种MQ?。"你直接回答"领导决定的。"这种回答就很LOW了。还是那句话,不要给公司挖坑。
回答:首先,咱先上ActiveMQ的社区,看看该MQ的更新频率:

<span style="color:#333333"><span style="background-color:#ffffff"><code class="language-mipsasm">Apache ActiveMQ <span style="color:#880000">5</span>.<span style="color:#880000">15</span>.<span style="color:#880000">3</span> Release Christopher L. <span style="color:#0000ff">Shannon </span>posted on Feb <span style="color:#880000">12</span>, <span style="color:#880000">2018</span> Apache ActiveMQ <span style="color:#880000">5</span>.<span style="color:#880000">15</span>.<span style="color:#880000">2</span> Released Christopher L. <span style="color:#0000ff">Shannon </span>posted on Oct <span style="color:#880000">23</span>, <span style="color:#880000">2017</span> Apache ActiveMQ <span style="color:#880000">5</span>.<span style="color:#880000">15</span>.<span style="color:#880000">0</span> Released Christopher L. <span style="color:#0000ff">Shannon </span>posted on <span style="color:#0000ff">Jul </span><span style="color:#880000">06</span>, <span style="color:#880000">2017</span> 省略以下记录 ... </code></span></span>

我们可以看出,ActiveMq几个月才发一次版本,据说研究重心在他们的下一代产品Apollo。
接下来,我们再去RabbitMQ的社区去看一下,RabbitMQ的更新频率

<span style="color:#333333"><span style="background-color:#ffffff"><code class="language-yaml"><span style="color:#a31515">RabbitMQ</span> <span style="color:#880000">3.7</span><span style="color:#880000">.3</span> <span style="color:#a31515">release</span> <span style="color:#880000">30</span> <span style="color:#a31515">January</span> <span style="color:#880000">2018</span> <span style="color:#a31515">RabbitMQ</span> <span style="color:#880000">3.6</span><span style="color:#880000">.15</span> <span style="color:#a31515">release</span> <span style="color:#880000">17</span> <span style="color:#a31515">January</span> <span style="color:#880000">2018</span> <span style="color:#a31515">RabbitMQ</span> <span style="color:#880000">3.7</span><span style="color:#880000">.2</span> <span style="color:#a31515">release23</span> <span style="color:#a31515">December</span> <span style="color:#880000">2017</span> <span style="color:#a31515">RabbitMQ</span> <span style="color:#880000">3.7</span><span style="color:#880000">.1</span> <span style="color:#a31515">release21</span> <span style="color:#a31515">December</span> <span style="color:#880000">2017</span> <span style="color:#a31515">省略以下记录</span> <span style="color:#a31515">...</span> </code></span></span>

我们可以看出,RabbitMQ版本发布比ActiveMq频繁很多。至于RocketMQ和kafka就不带大家看了,总之也比ActiveMQ活跃的多。详情,可自行查阅。
再来一个性能对比表

特性ActiveMQRabbitMQRocketMQkafka
开发语言javaerlangjavascala
单机吞吐量万级万级10万级10万级
时效性ms级us级ms级ms级以内
可用性高(主从架构)高(主从架构)非常高(分布式架构)非常高(分布式架构)
功能特性成熟的产品,在很多公司得到应用;有较多的文档;各种协议支持较好基于erlang开发,所以并发能力很强,性能极其好,延时很低;管理界面较丰富MQ功能比较完备,扩展性佳只支持主要的MQ功能,像一些消息查询,消息回溯等功能没有提供,毕竟是为大数据准备的,在大数据领域应用广。
综合上面的材料得出以下两点:
(1)中小型软件公司,建议选RabbitMQ.一方面,erlang语言天生具备高并发的特性,而且他的管理界面用起来十分方便。正所谓,成也萧何,败也萧何!他的弊端也在这里,虽然RabbitMQ是开源的,然而国内有几个能定制化开发erlang的程序员呢?所幸,RabbitMQ的社区十分活跃,可以解决开发过程中遇到的bug,这点对于中小型公司来说十分重要。不考虑rocketmq和kafka的原因是,一方面中小型软件公司不如互联网公司,数据量没那么大,选消息中间件,应首选功能比较完备的,所以kafka排除。不考虑rocketmq的原因是,rocketmq是阿里出品,如果阿里放弃维护rocketmq,中小型公司一般抽不出人来进行rocketmq的定制化开发,因此不推荐。
(2)大型软件公司,根据具体使用在rocketMq和kafka之间二选一。一方面,大型软件公司,具备足够的资金搭建分布式环境,也具备足够大的数据量。针对rocketMQ,大型软件公司也可以抽出人手对rocketMQ进行定制化开发,毕竟国内有能力改JAVA源码的人,还是相当多的。至于kafka,根据业务场景选择,如果有日志采集功能,肯定是首选kafka了。具体该选哪个,看使用场景。

4、如何保证消息队列是高可用的?

分析:在第二点说过了,引入消息队列后,系统的可用性下降。在生产中,没人使用单机模式的消息队列。因此,作为一个合格的程序员,应该对消息队列的高可用有很深刻的了解。如果面试的时候,面试官问,你们的消息中间件如何保证高可用的?你的回答只是表明自己只会订阅和发布消息,面试官就会怀疑你是不是只是自己搭着玩,压根没在生产用过。请做一个爱思考,会思考,懂思考的程序员。
回答:这问题,其实要对消息队列的集群模式要有深刻了解,才好回答。
以rcoketMQ为例,他的集群就有多master 模式、多master多slave异步复制模式、多 master多slave同步双写模式。多master多slave模式部署架构图(网上找的,偷个懒,懒得画):


其实博主第一眼看到这个图,就觉得和kafka好像,只是NameServer集群,在kafka中是用zookeeper代替,都是用来保存和发现master和slave用的。通信过程如下:
Producer 与 NameServer集群中的其中一个节点(随机选择)建立长连接,定期从 NameServer 获取 Topic 路由信息,并向提供 Topic 服务的 Broker Master 建立长连接,且定时向 Broker 发送心跳。Producer 只能将消息发送到 Broker master,但是 Consumer 则不一样,它同时和提供 Topic 服务的 Master 和 Slave建立长连接,既可以从 Broker Master 订阅消息,也可以从 Broker Slave 订阅消息。
那么kafka呢,为了对比说明直接上kafka的拓补架构图(也是找的,懒得画)


如上图所示,一个典型的Kafka集群中包含若干Producer(可以是web前端产生的Page View,或者是服务器日志,系统CPU、Memory等),若干broker(Kafka支持水平扩展,一般broker数量越多,集群吞吐率越高)

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/2 4:53:31

番茄小说下载器完整指南:构建个人数字图书馆的终极方案

番茄小说下载器完整指南&#xff1a;构建个人数字图书馆的终极方案 【免费下载链接】Tomato-Novel-Downloader 番茄小说下载器不精简版 项目地址: https://gitcode.com/gh_mirrors/to/Tomato-Novel-Downloader 你是否曾遇到过这样的情况&#xff1a;在番茄小说上找到一部…

作者头像 李华
网站建设 2026/7/2 4:50:40

OpenCV + Python 高效组合

Python 原生循环极慢&#xff0c;OpenCV 底层是 C 实现&#xff0c;尽量用 OpenCV 内置矩阵运算替代 Python for 循环是提速核心&#xff1b;搭配 NumPy 向量化、多线程、内存复用能成倍提升速度。下面分场景整理最强函数组合&#xff0c;附使用场景与提速原理。一、图像像素遍…

作者头像 李华
网站建设 2026/7/2 4:48:35

计算机Java毕设实战-基于 SpringBoot 的潮玩手办线上购物商城系统的设计与实现 基于 SpringBoot 的二次元周边商品交易系统【完整源码+LW+部署说明+演示视频,全bao一条龙等】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/7/2 4:45:05

Gemini AI工具全家桶深度应用指南

1. 你真的了解Gemini全家桶的全部潜力吗&#xff1f;作为一名长期混迹AI工具圈的深度用户&#xff0c;我见过太多人把Gemini系列产品当作"高级版搜索引擎"或"美图秀秀Pro"来使用。这就像用一台超级计算机只做加减法一样令人痛心。Gemini 3.1 Pro、Nano Ban…

作者头像 李华
网站建设 2026/7/2 4:43:56

SSH协议详解+Xshell连接虚拟机+Xftp文件传输全流程

一、什么是SSH连接协议 SSH&#xff08;Secure Shell&#xff0c;安全外壳协议&#xff09;是一种建立在应用层的加密网络传输协议&#xff0c;主要用于远程登录服务器/虚拟机、远程执行命令和安全文件传输。 1.核心优势&#xff1a;传统Telnet协议传输明文数据极易被窃听、篡改…

作者头像 李华
网站建设 2026/7/2 4:43:29

00-源码解析导学:深入Vue底层机制

源码解析导学&#xff1a;深入Vue底层机制 本系列将带你深入Vue框架的核心源码&#xff0c;从响应式原理到虚拟DOM Diff算法&#xff0c;从编译器到组件化实现&#xff0c;彻底理解Vue的底层工作机制。 一、前言 "会用"和"懂原理"是两种截然不同的技术境界…

作者头像 李华