消息代理与事件代理:何时使用它们

选择正确的工具来满足异步处理需求的技术指南

作为后端开发人员,有一天你需要回答这个问题:

我需要构建一个使用分布式队列的异步应用程序,我应该使用哪个代理? 作为工程师,我们的本能是列出我们了解或希望熟悉的工具(如果它是一种新的和已知的技术),然后开始使用它。不幸的是,在那个时刻,我们错过了第一个最重要的问题,这个问题需要在所有其他问题之前得到答案:我们的现有和有时未来的用例/需求是什么,什么工具能最好地解决它们? 这是我们在设计一个重要功能时的起点,当时工程师的本能占了上风。我们的第一个问题不是最重要的问题,从那时开始,我们选择正确工具的过程变得不太有效。我们的团队开了几次会,讨论了我们对分布式队列的需求,不同技术的不同限制和特性(来自不同的范例)让关注点远离了我们最重要的需求,也远离了决策和共识的实现。 在那个时候,我们决定回到基本问题,问:我们试图解决的用例是什么,没有让步的余地在哪些领域?一如既往,让我们从需求开始。

步骤1:明确您要解决的问题以及技术/工具体系结构如何与您的目标和考虑保持一致

在选择消息代理或事件代理时,有很多事情要考虑:高可用性、容错性、多租户、多云区域支持、能够支持高吞吐量和低延迟等等,列举不胜枚举。

大多数情况下,当阅读有关事件代理或消息代理的主要特性时,我们都是以大多数公司或产品从未完全使用或需要的最复杂用例为例的。

作为工程师,生活中有一句常用的话语:

“上帝在细节中,但魔鬼隐藏在细节之间。”

在选择事件代理与消息代理两个范式之间,"魔鬼"隐藏在更多的低层技术考虑因素中,比如:

消息的消耗或生成确认方法、去重、消息的优先级、消费者线程模型、消息的消耗方法、消息的分发/扩散支持、毒药药处理等等。

概念之间的不同:橙子与苹果

步骤2:了解两种范式之间的差异

事件代理

存储一系列事件。通常,事件会按到达事件代理的顺序附加到日志(队列或主题)上。主题或队列中的事件是不可变的,其顺序不能更改。

当事件发布到队列或主题时,代理识别主题或队列的订阅者,并使事件可供多种类型的订阅者使用。

生产者和消费者不需要彼此熟悉。

事件潜在地可以存储数天或数周,因为它们一旦被成功消耗,就不会从队列/主题中删除。

消息代理

用于服务或组件之间的通信。它通过异步方式在应用程序之间传输由生产者接收的消息。

它通常支持队列的概念,其中消息通常存储一段时间。队列中消息的目的是在消费者可用于处理消息并在成功消耗后删除消息。

不能保证队列中消息处理的顺序,并且可以更改。

消息代理与事件代理

通常,在处理短命令或面向任务的处理时,我们会倾向于使用消息代理

例如,假设你在一家电子商务公司工作,想要将新产品添加到公司的网站。这可能意味着多个服务需要知道并以异步方式处理此请求。

f358673a5873b0c064e2266c6c91cd80.png
1*5m9zqTMXWlBh8U2UCPAVCg.png

上图显示了RabbitMQ扇出消息分发的使用,其中每个服务都有自己的队列连接到扇出交换机。

产品服务发送包含新产品信息的消息到交换机,交换机将消息发送到所有连接的队列。

在从队列成功消耗消息后,它将被删除,因为涉及的服务不需要保留或重新处理消息。

在处理当前或历史事件时,通常涉及大量数据,需要以单个或批量方式处理这些数据,我们会倾向于使用事件代理

例如,假设你在一个娱乐评级网站工作,你想为用户添加一个新功能,用来显示电影的编剧和导演。这些信息虽然历史存储,但不对负责提供这些数据的服务可用。

417655d56b2e3954057d3c8c18b6182e.png
1*cV63VZXluLMBssYkUJptXQ.png

