如何选择消息队列
作为一个程序员,我们必须要认识到,软件工程中是不存在”银弹“的。<!--more-->
在消息队列的选型问题上,也是同样的道理。并不存在哪个消息队列就是最好的,能够解决所有的问题。常用的消息队列有好几个,每一种都有自己的优势和劣势,需要业务方根据自己的系统的情况,选择最适合的产品。
选择消息队列的基本标准
1、开源
首先,必须是开源的产品,因为一旦在开发过程中遇到一个系统 Bug,你至少有机会通过修改源代码来修复这个 Bug,而不是只能无期限地等待产品的开发者发布新版本解决该问题。
2、流行
其次,这个产品必须是近年来比较流行并且有一定社区活跃度的产品。流行意味着使用的人很多,只要你的场景不是很冷门,几乎你遇到的 Bug 都有前辈已经踩过坑了,都能找到类似的解决方案。
同时流行的产品与周边生态系统会有一个比较好的集成和兼容,大部分场景下不需要为自己的业务额外地去开发其他中间件。
3、可靠
需要保证消息传递的可靠,确保消息不会丢失。
4、支持 Cluster
支持集群,确保不会因为某个节点宕机导致服务不可用的情况,同时也需要保证消息不会丢失
5、性能
具备足够好的性能,能满足大多数场景的性能要求。
可供选择的消息队列产品
1、RabbitMQ
老牌消息队列 RabbitMQ,俗称兔子 MQ。它是用一种比较小众的语言:Erlang 编写的,最早为电信行业系统之间的可靠通信设计的,支持 AMQP 协议。
它的特点是:轻量级、迅捷,宣传口号是:”开箱即用的消息队列“,是一个相当轻量级的消息队列,非常容易部署和使用。因此 RabbitMQ 成为了 ”最流行的消息中间件之一“。
RabbitMQ 一个比较有特色的功能是支持非常灵活的路由配置,和其他消息队列不同的是,它在生产者和队列之间增加了一个类似交换机的 Exchange 模块。这个模块根据配置的路由规则将生产者发出的消息分发到不同的队列中。路由的规则也非常灵活,甚至可以自己来实现路由规则。
这里通过一个示例,详细解释一下 Exchange 模块的作用:
假设你有一个电商网站,你希望根据用户的购买地理位置将订单消息路由到不同的队列,以便分别处理。
创建 Exchange: 首先,你会创建一个 Exchange,可以命名为 "OrderExchange"。这是消息的中转站,它会接收生产者发送的订单消息,并负责将这些消息路由到一个或多个队列中。
创建队列: 然后,你会创建多个队列,每个队列代表一个不同的地理位置,比如 "USOrders"、"EUOrders" 和 "AsiaOrders"。
定义绑定规则: 接下来,你会定义绑定规则。这些规则告诉 Exchange 如何将消息路由到队列。例如,你可以定义规则,将订单消息中的地理位置信息与队列的名称进行匹配。如果订单来自美国,它将被路由到 "USOrders" 队列,如果来自欧洲,它将被路由到 "EUOrders" 队列。
生产者发送消息: 当用户在网站上下订单时,订单服务会将订单消息发送到 "OrderExchange"。这个消息会带有订单信息,包括地理位置。
Exchange 路由消息: "OrderExchange" 根据你定义的规则,将消息路由到相应的队列。如果订单来自美国,它将被发送到 "USOrders" 队列。
队列消费消息: 各个队列中的消费者(可能是不同的处理订单的系统)订阅相应队列并处理订单消息。"USOrders" 队列中的消费者处理来自美国的订单,"EUOrders" 队列中的消费者处理来自欧洲的订单,依此类推。
RabbitMQ 的客户端所支持的编程语言是消息队列中最多的,如果你的系统是使用某种冷门语言开发,那你可以尝试找到对应的 RabbitMQ 客户端,不出意外的话,应该是能找到的。
接下来说说 RabbitMQ 的几个问题:
-
消息堆积:RabbitMQ 的设计理念是管道,它对消息堆积的支持有限,大量消息堆积可能导致性能下降。因此,它不是最佳选择用于需要大规模消息堆积的应用。
-
性能较差:相对于其他消息队列系统,RabbitMQ 的性能较差。它通常能够处理每秒数万到十几万条消息,性能依赖于硬件配置,虽然大多数的应用场景也够用了,但如果对消息队列的性能要求非常高的话,就不要选择 RabbitMQ。
-
二次开发难: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 是最适合你的消息队列。
相关文章:
如何选择消息队列
作为一个程序员,我们必须要认识到,软件工程中是不存在”银弹“的。<!--more--> 在消息队列的选型问题上,也是同样的道理。并不存在哪个消息队列就是最好的,能够解决所有的问题。常用的消息队列有好几个,每一种都…...
读取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 为什么要有区?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 基本介绍 **反射:**在编译时静态类型语言中实现动态特性的一种机制。 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实战项目-学习任务系统-任务管理
接着上期代码框架,开发第3个功能,任务管理,再增加一个学习任务表,用来记录发布的学习任务的标题和内容,预计完成天数,奖励积分和任务状态等信息。 第一步:编写第三个功能-任务管理 1࿰…...
ubuntu18.04设置开机自动启动脚本(以自动启动odoo命令行为例讲解)
简介 ubuntu作为服务器使用时,常常需要在机器重启时能自动启动我们开发的服务。 Ubuntu 16.10开始不再使用initd管理系统,改用systemd,包括用systemctl命令来替换了service和chkconfig的功能。 systemd 默认读取 /etc/systemd/system 下的配…...
golang工程——grpc-gateway 转发http header中自定义字段到grpc上下文元数据
http header 转发到 grpc上下文 grpc网关可以将请求体内容转发到grpc对应消息中。那如何获取http header头中的信息,本文将介绍如何将http header转发到grpc上下文并采用拦截器,获取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,今天事10月27日,距离刚开始写博客已经过去挺久了,我也不知道是什么让我坚持这么久,但是学校的课真的很多,很少有时间多出来再学习,有些科目马上要考试了,我还不知道我呢不能过哈哈哈&…...

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

