消息驱动与事件驱动的应用集成方法

106
我想知道在SOA或中间件以及应用和企业集成的情况下,消息驱动和事件驱动环境是否有明显区别。我理解用户界面类似于事件驱动模型,其中我们的系统截取用户操作。
此外,消息支持基于发布/订阅、同步或异步通信、事务等的系统。
但在中间件/SOA/应用程序集成环境(架构层面)中是否存在差异?我试图参考维基百科(这里这里 ),但仍然有些困惑。开发人员何时应该选择一种解决方案而不是另一种解决方案?
是否有例子或情况,其中一种方法比另一种方法更合理?或者有关于实现每种方法的全面资源和指南吗?
非常感谢您提供的任何见解。
12个回答

119
这是关于 Jonas Bonér 的一个问题的Typesafe/Reactive观点。从这篇博客文章的第三段开始:
“区别在于消息是有方向性的,而事件则没有——消息具有明确的可寻址收件人,而事件只是为其他人(0-N)观察而发生。”

6
值得强调的是直接通讯,因为我们可以向0-N个可寻址的接收者广播消息。 - 4lex1v
但是事件最终被发送为消息。 :/ - Mr_Hmp
“处理这个有效载荷”是一条消息(比如说基于某些元数据生成图像,或从某个PDF中提取数据),但是,“我已经处理了这个PDF或系统中发生的某些变化”是一个事件。显然,没有人能阻止你滥用它。 - best wishes

59

这个问题很久以前就被提出来了。我认为更现代和清晰的回答是由Reactive ManifestoMessage-Driven(与Event-Driven相对)中给出的:

消息是发送到特定目标的数据项。事件是组件达到给定状态时发出的信号。在消息驱动的系统中,可寻址接收者等待消息的到来并对其做出反应,否则处于休眠状态。在事件驱动的系统中,通知监听器附加到事件源,使得它们在事件发出时被调用。这意味着一个事件驱动的系统关注可寻址的事件源,而一个消息驱动的系统集中于可寻址的接收者。消息可以作为其有效负载包含编码事件。


43
假设您正在为电子商务网站构建付款服务。当下订单时,订单服务将请求您的付款服务授权客户的信用卡。只有在信用卡获得授权后,订单服务才会将订单发送到仓库进行打包和发货。
您需要与负责订单服务的团队就如何从他们的服务向您的服务发送信用卡授权请求达成一致。有两个选择:
1. 消息驱动:下订单时,订单服务向您的付款服务发送授权请求。您的服务处理该请求,并将成功或失败的结果返回给订单服务。初始请求和结果可以同步或异步发送。 2. 事件驱动:下订单时,订单服务发布一个NewOrder事件。您的付款服务订阅了该类型的事件,因此会被触发。您的服务处理该请求,并发布AuthorizationAccepted或AuthorizationDeclined事件。订单服务订阅这些事件类型。所有事件都是异步的。
事件驱动方法的优势是其他服务也可以订阅各种事件。例如,可能会有一个RevenueReporting服务订阅AuthorizationAccepted事件并创建财务团队的报告。

事件驱动方法的一个缺点是整个系统变得稍微难以理解。例如,假设负责订单服务的团队要求您根据信用卡被拒绝的原因(没有资金,账户关闭,账单地址不正确等)用不同的事件替换AuthorizationDeclined事件。如果您停止发布AuthorizationDeclined事件,那么是否会影响其他一些服务?如果有许多事件和服务,则可能很难跟踪。


1
这并没有解释消息和事件之间的有效区别。付款服务也可以订阅newOrder消息。你是想说事件驱动默认情况下是异步的吗?能否进一步澄清? - Aarish Ramesh
在面向对象编程中,调用者和被调用者之间是通过消息交互的方式进行交互的。 - fjjiaboming
2
我喜欢这个解释。底线问题是何时使用其中之一。我的看法是要注意“订阅者”以及如何处理源和对订阅者的影响的变化。根据您的源和目标(即订阅者),使用一种方法或另一种方法都有意义。 - FraK
3
@AarishRamesh - 我认为主要的区别在于:1.消息是点对点的,发送者需要知道接收者。2.事件是一对多的广播,发送者不需要知道接收者。 - Martin Omander