上图显示了使用Kafka作为事件代理,它能够从数据仓库中提取数亿部电影,以为每个

服务存储的电影信息附加所需的信息。

Kafka可以在相对短的时间内接受大量的数据,而消费者可以有一个独立的消费者组来单独处理电影主题流。

需要注意的重要方面

正如我之前提到的,选择合适的范式时有很多事情要考虑。

我想讨论一些关键的差异,这些差异通常可能成就或破坏您对技术的决策。

在这一部分,我将比较迄今为止最流行的两种技术:Kafka(事件代理)和RabbitMQ(消息代理),它们分别代表了这两个范式,我对它们都有实际经验。

我强烈鼓励您在技术选择过程中考虑以下几点。

轮询与推送

Kafka消费者的工作方式是通过轮询一个主题中按顺序分区划分的消息的块,每个消费者负责从一个或多个分区中消费消息,其中分区用作消费者的并行机制(隐式线程模型)。

这意味着通常负责管理主题的生产者会隐式知道可以订阅主题的消费者实例的最大数量。

消费者负责处理消息处理的成功和失败情况。由于消息是从分区中批量轮询的,所以消息处理顺序在分区级别是有保证的。

RabbitMQ消费者从队列中接收消息的方式是通过代理将消息推送给它们。

每条消息都以一种独立的方式进行处理,消费者可以采用显式线程模型,而不需要生产者知道消费者实例的数量。

成功的消息处理是消费者的责任,而处理失败主要由消息代理完成。

消息分发由代理进行管理。

如延迟消息和消息优先级等功能是开箱即用的,因为消息处理顺序在队列中通常是不保证的。

错误处理

Kafka处理消息处理错误的方式是将处理错误的责任委托给消费者。

如果某条消息被处理了几次但失败(毒药药),消费者应用程序需要跟踪处理尝试的数量,然后生成一条消息到一个单独的DLQ(死信队列)主题,以便以后检查/重新运行。

就错误处理而言,消费者是承担所有责任的一方。

这意味着如果您希望具有重试/DLQ功能,您需要提供重试机制,并在发送消息到DLQ主题时充当生产者,这在某些极端情况下可能导致消息丢失。

RabbitMQ处理消息处理错误的方式是跟踪处理消息失败。一旦一条消息被视为毒药药,它将被路由到一个DLQ交换机。

这允许重新排队消息或将其路由到专用DLQ以进行检查。

通过这种方式,RabbitMQ提供了保证未成功处理的消息不会丢失。

消费者确认和传递保证

Kafka处理消费者确认的方式是由消费者提交从主题分区中轮询的消息的偏移量。

开箱即用,Kafka客户端会自动提交偏移量,无论消息是否成功处理,这可能导致消息丢失,如下图所示。

bc0b611ec2df084393c36cb54f4f8fcd.png
1*m_KvTEvbCcoFZp3L4HWLSw.png

通过消费者代码负责手动提交获取的消息的偏移量,包括处理消息消费失败的情况,可以更改此行为。

RabbitMQ处理消费者确认的方式是消费者以每条消息的方式进行“确认”或“否认”,允许由消息代理处理重试策略/DLQ,如果需要,可以由消息代理进行管理。

开箱即用,RabbitMQ客户端自动进行确认,无论消息是否成功处理,可以通过消费者端的配置手动控制确认,允许消息在失败/超时时重新推送给消费者。

RabbitMQ和Kafka在大多数情况下都提供至少一次消息/事件处理的保证,这意味着消费者应该是幂等的,以处理同一消息/事件的多次处理。

我们的流程

步骤 3:根据您的用例选择技术,而不是反过来

对我们来说,最重要的部分是编制我们解决方案的技术标准清单,并为我们作为团队和产品不能缺少的要求分配“不可接受”。

回到基础精神,我使用了一个普通的表格来编制和比较不同的标准,并提到了一些需要注意的地方。记住,“细节藏在细节之中”。

a589ed9c90a1816ffbf9adbd758461be.png
1*WWj9uxOKprQ6BlmBGmbkMg.png

