当前位置: 首页 > news >正文

如何选择消息队列

作为一个程序员,我们必须要认识到,软件工程中是不存在”银弹“的。<!--more-->

在消息队列的选型问题上,也是同样的道理。并不存在哪个消息队列就是最好的,能够解决所有的问题。常用的消息队列有好几个,每一种都有自己的优势和劣势,需要业务方根据自己的系统的情况,选择最适合的产品。

选择消息队列的基本标准

1、开源

首先,必须是开源的产品,因为一旦在开发过程中遇到一个系统 Bug,你至少有机会通过修改源代码来修复这个 Bug,而不是只能无期限地等待产品的开发者发布新版本解决该问题。

2、流行

其次,这个产品必须是近年来比较流行并且有一定社区活跃度的产品。流行意味着使用的人很多,只要你的场景不是很冷门,几乎你遇到的 Bug 都有前辈已经踩过坑了,都能找到类似的解决方案。

同时流行的产品与周边生态系统会有一个比较好的集成和兼容,大部分场景下不需要为自己的业务额外地去开发其他中间件。

3、可靠

需要保证消息传递的可靠,确保消息不会丢失。

4、支持 Cluster

支持集群,确保不会因为某个节点宕机导致服务不可用的情况,同时也需要保证消息不会丢失

5、性能

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

可供选择的消息队列产品

1、RabbitMQ

老牌消息队列 RabbitMQ,俗称兔子 MQ。它是用一种比较小众的语言:Erlang 编写的,最早为电信行业系统之间的可靠通信设计的,支持 AMQP 协议。

它的特点是:轻量级、迅捷,宣传口号是:”开箱即用的消息队列“,是一个相当轻量级的消息队列,非常容易部署和使用。因此 RabbitMQ 成为了 ”最流行的消息中间件之一“。

RabbitMQ 一个比较有特色的功能是支持非常灵活的路由配置,和其他消息队列不同的是,它在生产者和队列之间增加了一个类似交换机的 Exchange 模块。这个模块根据配置的路由规则将生产者发出的消息分发到不同的队列中。路由的规则也非常灵活,甚至可以自己来实现路由规则。

这里通过一个示例,详细解释一下 Exchange 模块的作用:

假设你有一个电商网站,你希望根据用户的购买地理位置将订单消息路由到不同的队列,以便分别处理。

  1. 创建 Exchange: 首先,你会创建一个 Exchange,可以命名为 "OrderExchange"。这是消息的中转站,它会接收生产者发送的订单消息,并负责将这些消息路由到一个或多个队列中。

  2. 创建队列: 然后,你会创建多个队列,每个队列代表一个不同的地理位置,比如 "USOrders"、"EUOrders" 和 "AsiaOrders"。

  3. 定义绑定规则: 接下来,你会定义绑定规则。这些规则告诉 Exchange 如何将消息路由到队列。例如,你可以定义规则,将订单消息中的地理位置信息与队列的名称进行匹配。如果订单来自美国,它将被路由到 "USOrders" 队列,如果来自欧洲,它将被路由到 "EUOrders" 队列。

  4. 生产者发送消息: 当用户在网站上下订单时,订单服务会将订单消息发送到 "OrderExchange"。这个消息会带有订单信息,包括地理位置。

  5. Exchange 路由消息: "OrderExchange" 根据你定义的规则,将消息路由到相应的队列。如果订单来自美国,它将被发送到 "USOrders" 队列。

  6. 队列消费消息: 各个队列中的消费者(可能是不同的处理订单的系统)订阅相应队列并处理订单消息。"USOrders" 队列中的消费者处理来自美国的订单,"EUOrders" 队列中的消费者处理来自欧洲的订单,依此类推。

RabbitMQ 的客户端所支持的编程语言是消息队列中最多的,如果你的系统是使用某种冷门语言开发,那你可以尝试找到对应的 RabbitMQ 客户端,不出意外的话,应该是能找到的。

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

  1. 消息堆积:RabbitMQ 的设计理念是管道,它对消息堆积的支持有限,大量消息堆积可能导致性能下降。因此,它不是最佳选择用于需要大规模消息堆积的应用。

  2. 性能较差:相对于其他消息队列系统,RabbitMQ 的性能较差。它通常能够处理每秒数万到十几万条消息,性能依赖于硬件配置,虽然大多数的应用场景也够用了,但如果对消息队列的性能要求非常高的话,就不要选择 RabbitMQ。

  3. 二次开发难:RabbitMQ 使用的 Erlang 语言不仅非常小众,而且这个语言的学习曲线非常陡峭。如果想基于 RabbitMQ 做一些扩展和二次开发,则需要慎重考虑可持续维护的问题。

