我应该使用命令还是事件?


14

在总线通信中,命令和事件之间的区别在我看来似乎有点模糊。我知道命令应该只执行一次,而一个事件可以处理多次,但是我仍然不确定何时使用命令或事件。

让我们看一个例子:

当新用户注册到Web应用程序时,我们应该为他创建一个帐户并发送确认电子邮件。

创建帐户 -这似乎是将a发送CreateUserCommand到总线并由专门的组件处理的正确位置。

也许这甚至不应该使用异步总线通信来实现?我们希望用户能够立即登录到应用程序。对于总线,我们无法保证命令将在何时执行。

发送电子邮件 -组件创建帐户后,我可以看到2种可能性

  1. 向总线发送另一个命令 SendConfirmationEmailCommand
  2. 发布活动 UserAccountCreatedEvent

而不是让电子邮件发件人组件抓住它并完成任务。

一方面,我希望确认电子邮件仅发送一次(使用命令),另一方面,我相信可能有多个对新注册用户感兴趣的组件。记录器或SMS发送者。

您将如何实施?

Answers:


16

原则上,命令描述将要执行的请求,而事件则描述已发生的事情:

  • 命令需要由处理器执行某些操作,并且此操作应仅由该处理器执行一次。

  • 事件是已执行或外部发生的某些操作的通知。几个处理器/代理可能对了解事件感兴趣。他们中的一些人可能会在其责任范围内进一步发出此通知所要求的命令或动作。

在您的情况下,我了解:

  • CreateUserCommand 是命令
  • UserAccountCreatedEventCreateUserCommand由帐户管理服务成功完成时应发出的事件

现在有两种可能性:

  1. 帐户管理服务会SendConfirmationEmailCommand在总线上自行发出“ a ”,因为它希望该命令由更专业的服务执行。
  2. 帐户管理服务只不过是在完成时发送事件通知,并留给另一个服务(例如,通信服务,订阅服务等)来决定是否发送电子邮件/短信/等...以及是否发出SendConfirmationEmailCommand要由某个网关执行的命令所必需的。

如果您选择了服务总线方法,则应使用允许的灵活性,即支持选项2。


谢谢,这清除了一切。关于选项2的另外两个问题:1.帐户管理服务如何知道命令的完成?我相信这是通过听取专业服务在完成任务后发布的事件来进行的,而不是帐户管理服务的真正目的是什么?要重新发布事件?似乎多余。2.我也不知道应该由谁发出SendConfirmationEmailCommand。帐户管理服务还是“其他服务”?
Andrzej Gis

1)我的假设是,帐户管理服务会自行完成工作,并在事件成功完成后发送事件(即没有遇到错误)。但是您是正确的:帐户管理服务可能会将其自身的命令发送到持久性/数据库服务,并且必须监视作业完成事件(例如,异步回答)。
Christophe

@gisek 2)在服务总线中,我想您有非常专业的服务,每个服务的责任有限。在这种情况下,“帐户管理”仅执行创建操作,并向感兴趣的任何人通知创建完成。然后,其他一些服务将监视事物以做出反应。例如,您可能有一个沟通经理,他将负责应用业务规则来决定何时以及如何向用户传达事件。如果您在同一服务中执行1)+2),则几乎不需要服务总线。
Christophe
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.