Kafka or RabbitMQ:消息中间件选型深入分析

2023-11-01

一、前言

消息队列中间件(简称消息中间件)是指利用高效可靠的消息传递机制进行与平台无关的数据交流,并基于数据通信来进行分布式系统的集成。通过提供消息传递和消息排队模型,它可以在分布式环境下提供应用解耦、弹性伸缩、冗余存储、流量削峰、异步通信、数据同步等等功能,其作为分布式系统架构中的一个重要组件,有着举足轻重的地位。

目前开源的消息中间件可谓是琳琅满目,能让大家耳熟能详的就有很多,比如ActiveMQ、RabbitMQ、Kafka、RocketMQ、ZeroMQ等。不管选择其中的哪一款,都会有用的不趁手的地方,毕竟不是为你量身定制的。有些大厂在长期的使用过程中积累了一定的经验,其消息队列的使用场景也相对稳定固化,或者目前市面上的消息中间件无法满足自身需求,并且也具备足够的精力和人力而选择自研来为自己量身打造一款消息中间件。但是绝大多数公司还是不会选择重复造轮子,那么选择一款合适自己的消息中间件显得尤为重要。就算是前者,那么在自研出稳定且可靠的相关产品之前还是会经历这样一个选型过程。

在整体架构中引入消息中间件,势必要考虑很多因素,比如成本及收益问题,怎么样才能达到最优的性价比?虽然消息中间件种类繁多,但是各自都有各自的侧重点,选择合适自己、扬长避短无疑是最好的方式。如果你对此感到无所适从,本文或许可以参考一二。

二、各类消息队列简述

ActiveMQ是Apache出品的、采用Java语言编写的完全基于JMS1.1规范的面向消息的中间件,为应用程序提供高效的、可扩展的、稳定的和安全的企业级消息通信。不过由于历史原因包袱太重,目前市场份额没有后面三种消息中间件多,其最新架构被命名为Apollo,号称下一代ActiveMQ,有兴趣的同学可行了解。

RabbitMQ是采用Erlang语言实现的AMQP协议的消息中间件,最初起源于金融系统,用于在分布式系统中存储转发消息。RabbitMQ发展到今天,被越来越多的人认可,这和它在可靠性、可用性、扩展性、功能丰富等方面的卓越表现是分不开的。

Kafka起初是由LinkedIn公司采用Scala语言开发的一个分布式、多分区、多副本且基于zookeeper协调的分布式消息系统,现已捐献给Apache基金会。它是一种高吞吐量的分布式发布订阅消息系统,以可水平扩展和高吞吐率而被广泛使用。目前越来越多的开源分布式处理系统如Cloudera、Apache Storm、Spark、Flink等都支持与Kafka集成。

RocketMQ是阿里开源的消息中间件,目前已经捐献个Apache基金会,它是由Java语言开发的,具备高吞吐量、高可用性、适合大规模分布式系统应用等特点,经历过双11的洗礼,实力不容小觑。

ZeroMQ号称史上最快的消息队列,基于C语言开发。ZeroMQ是一个消息处理队列库,可在多线程、多内核和主机之间弹性伸缩,虽然大多数时候我们习惯将其归入消息队列家族之中,但是其和前面的几款有着本质的区别,ZeroMQ本身就不是一个消息队列服务器,更像是一组底层网络通讯库,对原有的Socket API上加上一层封装而已。

目前市面上的消息中间件还有很多,比如腾讯系的PhxQueue、CMQ、CKafka,又比如基于Go语言的NSQ,有时人们也把类似Redis的产品也看做消息中间件的一种,当然它们都很优秀,但是本文篇幅限制无法穷极所有,下面会针对性的挑选RabbitMQ和Kafka两款典型的消息中间件来做分析,力求站在一个公平公正的立场来阐述消息中间件选型中的各个要点。

三、选型要点概述

衡量一款消息中间件是否符合需求需要从多个维度进行考察,首要的就是功能维度,这个直接决定了你能否最大程度上的实现开箱即用,进而缩短项目周期、降低成本等。如果一款消息中间件的功能达不到想要的功能,那么就需要进行二次开发,这样会增加项目的技术难度、复杂度以及增大项目周期等。

1. 功能维度

功能维度又可以划分个多个子维度,大致可以分为以下这些:

优先级队列
优先级队列不同于先进先出队列,优先级高的消息具备优先被消费的特权,这样可以为下游提供不同消息级别的保证。不过这个优先级也是需要有一个前提的:如果消费者的消费速度大于生产者的速度,并且消息中间件服务器(一般简单的称之为Broker)中没有消息堆积,那么对于发送的消息设置优先级也就没有什么实质性的意义了,因为生产者刚发送完一条消息就被消费者消费了,那么就相当于Broker中至多只有一条消息,对于单条消息来说优先级是没有什么意义的。