2、RocketMQ

RocketMQ 是阿里巴巴开源的消息队列产品,后捐赠于 Apache 软件基金会,成为其顶级项目。它经历多次 ”双十一“ 的考研,性能、稳定性和可靠性都是值得信赖的,是一款优秀的国产消息队列。

RocketMQ 有非常活跃的中文社区,大多数问题都能够找到中文的答案,这或许也是越来越多国内大厂使用的原因。另外,它使用 Java 语言开发,贡献者大多数都是中国人,源代码也相对比较容易读懂,很方便进行扩展或二次开发。

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

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

RocketMQ 的一个劣势是,国际知名度比较低,与周边生态系统的集成和兼容程度要略逊一筹。

3、Kafka

Kafka 最早是由 Linkedln 开发,目前也是 Apache 的顶级项目,它最初的设计目的是用于处理海量的日志

在早期的版本中,为了获得极致的性能,在设计方面做了很多牺牲,比如不保证消息的可靠性,可能会丢失消息,也不支持集群,功能上也比较简陋。这些牺牲对于处理海量日志这个特定的场景是可以接收的,但此时的 Kafka 不能被称为一个合格的消息队列。在随后几年 Kafka 逐步补齐了短板,当下的 Kafka 已经发展为一个非常成熟的消息队列产品,无论数据可靠性、稳定性和功能特性等方面都可以满足绝大多数场景了。

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

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

然而,Kafka采用的异步批量消息处理设计会引发一个问题,即它的同步消息传递响应时延较高。这是因为在客户端发送一条消息后,Kafka不会立即传递消息,而是会等待一段时间以便累积一批消息后再一起处理。这种"批量处理"设计在Kafka的Broker中多次出现。在业务场景中,如果每秒的消息数量相对较低,Kafka的响应时延可能会变得较高。因此,Kafka通常不太适用于需要低延迟的在线业务场景。

第二梯队的消息队列

除了上述比较常用的消息队列,还有一些不太常用的产品,之所以不太流行肯定是有原因的,所以不推荐使用。下面简单介绍一下:

1、ActiveMQ

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

2、ZeroMQ

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

3、Pulsar

Pulsar是一个相对较新的开源消息队列系统,最初由Yahoo开发,目前仍处于不断成长和发展的阶段。与其他传统消息队列系统最显著的不同之处在于其采用了存储和计算分离的设计思想。不少人比较喜欢这种设计,它有可能会引领未来消息队列的一个发展方向。

总结

根据上述多种消息队列的讲解,对于消息队列的选择肯定已经心中有数了,下面给出几点意见:

  • 如果你的系统中消息队列不是主要部分,且对消息队列的功能和性能没有很高的要求,只需要用一个开箱即用易于维护的产品,则开源使用 RabbitMQ

  • 如果你的系统使用消息队列的场景是处理在线业务,比如交易系统中用消息队列传递订单,那么 RocketMQ低延迟和稳定性是比较推荐的

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

相关文章:

如何选择消息队列

作为一个程序员&#xff0c;我们必须要认识到&#xff0c;软件工程中是不存在”银弹“的。<!--more--> 在消息队列的选型问题上&#xff0c;也是同样的道理。并不存在哪个消息队列就是最好的&#xff0c;能够解决所有的问题。常用的消息队列有好几个&#xff0c;每一种都…...

读取mysql数据库表结构生成接口文档

1、引入依赖 <!-- 导出word --><dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.30</version></dependency><!-- https://mvnrepository.com/artifact/e-iceblue/s…...

【MySQL索引与优化篇】InnoDB数据存储结构