这真的帮助我们组织并集中精力关注对我们至关重要的内容以及我们无法缺少的内容。

例如,我们的“不可接受”要求之一是,如果在处理过程中发生错误,我们不能承受丢失消息。

正如您可能从上面的部分中记得的,当使用需要DLQ的Kafka时,消费者也是DLQ的生产者。这意味着在消费者发生故障的某些情况下,消息将不会被发送到DLQ主题,可能导致消息丢失。

在这一点上,正如您可能已经猜到的那样,我们决定选择消息代理。

我们的功能包括面向命令/任务的处理用例,消息代理满足了我们的产品/数据容量要求,也满足了我们团队的需求。

最后的思考

消息和事件流生态系统包括许多解决方案,每个解决方案都有许多不同的方面需要考虑和熟悉。

重要的是我们要睁大眼睛进入每个生态系统,并对这些不同的范式有清晰的理解。它们将对我们工程师的日常生活(有时是夜间生活)产生重大影响。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/119919.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

汇编-变量

.386 .model flat,stdcall option casemap:none.data sum DWORD 0 ;创建一个全局变量,取名sum,初始化0 sum1 DWORD ? ;创建一个全局变量sum1,无初始化 ;问号(?)初始化值使得变量未被初始化,这意味着在运行时才会为该变量分配一个值 ;变量名…

【Git】Git 学习笔记_操作远程仓库

1. SSH 配置和克隆仓库 ssh-keygen -t rsa -C "xxxqq.com"回车后出现以下内容,直接回车: Generating public/private rsa key pair. Enter file in which to save the key (/Users/your_user_directory/.ssh/id_rsa): (按回车键) Enter pass…

指针进阶(3)

文章目录 9. 指针和数组笔试题解析10. 指针笔试题 9. 指针和数组笔试题解析 在做题之前,我们再次明确一下数组名的理解: 数组名是数组首元素的地址,但是有2个例外: sizeof(数组名),这里的数组名表示整个数组&#xff…

[黑马程序员Pandas教程]——Pandas数据结构

目录: 学习目标认识Pandas中的数据结构和数据类型Series对象通过numpy.ndarray数组来创建通过list列表来创建使用字典或元组创建s对象在notebook中不写printSeries对象常用API布尔值列表获取Series对象中部分数据Series对象的运算DataFrame对象创建df对象DataFrame…

pytorch之relu激活函数

目录 1、relu 2、relu6 3、leaky_relu 4、ELU 5、SELU 6、PReLU 1、relu ReLU(Rectified Linear Unit)是一种常用的神经网络激活函数,它在PyTorch中被广泛使用。ReLU函数接受一个输入值,如果该值大于零,则返回该…

python的format函数的用法及实例

目录 1.format函数的语法及用法 (1)语法:{}.format() (2)用法:用于格式化字符串。可以接受无限个参数,可以指定顺序。返回结果为字符串。 2.实例 (1)不设置位置&…

浮点数存储

//浮点数存储 int main() {int n 9;//00000000 00000000 00000000 00001001//0 00000000 00000000000000000001001//S E(8bit) M(23bit)//E-126//M0.000000000000000000001001// 0.000000000000000000001001 *2^-126float* pFloat (float*)&n;printf("n的值…

挖掘非结构化数据潜能——向量数据库的探索之路

“ 摸着石头过河,一直向前,不断尝试 ” 整理 | 小白 出品|极新 IDC 预测,到 2025 年,中国的数据量将增长到 48.6ZB,80% 是非结构化数据,并且将成为全球最大的数据圈。在我们的日常生活中&…

python使用pysqlcipher3对sqlite数据库进行加密

python对很多项目都需要对sqlite数据库的数据进行加密,最流行的加密方式是使用pysqlcipher3,当前使用的python版本为3.7,本博文是直接使用pysqlcipher3在项目上的应用,使用的是已编译好的pysqlcipher3包,如果你需要pys…

Jmeter_逻辑控制器

