如何仅在事件驱动的体系结构中接收到两个或多个事件后才触发操作?

时间:2018-07-19 11:13:01

标签: architecture microservices event-driven-design

我已经开始在事件驱动的体系结构中实现微服务。因此,我的某些服务正在发布事件并监听其他事件。例如,当一个动作依赖于一个事件时,实现侦听器非常简单;

ORDER SERVICE 
  1. Publishes `ORDER_INTENT_EVENT` then
  2. Listens for `CREDIT_AVAILABLE_EVENT` then
  3. Finishes the `Order`

CREDIT SERVICE
  1. Listens for `ORDER_INTENT_EVENT` then
  2. Verifies if the client has credit then locks the amount and
  3. Publishes `CREDIT_AVAILABLE_EVENT`

例如,当OrderService必须等待多个事件时,就会出现问题;

ORDER SERVICE 
  1. Publishes `ORDER_INTENT_EVENT` then
  2. Listens for `CREDIT_AVAILABLE_EVENT` 
             and `INVENTORY_AVAILABLE_EVENT` then <--- Problem here

  3. Finishes the `Order`

CREDIT SERVICE
  1. Listens for `ORDER_INTENT_EVENT` then
  2. Verifies if the client has credit then locks the amount and
  3. Publishes `CREDIT_AVAILABLE_EVENT`

INVENTORY SERVICE
  1. Listens for `ORDER_INTENT_EVENT` then
  2. Verifies if inventory has items then locks the items and
  3. Publishes `INVENTORY_AVAILABLE_EVENT`

问题是;我正在同时合并两个队列CREDIT_AVAILABLE_QUEUEINVENTORY_AVAILABLE_QUEUE, 而且两个事件都必须存在,这样我才能完成订单。 如何进行协调,以便OrderService将两个事件都视为一个事件?

例如,我可以在应用程序级别实现它;如果发生一个事件,则将其保存到数据库中,并检查是否有另一个对应的事件以相同的顺序进行;如果是,则我继续完成该命令;如果没有,我什么也不做,那么当另一个事件到达时,我将它们全部都包含在内我能够完成订单。这种方法的问题在于,在同时产生比赛条件的同时接收两个事件的可能性很小。

这种情况的建议模式是什么?

PS 。:我发现this similar question,但一个答案表明与.net相关的工具,而另一个答案则指向第三方服务。我对模式/代码解决方案感兴趣。

1 个答案:

答案 0 :(得分:0)

每当您有多个输入源进入一个特定状态时,您就有可能出现竞争状况。这就是为什么我们有锁。您必须使用某种锁来处理竞争状况。

这可以在数据库层或使用锁定库或共享内存来实现(请使用锁定库,除非您对这种内存/ CPU体系结构的了解超出了此发布所暗示的范围,否则请使用锁定库。)

大多数语言都实现了某种形式的互斥锁,以解决此问题。如果您使用多个进程/机器/等等,则将需要某种形式的外部互斥锁(通常由数据库提供程序实现)。如果您缺少此功能,则可以使用分布式锁定系统。