文章目录 1. 数据库的存储结构:页1.1 磁盘与内存交互基本单位:页1.2 页结构概述1.3 页的上层结构 2. 页的内部结构3. InnoDB行格式(或记录格式)3.1 Compact行格式3.2 Dynamic和Compressed行格式3.3 Redundant行格式 4. 区、段与碎片区4.1 为什么要有区&#xff1f;4.2 为什么要…...

Go学习第十二章——Go反射与TCP编程

Go反射与TCP编程 1 反射1.1 基本介绍1.2 快速入门1.3 注意事项和细节说明1.4 最佳实践 2 Tcp Socket编程2.1 基本介绍2.2 入门案例2.3 服务器监听2.4 服务器接受客户端消息 1 反射 1.1 基本介绍 **反射&#xff1a;**在编译时静态类型语言中实现动态特性的一种机制。 Go语言…...

uniapp编译微信小程序富文本rich-text的图片样式不生效原因

this.detail.contents this.detail.contents.replace(/\<img/gi, <img style"display:block;max-width:90%;height:auto;border:2px solid #eee;box-shadow:5px 5px 5px rgba(100,100,100,0.8);margin-bottom:10px;text-align:center;" );开始采用这个replace…...

Django实战项目-学习任务系统-任务管理

接着上期代码框架&#xff0c;开发第3个功能&#xff0c;任务管理&#xff0c;再增加一个学习任务表&#xff0c;用来记录发布的学习任务的标题和内容&#xff0c;预计完成天数&#xff0c;奖励积分和任务状态等信息。 第一步&#xff1a;编写第三个功能-任务管理 1&#xff0…...

ubuntu18.04设置开机自动启动脚本(以自动启动odoo命令行为例讲解)

简介 ubuntu作为服务器使用时&#xff0c;常常需要在机器重启时能自动启动我们开发的服务。 Ubuntu 16.10开始不再使用initd管理系统&#xff0c;改用systemd&#xff0c;包括用systemctl命令来替换了service和chkconfig的功能。 systemd 默认读取 /etc/systemd/system 下的配…...

golang工程——grpc-gateway 转发http header中自定义字段到grpc上下文元数据

http header 转发到 grpc上下文 grpc网关可以将请求体内容转发到grpc对应消息中。那如何获取http header头中的信息&#xff0c;本文将介绍如何将http header转发到grpc上下文并采用拦截器&#xff0c;获取http header中的内容。 有些http header中的内置字段是会转发的比如Au…...

CPU眼里的C/C++: 1.3 汇编级单步调试函数执行过程

1. 目的 2. 基于 GDB 的汇编级单步调试 原始代码 #include <stdio.h>long test() {long a 1;a 2;return a; }int main() {int ret test();printf("test return %d\n", ret);return 0; }关键 gdb 命令 si 指令执行汇编级的单步调试info registers 读取寄…...

数据结构时间复杂度(补充)和空间复杂度

Hello&#xff0c;今天事10月27日&#xff0c;距离刚开始写博客已经过去挺久了&#xff0c;我也不知道是什么让我坚持这么久&#xff0c;但是学校的课真的很多&#xff0c;很少有时间多出来再学习&#xff0c;有些科目马上要考试了&#xff0c;我还不知道我呢不能过哈哈哈&…...

Mac-postman存储文件目录

今天postman弹窗要求登录账号才可访问之前的API文档数据。 但是这postman的账号又是前同事的账号&#xff0c;我没有他的账号和密码啊。 登录了我自己的postman账号后&#xff0c;所有的api文档都不见了....我服了。 首先去屏幕左上角---> 前往 --->个人 然后键盘按显…...

JAVA面试题简单整理

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、重载和重写的区别一、&和&&的区别一、get和post请求的区别 delete、put一、cookie和session的区别一、Autowired和Resource区别一、”和equals…...

dd命令用法学习,是一个功能强大的工具

dd 命令是一个功能强大的工具&#xff0c;它有许多参数可以用来控制其行为。以下是 dd 命令中常用的一些参数&#xff1a; - ifinputfile&#xff1a;指定输入文件的路径。 - ofoutputfile&#xff1a;指定输出文件的路径。 - bssize&#xff1a;设置每个块的大小。可以使用不同…...

Games104现代游戏引擎笔记 网络游戏进阶架构

