当前位置: 首页 > 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防止…...

新装Ubuntu 22.04.4 LTS后,我做的第一件事:开启root和SSH远程管理

新装Ubuntu 22.04.4 LTS后必做的安全加固与远程管理配置拿到一台全新安装的Ubuntu 22.04.4 LTS服务器时&#xff0c;很多开发者会迫不及待地开始部署应用。但根据我管理上百台服务器的经验&#xff0c;初始配置的质量直接决定了后续运维的难易程度。本文将分享我每次部署新系统…...

机器学习结合对称性描述符高效预测硅带隙温度依赖性

1. 项目概述&#xff1a;当机器学习遇见声子物理在材料计算领域&#xff0c;我们常常面临一个“鱼与熊掌”的困境&#xff1a;一方面&#xff0c;基于第一性原理的密度泛函理论&#xff08;DFT&#xff09;计算能给出相当可靠的基态电子结构&#xff0c;比如硅的晶格常数、能带…...

阴阳师自动化脚本终极指南:一键解放双手的智能游戏助手

阴阳师自动化脚本终极指南&#xff1a;一键解放双手的智能游戏助手 【免费下载链接】OnmyojiAutoScript Onmyoji Auto Script | 阴阳师脚本 项目地址: https://gitcode.com/gh_mirrors/on/OnmyojiAutoScript 还在为阴阳师中重复繁琐的日常任务而烦恼吗&#xff1f;每天需…...

基于Hugging Face与Gradio的智能问答系统构建实战

1. 项目概述&#xff1a;从零构建一个可交互的智能问答系统 如果你对自然语言处理&#xff08;NLP&#xff09;感兴趣&#xff0c;并且一直想亲手搭建一个能“读懂”文章并回答问题的智能系统&#xff0c;那么这篇文章就是为你准备的。过去几年&#xff0c;基于Transformer架构…...

Unity深度调试框架UniHacker:突破IL2CPP可观测性断层

1. 这不是“破解工具”&#xff0c;而是一套面向Unity开发者的深度调试与逆向协作框架“UniHacker”这个名字在社区里常被误读为某种一键解锁Asset Store资源或绕过License校验的黑盒程序——这恰恰是我们今天要彻底厘清的第一件事。它既不触碰Unity官方EULA中关于授权使用的核…...

解决Keil C51项目中PL/M-51编译警告导致构建失败问题

1. 问题现象与背景分析当使用Keil Vision IDE进行C51项目开发时&#xff0c;许多工程师都遇到过这样一个棘手情况&#xff1a;在点击"Build target"或"Rebuild all target files"后&#xff0c;编译过程会在某个PL/M-51源文件处突然停止。输出窗口显示该文…...

LPC2000复位行为解析与调试技巧

1. 理解LPC2000设备的复位行为问题 在嵌入式开发中&#xff0c;复位操作是最基础也是最重要的调试手段之一。当我们使用Keil MDK配合ULINK调试器对Philips&#xff08;现NXP&#xff09;LPC2000系列ARM微控制器进行调试时&#xff0c;可能会遇到一个看似简单却令人困惑的现象&a…...

RFECV特征选择在勒索软件分类中的实战:API与网络流量特征对比

1. 项目概述&#xff1a;当勒索软件分类遇上RFECV特征选择在网络安全攻防的战场上&#xff0c;勒索软件无疑是最具破坏性和经济威胁的对手之一。它不再仅仅是技术宅的恶作剧&#xff0c;而是演变成了组织化、产业化的犯罪工具&#xff0c;其变种迭代速度之快&#xff0c;让传统…...

保姆级教程:在Ubuntu 20.04上从源码编译安装SUMO 1.19.0(含环境变量配置避坑指南)

从源码构建SUMO 1.19.0&#xff1a;Ubuntu 20.04深度编译指南与排错实战在交通仿真领域&#xff0c;SUMO&#xff08;Simulation of Urban MObility&#xff09;作为开源微观仿真工具链的核心&#xff0c;其源码编译安装能为研究者带来三大不可替代的优势&#xff1a;定制化模块…...

CVE、CNVD、CNNVD、NVD四大漏洞编号体系深度解析

1. 这些字母组合不是密码&#xff0c;而是漏洞世界的“身份证号” 刚入行做安全运维那会儿&#xff0c;我在日报里看到一条告警&#xff1a;“检测到 CVE-2021-44228 漏洞利用尝试”&#xff0c;顺手抄下来准备查资料&#xff0c;结果一搜发现——同一款 Log4j 组件&#xff0c…...