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

选择正确的工具来满足异步处理需求的技术指南作为后端开发人员,有一天你需要回答这个问题:

 
我需要构建一个使用分布式队列的异步应用程序,我应该使用哪个代理? 作为工程师,我们的本能是列出我们了解或希望熟悉的工具(如果它是一种新的和已知的技术),然后开始使用它 。不幸的是,在那个时刻 , 我们错过了第一个最重要的问题 , 这个问题需要在所有其他问题之前得到答案:我们的现有和有时未来的用例/需求是什么,什么工具能最好地解决它们? 这是我们在设计一个重要功能时的起点,当时工程师的本能占了上风 。我们的第一个问题不是最重要的问题,从那时开始,我们选择正确工具的过程变得不太有效 。我们的团队开了几次会,讨论了我们对分布式队列的需求,不同技术的不同限制和特性(来自不同的范例)让关注点远离了我们最重要的需求 , 也远离了决策和共识的实现 。在那个时候,我们决定回到基本问题,问:我们试图解决的用例是什么,没有让步的余地在哪些领域?一如既往,让我们从需求开始 。
 
 
步骤1:明确您要解决的问题以及技术/工具体系结构如何与您的目标和考虑保持一致在选择消息代理或事件代理时,有很多事情要考虑:高可用性、容错性、多租户、多云区域支持、能够支持高吞吐量和低延迟等等 , 列举不胜枚举 。
大多数情况下,当阅读有关事件代理或消息代理的主要特性时,我们都是以大多数公司或产品从未完全使用或需要的最复杂用例为例的 。
作为工程师,生活中有一句常用的话语:
上帝在细节中,但魔鬼隐藏在细节之间 。
在选择事件代理与消息代理两个范式之间,"魔鬼"隐藏在更多的低层技术考虑因素中,比如:消息的消耗或生成确认方法、去重、消息的优先级、消费者线程模型、消息的消耗方法、消息的分发/扩散支持、毒药药处理等等 。
概念之间的不同:橙子与苹果步骤2:了解两种范式之间的差异(1) 事件代理
存储一系列事件 。通常,事件会按到达事件代理的顺序附加到日志(队列或主题)上 。主题或队列中的事件是不可变的 , 其顺序不能更改 。
当事件发布到队列或主题时,代理识别主题或队列的订阅者,并使事件可供多种类型的订阅者使用 。
生产者和消费者不需要彼此熟悉 。
事件潜在地可以存储数天或数周,因为它们一旦被成功消耗 , 就不会从队列/主题中删除 。
(2) 消息代理
用于服务或组件之间的通信 。它通过异步方式在应用程序之间传输由生产者接收的消息 。
它通常支持队列的概念,其中消息通常存储一段时间 。队列中消息的目的是在消费者可用于处理消息并在成功消耗后删除消息 。
不能保证队列中消息处理的顺序,并且可以更改 。
消息代理与事件代理通常,在处理短命令或面向任务的处理时,我们会倾向于使用消息代理 。
例如,假设你在一家电子商务公司工作,想要将新产品添加到公司的网站 。这可能意味着多个服务需要知道并以异步方式处理此请求 。
消息代理与事件代理:何时使用它们

文章插图
上图显示了RabbitMQ扇出消息分发的使用,其中每个服务都有自己的队列连接到扇出交换机 。
产品服务发送包含新产品信息的消息到交换机,交换机将消息发送到所有连接的队列 。
在从队列成功消耗消息后,它将被删除,因为涉及的服务不需要保留或重新处理消息 。
在处理当前或历史事件时,通常涉及大量数据,需要以单个或批量方式处理这些数据,我们会倾向于使用事件代理 。
例如,假设你在一个娱乐评级网站工作 , 你想为用户添加一个新功能,用来显示电影的编剧和导演 。这些信息虽然历史存储,但不对负责提供这些数据的服务可用 。
消息代理与事件代理:何时使用它们

文章插图
上图显示了使用Kafka作为事件代理,它能够从数据仓库中提取数亿部电影,以为每个服务存储的电影信息附加所需的信息 。
Kafka可以在相对短的时间内接受大量的数据,而消费者可以有一个独立的消费者组来单独处理电影主题流 。
需要注意的重要方面正如我之前提到的,选择合适的范式时有很多事情要考虑 。
我想讨论一些关键的差异,这些差异通常可能成就或破坏您对技术的决策 。


推荐阅读