Character Movement Replication 角色位移同步 玩家2的视角看玩家1的移动是起伏一截一截&#xff0c;并且滞后的 interpolation&#xff1a;内插值&#xff0c;在两个旧的但已知的状态计算 extrapolation&#xff1a;外插值&#xff0c;本质是预测 内插值&#xff1a;但网络随着…...

Apollo 快速上手指南:打造自动驾驶解决方案

快速上手 概述云端体验登录云端仿真环境 打开DreamView播放离线数据包PNC Monitor 内置的数据监视器cyber_monitor 实时通道信息视图福利活动 主页传送门&#xff1a;&#x1f4c0; 传送 概述 Apollo 开放平台是一个开放的、完整的、安全的平台&#xff0c;将帮助汽车行业及自…...

C现代方法(第14章)笔记——预处理器

文章目录 第14章 预处理器14.1 预处理器的工作原理14.2 预处理指令14.3 宏定义14.3.1 简单的宏14.3.2 带参数的宏14.3.3 #运算符14.3.4 ##运算符14.3.5 宏的通用属性14.3.6 宏定义中的圆括号14.3.7 创建较长的宏14.3.8 预定义宏14.3.9 C99中新增的预定义宏14.3.10 空的宏参数(C…...

Kafka KRaft模式探索

1.概述 Kafka是一种高吞吐量的分布式发布订阅消息系统&#xff0c;它可以处理消费者在网站中的所有动作流数据。其核心组件包含Producer、Broker、Consumer&#xff0c;以及依赖的Zookeeper集群。其中Zookeeper集群是Kafka用来负责集群元数据的管理、控制器的选举等。 2.内容…...

LVS-keepalived实现高可用

概念&#xff1a; 本章核心&#xff1a; Keepalived为LVS应运而生的高可用服务。LVS的调度无法做高可用&#xff0c;预算keepalived这个软件&#xff0c;实现了调度器的高可用。 但是&#xff1a;Keeplived不是专门为LVS集群服务的&#xff0c;也可以做其他服务器的高可用 LVS…...

Linux内核驱动开发的需要掌握的知识点

Linux内核驱动开发是一项复杂而有挑战性的任务&#xff0c;需要掌握多方面的知识和技能。下面是一些需要掌握的关键知识点&#xff0c;这些知识将有助于你成功地开发Linux内核驱动程序。 1. Linux内核基础知识 首先&#xff0c;了解Linux内核的基础知识至关重要。这包括Linux…...

nginx 动静分离 防盗链

一、动静分离环境准备静态资源配置(10.36.192.169)安装nginx修改配置文件重启nginx 动态资源配置(192.168.20.135)yum安装php修改nginx配置文件重启nginx nginx代理机配置&#xff08;192.168.20.134&#xff09;修改nginx子自配置文件重启nginx 客户端访问 二、防盗链nginx防止…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

内存分配函数malloc kmalloc vmalloc

内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

基于大模型的 UI 自动化系统

基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

基于FPGA的PID算法学习———实现PID比例控制算法

基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容&#xff1a;参考网站&#xff1a; PID算法控制 PID即&#xff1a;Proportional&#xff08;比例&#xff09;、Integral&#xff08;积分&…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来

一、破局&#xff1a;PCB行业的时代之问 在数字经济蓬勃发展的浪潮中&#xff0c;PCB&#xff08;印制电路板&#xff09;作为 “电子产品之母”&#xff0c;其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透&#xff0c;PCB行业面临着前所未有的挑战与机遇。产品迭代…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时&#xff0c;需结合业务场景设计数据流转链路&#xff0c;重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点&#xff1a; 一、核心对接场景与目标 商品数据同步 场景&#xff1a;将1688商品信息…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

html-<abbr> 缩写或首字母缩略词

定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...

R语言速释制剂QBD解决方案之三

本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...

SpringAI实战:ChatModel智能对话全解

一、引言&#xff1a;Spring AI 与 Chat Model 的核心价值 &#x1f680; 在 Java 生态中集成大模型能力&#xff0c;Spring AI 提供了高效的解决方案 &#x1f916;。其中 Chat Model 作为核心交互组件&#xff0c;通过标准化接口简化了与大语言模型&#xff08;LLM&#xff0…...