JAVA面试题简单整理
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、重载和重写的区别一、&和&&的区别一、get和post请求的区别 delete、put一、cookie和session的区别一、Autowired和Resource区别一、”和equals…...
dd命令用法学习,是一个功能强大的工具
dd 命令是一个功能强大的工具,它有许多参数可以用来控制其行为。以下是 dd 命令中常用的一些参数: - ifinputfile:指定输入文件的路径。 - ofoutputfile:指定输出文件的路径。 - bssize:设置每个块的大小。可以使用不同…...

Games104现代游戏引擎笔记 网络游戏进阶架构
Character Movement Replication 角色位移同步 玩家2的视角看玩家1的移动是起伏一截一截,并且滞后的 interpolation:内插值,在两个旧的但已知的状态计算 extrapolation:外插值,本质是预测 内插值:但网络随着…...

Apollo 快速上手指南:打造自动驾驶解决方案
快速上手 概述云端体验登录云端仿真环境 打开DreamView播放离线数据包PNC Monitor 内置的数据监视器cyber_monitor 实时通道信息视图福利活动 主页传送门:📀 传送 概述 Apollo 开放平台是一个开放的、完整的、安全的平台,将帮助汽车行业及自…...
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是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者在网站中的所有动作流数据。其核心组件包含Producer、Broker、Consumer,以及依赖的Zookeeper集群。其中Zookeeper集群是Kafka用来负责集群元数据的管理、控制器的选举等。 2.内容…...

LVS-keepalived实现高可用
概念: 本章核心: Keepalived为LVS应运而生的高可用服务。LVS的调度无法做高可用,预算keepalived这个软件,实现了调度器的高可用。 但是:Keeplived不是专门为LVS集群服务的,也可以做其他服务器的高可用 LVS…...
Linux内核驱动开发的需要掌握的知识点
Linux内核驱动开发是一项复杂而有挑战性的任务,需要掌握多方面的知识和技能。下面是一些需要掌握的关键知识点,这些知识将有助于你成功地开发Linux内核驱动程序。 1. Linux内核基础知识 首先,了解Linux内核的基础知识至关重要。这包括Linux…...

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

手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...

.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...

STM32F4基本定时器使用和原理详解
STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...

Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...