延迟队列
当你在网上购物的时候是否会遇到这样的提示:“三十分钟之内未付款,订单自动取消”?这个是延迟队列的一种典型应用场景。延迟队列存储的是对应的延迟消息,所谓“延迟消息”是指当消息被发送以后,并不想让消费者立刻拿到消息,而是等待特定时间后,消费者才能拿到这个消息进行消费。延迟队列一般分为两种:基于消息的延迟和基于队列的延迟。基于消息的延迟是指为每条消息设置不同的延迟时间,那么每当队列中有新消息进入的时候就会重新根据延迟时间排序,当然这也会对性能造成极大的影响。实际应用中大多采用基于队列的延迟,设置不同延迟级别的队列,比如5s、10s、30s、1min、5mins、10mins等,每个队列中消息的延迟时间都是相同的,这样免去了延迟排序所要承受的性能之苦,通过一定的扫描策略(比如定时)即可投递超时的消息。

死信队列
由于某些原因消息无法被正确的投递,为了确保消息不会被无故的丢弃,一般将其置于一个特殊角色的队列,这个队列一般称之为死信队列。与此对应的还有一个“回退队列”的概念,试想如果消费者在消费时发生了异常,那么就不会对这一次消费进行确认(Ack),进而发生回滚消息的操作之后消息始终会放在队列的顶部,然后不断被处理和回滚,导致队列陷入死循环。为了解决这个问题,可

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Kafka or RabbitMQ:消息中间件选型深入分析 的相关文章

  • 从txt文件中读取数据而不下载它?

    我想从提供的文本文件中解析信息 有没有一种方法可以在应用程序中执行此操作 而无需先下载文件 以某种方式传输文本内容 打开到 URL 的 Http 连接 使用内置 HttpURLConnection 或使用 commons httpclien
  • 将 WAR 部署到 Tomcat(Spring Boot + Angular)

    我正在尝试使用以下命令部署 Spring Boot 应用程序WAR包装至Tomcat 10 应用程序已成功部署 但是 当我尝试访问端点时 它会导致404 未找到 战争文件 应用程序 war http localhost 8080 appli
  • Java 错误和警告列表

    在哪里 如何获得所有 java 和 javac 的错误和警告消息的列表 This http mindprod com jgloss compileerrormessages html我认为页面是您所需要的
  • java中高效的输入流到字符串方法

    因此 我在 Java 中的 诚然非常简单 应用程序上运行探查器 令我惊讶的是 仅次于需要在时间上发出 HTTP 请求的方法的是我的方法 inputStreamToString方法 目前它的定义如下 public static String
  • 使用 Spring MVC 在 jar 文件中显示 jsp 页面

    我正在使用 Spring MVC 3 2 2 在 java 中开发一个 Web 应用程序 我在从 jar 文件中加载 jsp 页面时遇到问题 Spring MVC Web应用程序具有以下结构 META INF WEB INF spring
  • 如何杀死 Java Future?

    我正在开发的服务使用 Future 来并行运行多个任务 每个任务最多可能需要一分钟才能完成 然而 外部库似乎有问题 因为在某些情况下 2 的时间 它不会返回 在这些情况下 我想给出 2 分钟的等待时间 如果还没有返回 我想杀死 future
  • 当前平台不支持桌面 API

    我遇到过这个错误 java lang UnsupportedOperationException 当前平台不支持桌面 API 我将从我的 java 应用程序中打开一个文件 我用这个方法 Desktop getDesktop open new
  • 使用 https 的 Web 服务身份验证给出错误

    我编写了一个简单的 Web 服务 并使用摘要和 HTTPS 身份验证来保护它 我已经使用 Java 中的 keytool 生成了我的证书 当我通过创建 war 文件在 Tomcat 中部署 Web 服务时 axis 的欢迎页面正确显示 但是
  • Google 表格使用 API 密钥而不是 client_secret.json

    In the QuickStart java示例Java 快速入门 https developers google com sheets api quickstart java他们使用OAuth client ID识别该应用程序 这会弹出一
  • java:为什么主线程等待子线程完成

    我有一个简单的java程序 主线程 main 创建并启动另一个线程t class T extends Thread Override public void run while true System out println Inside
  • 是否可以创建 Java RAM 磁盘以与 java.io.* API 一起使用?

    我正在使用一个第三方库 它基本上创建一个输出目录 其中包含不同类型的文件和子目录 我希望能够编写单元测试来确认输出正确 我希望能够将库与 RAM 磁盘一起使用 这样库所做的任何事情都不会以任何方式接触实际的磁盘板 这个想法是让测试运行和清理
  • 我的 Kafka 流应用程序刚刚退出,代码为 0,什么也不做

    为了尝试 Kafka 流 我这样做了 public static void main String args final StreamsBuilder builder new StreamsBuilder final Properties
  • java彩色滚动条搜索结果

    我将如何在 Java 中自定义滚动条 以便我可以进行像 chrome 一样的搜索 也就是说在结果所在的位置放置彩色条纹 我不想要一个库 因为我更喜欢自己编写代码 另外 我不想失去我拥有的 L F 欢迎举例 实际上 它将查看一个大的文本文件或
  • 为休息服务实施 JUnit 测试

    我必须为我的休息服务实现一些 JUnit 测试 例如 这是我的休息服务之一 Path dni fe public class HelloWorld POST Path home Consumes MediaType APPLICATION
  • Spring Security 角色层次结构不适用于 Thymeleaf sec:authorize

    我正在使用 Spring Security 3 2 5 RELEASE 和 ThymeLeaf 2 1 4 RELEASE 我已经在安全上下文中定义了角色层次结构 在我的视图层中我正在使用sec authorize属性来定义菜单项 我希望看
  • 获取接收者的设备令牌以在 Firebase 中发送通知

    所以我正在学习如何使用 firebase 发送设备到设备的通知 我看到了这个answer https stackoverflow com a 42548586 5237289发送通知 看起来很简单 现在 我知道要获取发件人的令牌 它应该如下
  • 如何在 JASPIC 中保存经过身份验证的用户?

    我开发了一个安全认证模块 SAM 并实现了validateRequest方法 我还有一个简单的 Web 应用程序配置为使用此 SAM In my validateRequest方法 我检查 clientSubject 并设置一个Caller
  • 如何在不使用 -cp 开关的情况下在 Groovy 中自动加载数据库 jar?

    我想简化调用 Oracle 数据库的 Groovy 脚本的执行 如何将 ojdbc jar 添加到默认类路径以便我可以运行 groovy RunScript groovy 代替 groovy cp ojdbc5 jar RunScript
  • 用于生成 ISO 文件的 Maven 插件

    有没有可以生成ISO镜像的maven插件 我需要获取一些模块的输出 主要是包含 jar 的 zip 文件 并将它们组合成一个 ISO 映像 Thanks 现在有一个 ISO9660 maven 插件可以完成这项工作 https github
  • JPA ManyToMany 产生的空联接表

    我有一个应用程序 其中我尝试使用 Hibernate 作为 JPA 提供程序来实现两个实体之间的多对多关系 我正在尝试的例子是一个单向的 其中一个相机可以有多个镜头 而镜头可以安装到多个相机中 以下是我的实体类 只需粘贴其中的相关部分 Ca