36
"是否有明确的区别"的简短回答是"没有"。
这些术语并不能完全互换,但意味着同样的基本架构-具体来说,您将会触发事件或消息。
您所提到的第一篇文章是关于底层管道,即MOM或发布/订阅“总线”,它代表您传输消息。事件驱动架构是您在该框架之上构建的内容。
虽然术语“事件驱动”也适用于GUI代码,但实际上不处于相同的抽象级别。在那种情况下,它是一种小型模式,与沿消息/事件驱动线构建整个企业相比较而言。

3
我无法完全同意这个答案,因为在其他答案中列出了这两种方法之间的明显区别。 - Pavel
1
@Pavel,你为什么认为它们有明显的区别?其他答案只是提出了它们之间的一些差异,这些差异并不是绝对的区别。 - choxsword

11

事件驱动架构可以使用或不使用消息传递来通信。消息传递是一种可靠、保证的方式,用于将生产者产生的事件传递给消费者。特别是当生产者和消费者真正解耦且可能托管在不同的服务器/虚拟机/环境中,并且没有直接访问任何共享内存时。

但在某些情况下-当事件的消费者是注册在同一应用程序内部的函数/回调时,或者当需要同步执行消费者时,可以在不使用消息传递的情况下实现事件订阅。


5

消息(Message)概念是抽象的,更具体的消息类型是事件(Event)和命令(Command)。

虽然消息没有任何特殊意图,但是事件通知已经发生并已经完成(在过去)。命令触发应该发生的事情(在未来)。


3
正如这篇文章中所说的那样,为了理解事件驱动设计,我们必须观察它隐藏的东西,而这恰恰是编程基础——“调用栈”。在事件驱动设计中,方法调用的定义不再适用。没有了调用者和被调用者,也就不需要考虑调用顺序和顺序问题。系统不需要知道事情发生的顺序。因此,共享内存空间(调用栈的前提条件)变得不再必要。
然而,在调用栈环境中,不仅调用者必须知道接下来会发生什么,还必须能够将功能与方法名称关联起来。
默认情况下,面向消息的应用程序会删除共享内存。发布者和订阅者不需要共享内存空间。另一方面,所有其他特征(例如顺序、方法名称耦合等)都不是必需的。
如果消息传递被设计为符合事件驱动架构的公理,它们可以被认为是相同的。否则,它们之间存在巨大的差异。

2

事件驱动架构和消息驱动架构是两种不同的东西,解决了两个不同的问题。

事件驱动架构关注的是系统如何被触发运行。在EDA的上下文中,大多数被认为是事件的触发器都是由其他手段生成的事件。如果让我们显式地考虑事件生成器、事件通道和事件处理引擎,那么它就是一个EDA。

键盘和鼠标是明显的事件生成器,但是这些事件的处理已经由各种框架或运行时进行了处理,作为架构师,我们不需要担心这一点。架构师需要思考的是某些领域特定的其他事件。例如——供应链管理事件——拣选、打包、派送、分销商、售出等。从技术角度来看,对于工业物联网类型的应用程序,RFID读取、生物识别读取、传感器数据、条码扫描、系统生成的事件是需要显式处理的事件,因为这些事件驱动着系统的功能。

消息驱动架构的重点是通过使用标准的面向消息的中间件将消息从一个模块传递到系统的另一个模块,以集成分布式系统。


2
如果我们采用事件驱动的方法,通常希望在事件中发送源对象——发布事件的组件。因此,在订阅者中,我们不仅可以获取数据,还可以知道是谁发布了这个事件。例如,在移动开发中,我们接收到的是View,它可以是按钮、图像或某个自定义视图。根据这个View的类型,我们可以在订阅者中使用不同的逻辑。在这种情况下,我们甚至可以添加一些后处理,修改源组件——例如,为这些源视图添加动画。

当我们使用消息驱动的方法时,我们只想发布带有一些数据的消息。对于订阅者来说,由谁发布这条消息并不重要,我们只想接收数据并以某种方式进行处理。


1

我在谷歌上搜索消息和事件之间的区别时遇到了这个帖子。在阅读了以上所有回复后,仍然没有得到答案。

于是我尝试了更多的搜索,并找到了适合我的答案,所以我打算留在这里,希望能帮助像我一样的人。

消息是发送到特定地址的一些数据。在消息驱动系统中,每个组件都有一个唯一的地址,其他组件可以向其发送消息。这些组件或接收者等待消息并对其做出反应。

事件是从组件发出的一些数据,供任何监听者使用。

Akka: 消息驱动 vs 事件驱动


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接