逻辑控制器 控制取样器执行顺序的组件实现(分支 循环) 分类 1、如果(if) 控制器 分支实现 2、forEach控制器 循环往复实现 3、循环控制器 循环往复实现 如果(if) 控制器 需求1:测试计划中定义一个 http 请求访问百度,但是该请求不是无条件执行的,…

【uniapp小程序下载】调用uni.uploadfile方法在调试工具里是没有问题的,但是线上版本和体验版就调用不成功,真机调试也没问题

把你的下载地址前缀添加到合法域名就解决了 在调试工具里成功了是因为勾选了下面这项 下面是我的下载并打开函数 methods: {// 下载downloadFileFn(data) {if (this.detailsObj.currentUserBuy) {uni.downloadFile({// data是路径url: https:// data,success(res) {//保存到本…

linux地址空间

地址空间 内存空间示意图虚拟地址空间虚拟地址进程地址空间生命周期图解为什么要有地址空间呢? 小结 内存空间示意图 进程是在内存中运行的,为了便于管理,不同的数据会存储在不同的区域,因此内存就被分为几部分,如下图…

新的iLeakage攻击从Apple Safari窃取电子邮件和密码

图片 导语:学术研究人员开发出一种新的推测性侧信道攻击,名为iLeakage,可在所有最新的Apple设备上运行,并从Safari浏览器中提取敏感信息。 攻击概述 iLeakage是一种新型的推测性执行攻击,针对的是Apple Silicon CPU和…

独立键盘接口设计(Keil+Proteus)

前言 软件的操作参考这篇博客。 LED数码管的静态显示与动态显示(KeilProteus)-CSDN博客https://blog.csdn.net/weixin_64066303/article/details/134101256?spm1001.2014.3001.5501实验:用4个独立按键控制8个LED指示灯。 按下k1键&#x…

Elasticsearch:RAG vs Fine-tunning (大语言模型微调)

如果你对 RAG 还不是很熟悉的话,请阅读之前的文章 “Elasticsearch:什么是检索增强生成 - RAG?”。你可以阅读文章 “Elasticsearch:在你的数据上训练大型语言模型 (LLM)” 来了解更多关于如何训练你的模型。在今天的文章中&#…

Git 内容学习

一、Git 的理解 Git是一个分布式版本控制系统(Distributed Version Control System,简称 DVCS),用于对项目源代码进行管理和跟踪变更。分为两种类型的仓库:本地仓库和远程仓库。 二、Git 的工作流程 详解如下&#x…

CATIA环境编辑器用不了时创建项目快捷方式

CATIA环境编辑器用不了时创建项目快捷方式 一、参考适用情况示例二、 解决步骤(一) 先正确放置winb_64部署包(二) 添加环境文件(三) 修改加入的环境文件(四) 复制本机CATIA快捷方式后重命名(五) 修改快捷方式目标的值 一、参考适用情况示例 二、 解决步骤 (一) 先正确放置winb…

社区分享|杭银消费金融基于MeterSphere开展接口自动化测试

杭银消费金融有限公司(以下简称“杭银消费金融”)成立于2015年12月,是经中国银保监会批准,由杭州银行作为主发起人,联合滴滴出行、中国银泰等企业组建的持牌消费金融机构,注册资本为25.61亿元。杭银消费金融…

关于Alibaba Cloud Toolkit 下载配置以及后端自动部署

idea中File-Settings-Plugins 搜索Alibaba Cloud Toolkit点击下载,下载完成重启 1、点击 Tools-Alibaba Cloud-Deploy to Host 部署到主机 2、配置服务器ip、jar包启动命令、服务器jar存放位置 3、设置服务器ip用户名密码,点击测试连接情况 4、配置脚本…

计算机的运算方法

无符号数 定义:没有符号的数,在寄存器中的每一位均可用来存放数值 表示范围:n 位无符号数 0~2n -1 有符号数 定义:符号位数值位 “0”代表正,“1”代表负 表示范围:n 位有符号整数 原码、反码&#x…