85

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

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

但是中间件/soa/应用程序集成上下文有区别吗?(架构级别)。我正在尝试咨询诸如维基百科(此处此处)之类的来源,但我仍然有些困惑。开发人员什么时候应该更喜欢一种解决方案而不是另一种?

有没有一种方法比另一种更有意义的例子或案例?或者任何全面的资源和指南来实施每一个?

非常感谢您的任何见解。

4

12 回答 12

97

这是 Jonas Bonér 对问题的Typesafe / Reactive观点。从这篇博文的第三段:

不同之处在于消息是定向的,事件不是——一条消息有一个明确的可寻址接收者,而一个事件只是发生给其他人(0-N)观察它。

于 2015-07-29T16:32:36.513 回答
50

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

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

于 2017-06-03T14:33:59.443 回答
34

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

这些术语不是完全可以互换的,但暗示了相同的基本架构——特别是您将触发事件或消息。

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

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

于 2009-12-23T02:10:23.187 回答
31

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

您需要就如何将信用卡授权请求从他们的服务发送到您的服务与处理 Order 服务的团队达成一致。有两种选择。

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

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

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

于 2019-03-05T18:02:55.047 回答
10

事件驱动的架构可以在有或没有消息的情况下实现。消息传递是以可靠、有保证的方式将生产者提出的事件传达给消费者的一种方式。尤其是当生产者和消费者真正解耦并且可能托管在不同的服务器/虚拟机/环境上并且不能直接访问任何共享内存时。

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

于 2012-03-19T17:18:59.900 回答
4

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

虽然消息根本没有特殊意图,但事件会告知已经发生和已经完成的事情(过去)。命令触发应该发生的事情(将来)。

于 2019-08-24T08:40:57.493 回答
3

正如本文所说为了理解事件驱动设计,我们必须观察它隐藏的内容,而不是查看它所呈现的内容,这只不过是编程的基础;“调用堆栈”。

在事件驱动设计中,方法调用的定义直接出现在窗口之外。没有更多的调用者和被调用者。那是对顺序和秩序的吻别。系统不需要知道事情必须以什么顺序发生。因此,作为调用堆栈的先决条件的共享内存空间变得不必要了。

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

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

如果消息传递的设计是为了符合事件驱动架构的公理,那么它们可以被认为是相同的。否则,它们之间存在巨大差异。

于 2014-05-15T12:57:07.463 回答
2

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

当我们使用消息驱动的方法时,我们只想发布带有一些数据的消息。发布此消息的订阅者并不重要,我们只想接收数据并以某种方式处理它。

于 2015-03-15T13:39:10.560 回答
2

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

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

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

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

于 2017-06-03T06:24:55.693 回答
1

在 OO 中,调用者和被调用者之间通过消息方式进行交互......在 GUI 中,我们总是说事件驱动。我们可以看到,如果我们需要管理发布者和订阅者的关系,我们应该使用事件驱动。如果我们管理上游和下游底层更抽象,没有强依赖(比如上游不知道下游),我们应该使用消息驱动。所以在 Message-Middleware 上下文中,并没有明显的区别,是构造上的差异,而不是设计上的差异。

于 2020-06-24T06:57:09.710 回答
1

我在谷歌搜索时遇到了这个线程,以区分消息和事件之间的差异。在阅读了上述所有回复之后,我仍然没有找到答案。

然后我尝试了更多的谷歌搜索并为我找到了答案,所以我将把它留在这里,希望对喜欢我的人有所帮助。

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

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

Akka:消息驱动与事件驱动

于 2021-10-24T14:14:00.320 回答
0

据我说:

  • 在事件驱动架构中,所有数据传输都是异步完成的,无需担心接收者/订阅者。发送的数据是对发生的某些操作的反应。一般消息量很小,但消息量很大。
  • 在消息驱动架构中,发送数据时要记住接收者使用预定义的消息格式,这种传输可以是同步的也可以是异步的。虽然它没有规则,但与事件驱动拱门相比,数据的大小更大,并且数据发送的量要少得多。
于 2020-10-31T13:10:43.013 回答