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


70

我想知道当我们提到SOA或中间件时,通常在应用程序和企业集成的情况下,消息驱动环境和事件驱动环境之间是否存在明显的区别。我了解到,用户界面类似于事件驱动的模型,其中我们的系统拦截用户的操作。

同样很明显,消息传递支持基于发布/订阅,同步或异步通信,事务等的系统。

但是中间件/ soa /应用程序集成上下文是否有所不同?(体系结构级别)。我正在尝试查阅Wikipedia的资源(herehere),但是我仍然有些困惑。开发人员何时应首选一种解决方案?

是否存在一些例子或案例,其中一种方法比另一种方法更有意义?或是否有任何综合资源和实施指南?

非常感谢您的见解。

Answers:


30

对“是否有明显区别”的简短回答是“否”。

这些术语并不是完全可以互换的,而是暗示着相同的基本体系结构-特别是您将触发事件或消息。

您引用的第一篇文章是有关低级管道,MOM或代表您传输消息的pub-sub“总线”的。事件驱动的体系结构是您在该框架之上构建的。

术语事件驱动,虽然也适用于GUI代码,但实际上并不是处于相同的抽象级别。在这种情况下,与沿着消息/事件驱动线构建整个企业相比,这是一个很小的模式。


1
我不能完全同意这个答案,因为这两种方法之间有明显的区别,并且在其他答案中也列出了它们。
帕维尔

72

这是JonasBonér对这个问题的Typesafe / Reactive观点。在此博客文章的第三段中:

区别在于消息是定向的,事件不是定向的-消息具有明确的可寻址收件人,而事件只是发生在其他人(0-N)观察它的情况下。


4
还需要强调直接词,因为我们可以在0-N个可寻址收件人之间广播消息。
2015年

但是事件将在一天结束时作为消息发送。:/
Mr_Hmp '20

41

这个问题是很久以前问的。我认为反应式宣言消息驱动(与事件驱动相反)中给出了更现代,更清晰的响应:

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


21

假设您正在为电子商务网站构建付款服务。下订单后,订单服务将要求您的付款服务授权客户的信用卡。仅当信用卡被授权后,订购服务才会将订单发送到仓库进行包装和运输。

您需要与订购服务团队合作,以了解如何将信用卡授权请求从他们的服务发送到您的服务。有两种选择。

  • 消息驱动:下订单时,订单服务会将授权请求发送到您的付款服务。您的服务处理该请求,并将成功/失败返回给订购服务。初始请求和结果可以同步或异步发送。
  • 事件驱动:下订单时,订单服务将发布NewOrder事件。您的付款服务订阅了此类事件,因此被触发。您的服务处理请求,并发布AuthorizationAccepted或AuthorizationDeclined事件。订单服务订阅这些事件类型。所有事件都是异步的。

事件驱动方法的优点是其他服务也可以订阅各种事件。例如,可能有一个RevenueReporting服务可以订阅AuthorizationAccepted事件并为Finance团队创建报告。

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


这不能解释消息和事件之间的有效区别。付款服务也可以订阅newOrder消息。您是否要说明事件驱动默认情况下是异步的?您能否进一步澄清?
Aarish Ramesh

在OO中,它通过呼叫者和被呼叫者之间的消息方式进行交互...
fjjiaboming

1
我喜欢这个解释。底部的问题是何时使用一个或另一个。我对此的看法是要记住“订户”以及如何处理源中的更改以及对订户的影响。根据您的来源和目的地(也就是订户),使用一种方法或另一种方法可能很有意义。
FraK

1
@AarishRamesh-我认为主要区别在于:1.消息是点对点的,发送方需要知道接收方。2.事件是一对多广播,发送方不需要知道接收方。
Martin Omander

8

事件驱动的体系结构可以在有或没有消息传递的情况下实现。消息传递是一种以可靠,有保证的方式将生产者引发的事件传达给消费者的方法。特别是当生产者和消费者真正脱钩,并且可能托管在不同的服务器/ VM /环境中并且无法直接访问任何共享内存时。

但是,在特定情况下-当事件的使用者是在同一应用程序本身内注册的函数/回调,或者当使用者需要同步执行时,则可以在没有消息传递的情况下实现事件订阅。


3

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

尽管消息根本没有什么特别的意图,但事件会告知已经发生并且已经完成的事情(过去)。命令会触发某些事情(将来发生)。


2

由于它在很好地把这个文章,以了解事件驱动的设计,而不是在它提出我们要观察什么隐瞒,这就是没有看多非常基本的编程; “调用堆栈”。

在事件驱动的设计中,方法调用的定义直接显示在窗口之外。没有更多的主叫方和被叫方。那是一个亲吻序列和命令的吻。系统不需要知道事情必须按什么顺序发生。因此,共享存储空间(这是调用堆栈的先决条件)变得不必要。

但是,在调用堆栈环境中,不仅调用者必须知道接下来会发生什么,而且还必须能够将功能与方法名称相关联。

默认情况下,面向消息的应用程序附带删除共享内存。发布者和订阅者不需要共享存储空间。另一方面,所有其他功能(即顺序,方法名称耦合等)不是必需的。

如果将消息传递设计为符合事件驱动架构的公理,则可以将它们视为相同。否则它们之间会有巨大的差异。


1

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

当我们使用消息驱动的方法时,我们只希望发布包含某些数据的消息。发布此消息的订户无关紧要,我们只想接收数据并以某种方式处理它。


1

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

事件驱动架构的重点是如何触发系统运行。在EDA上下文中被认为是事件的大多数触发器是通过键盘和鼠标以外的方式生成的事件。如果这使我们明确考虑事件生成器,事件通道,事件处理引擎,那么它就是EDA。

键盘和鼠标是明显的事件生成器,但是各种框架或运行时已经处理了这些事件,作为架构师,我们无需担心。预期架构师会考虑特定于特定领域的其他事件。示例–供应链管理事件–取货,包装,发货,分销,零售商,已售等。从工业物联网类型技术的技术角度来看,事件是– RFID读取,生物识别读取,传感器数据,条形码扫描,系统生成的事件是需要明确处理的事件,因为这些事件驱动系统的功能。

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


0

在OO中,它通过呼叫者和被叫者之间的消息方式进行交互。在GUI中,我们总是说事件驱动。我们可以看到,如果需要同时管理发布者和订阅者之间的关系,则应该使用事件驱动。如果我们在没有强依赖性的情况下管理更抽象的上游和下游基础(例如上游不知道下游),则应使用消息驱动。因此,在Message-Middleware上下文中,没有明显的区别,而是结构差异而不是设计差异。


更多详细信息,“事件驱动”表示存在一个状态更改的聚合,例如InventoryUpdated或UserCreated或OrderPaid。
fjjiaboming

一言以蔽之,消息驱动比事件驱动更抽象。我们关注事件驱动中的处理状态,而不是消息驱动中的具体数据细节。
fjjiaboming

0

据我说:

  • 在事件驱动的体系结构中,所有数据传输都是异步完成的,不必担心接收方/订阅方。发送的数据是对某些动作的反应。通常,消息大小很小,但是消息量很大。
  • 在消息驱动的架构中,发送数据时要牢记接收者采用预定义的消息格式,这种传输可以是同步的也可以是异步的。尽管没有规则,但是与事件驱动的拱门相比,数据的大小更大,并且数据的发送量要少得多。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.