随机推荐

  • BUCK-BOOST反激变压器设计

    Buck Boost电路中 最低电压为其最恶劣情况 以下图为例 注 1 Np为初级绕组匝数 Ns为次级绕组匝数 2 Vmos为MOS最大耐压值 1为整流管压降 Vl为漏 Vl 100V Vmos选取遵循的原则 开关关断瞬间 加在MOS上电压
  • echarts地图添加图片

    需求 地图的各区域添加图标 解决方案 通过散点图与地图的结合 为地图添加上图片 option geo map xx省 要显示地图的地区名 roam false zlevel 1 zoom 1 2 label normal show fals
  • ubuntu安装python库出现错误errno -3_python – “gaierror:[Errno -3]名称解析暂时失败”是什么意思...

    我正在尝试运行一个以错误结束的Flask应用程序 如果我追溯正在发生的事情 我可以使用以下iPython命令重现该问题 In 14 import socket In 15 s socket socket In 16 s connect ra
  • 格密码与最短向量下界

    目录 前言 一 格的最短向量 二 最短向量长度下界 三 格点离散 四 格的连续最小值 总结 前言 最短的非零向量长度是格密码中的一个基本量 定义前提为非零向量 因为格中总包含零向量 其模长为0 通常使用代量表示 用格的观点来理解 以r为半径
  • 数字逻辑·时序线路分析【触发器和时序线路分析方法】

    课程目标 掌握触发器的特征表达式 掌握触发器的激励表 掌握触发器的状态表 掌握时序线路分析方法 课程内容 D触发器 逻辑符号可以不画RD SD CP 上方 特征表达式 左下 激励表 右下 状态图 状态图 大圈里放置Q 为1或者0 线 输入激
  • 蓝桥杯每日一题2023.9.12

    蓝桥杯2022年第十三届决赛真题 卡牌 C语言网 dotcpp com 题目描述 这天 小明在整理他的卡牌 他一共有 n 种卡牌 第 i 种卡牌上印有正整数数 i i 1 n 且第 i 种卡牌 现有 ai 张 而如果有 n 张卡牌 其中每种
  • 微前端实战看这篇就够了 - Vue项目篇

    wl micro frontends wl qiankun 本项目采用 vue qiankun 实践微前端落地 同时qiankun是一个开放式微前端架构 支持当前三大前端框架甚至jq等其他项目无缝接入 此项目为了尽可能的简单易上手 以及方便
  • 助力响应式设计:Adobe发布最新HTML5工具包

    原文地址 http www csdn net article 2013 02 16 2814145 adobe responsive web design 助力响应式设计 Adobe发布最新HTML5工具包 发表于 19小时前 902次阅读
  • 物理网络设计——结构化综合布线系统(6个子系统)学习心得

    附 网络系统设计过程 逻辑网络设计 三层网络结构 核心汇聚接入 学习心得 结构化布线系统分为6个子系统 工作区子系统 Work Location 工作区子系统是指从终端设备到信息插座的整个区域 一个独立的需要安装终端设备的区域划分为一个工作
  • QT 使用第三方库QtXlsx操作Excel表

    一直以来 都想学习一下C C 如何操作excel表 在网上调研了一下 觉得使用C C 去操作很麻烦 遂转向QT这边 QT有一个自带的类QAxObject 可以使用他去操作 但随着了解的深入 觉得他并不是很好 有很多其他缺陷 例如必须电脑安装
  • 初步安装dns

    dns安装详解 dns的实现工具 bind 查找系统中的bind的rpm包 DNS服务器的监听端口 查看监听端口相关信息 dns的实现工具 bind 查找系统中的bind的rpm包 yum list grep bind bind x86 6
  • Latex命令速查

    TeX各版本概述及基本约定 特殊字符 tex提供300多条基本排版命令 由D E Knuth1978年开发 plain tex 在tex基础上新定义600多条复合命令 AMS TEX 美国数学会开发 amsmath宏包 排版的数学公式 LA
  • [文本挖掘和知识发现] 01.红楼梦主题演化分析——文献可视化分析软件CiteSpace入门

    八月太忙 还是写一篇吧 本文是作者2023年8月底新开的专栏 文本挖掘和知识发现 主要结合Python 大数据分析和人工智能分享文本挖掘 知识图谱 知识发现 图书情报等内容 此外 这些内容也是作者 文本挖掘和知识发现 Python版 书籍的
  • 一行代码解决各种IE兼容问题,IE6,IE7,IE8,IE9,IE10

    x ua compatible 用来指定IE浏览器解析编译页面的model x ua compatible 头标签大小写不敏感 必须用在 head 中 必须在除 title 外的其他 meta 之前使用 1 使用一行代码来指定浏览器使用特定
  • java如何设计模块_java设计模式--模板方法模式

    模板方法模式 模拟场景 登录控制 现在有一个基于Web的企业级应用系统 需要实现两种登录控制 管理员登录和客户登录 直接使用不同的登录页面来区分它们 下面是基本的功能需求描述 普通客户登录前台的登录控制功能 1 前台界面 用户能输入用户名和
  • dbeaver编辑表结构和调整字段的顺序

    DBeaver怎么才能编辑表 知乎 zhihu com 同样一个账号 navicat可以设计表 编辑表结构 而dbeaver不可以 需要在dbeaver数据库连接中修改配置才行 但不知道为什么hive还是不行 而且dbeaver不知道怎么调
  • csdn大师孟岩老师为本书作序——“未来属于动态语言”

    如果你想掌握Ruby 这本书是最好的起点 如果你想运用Ruby 这本书也是案头必备 所以 如果你已经决定要走入Ruby的世界 那么这本书是必经之路 而本不需要一篇 推荐序 问题在于 我们为什么还要学习一种新的语言 特别是当Ruby整体上仍然
  • iOS编程中——id数据类型

    iOS编程中经常见到的 id 数据类型 id类型声明没有 号 是动态数据类型 可以指向任何类的对象 而不关心具体类型 编译阶段不做类型检查 运行阶段检查具体类型 优点 灵活 可以指向任何数据类型 编译阶段不指向任何类型 缺点 可读性不高 编
  • AR(制作流程)

    http blog csdn net yy763496668 article details 77806420 杨勇博客之家unity 80
  • Kafka or RabbitMQ:消息中间件选型深入分析

    一 前言 消息队列中间件 简称消息中间件 是指利用高效可靠的消息传递机制进行与平台无关的数据交流 并基于数据通信来进行分布式系统的集成 通过提供消息传递和消息排队模型 它可以在分布式环境下提供应用解耦 弹性伸缩 冗余存储 流量削峰 异步通信