事件源架构是否需要使用消息队列?

时间:2019-04-29 21:26:07

标签: architecture message-queue event-sourcing event-driven

考虑这个简单的例子。假设您有一个带ff的事件表TBL_EVENTS。列:

  • eventId(int)
  • dateTime(日期时间)
  • eventName(字符串)
  • 数据(json)

现在ff。事件发生了:

$UserService->registerUser();

USER_REGISTERED事件现在与ff一起存储在TBL_EVENTS中。数据:

eventId: 1
dateTime: 2019-04-30 00:00:00
eventName: USER_REGISTERED
data: {"userId":1, "name":"foo"}

第一个问题:事件侦听器是否每隔x秒直接查询/监听TBL_EVENTS,还是需要一个消息队列来避免对轮询请求进行“轰炸” TBL_EVENTS

例如,除了$UserService->registerUser();之外,AWS SQS还在单独的消息队列(例如TBL_EVENTS)中推送“事件”,然后$UserService->listener();轮询{{1 }}而不是SQS?还是在现实应用中使用了对TBL_EVENTS的直接轮询?


第二个问题:当TBL_EVENTS获得一个$UserService->listener();事件时,它只是为一个单独的USER_REGISTERED表创建了一个新用户还是重播了所有事件从TBL_USERS到现在,从而每次都在0中创建所有用户?

1 个答案:

答案 0 :(得分:0)

对于类似的用例,我的设计实现了以下方法-

[1] 事件源系统-调用->事件代理-写入记录->事件阶段表

[2] 事件阶段表-触发器->数据库过程-写入->事件队列

[3] 事件处理程序-投票->事件队列

这样的处理点链帮助我保持了非常简单和干净的实现,并且可以灵活地独立测试系统的单元部分。

现在,关于您的问题2 ;我不理解您始终需要从头开始创建用户的需求。但是,如果出于某种原因需要这样做,则使用上述方法,您将需要另一个数据库过程(在第2点处),该过程将迭代表的现有行,并调用写入事件队列的现有过程。

这里可以考虑的另一种替代方法是,写入数据库并并行处理事件-

[1] 事件源系统-广播->事件频道

[2] 数据库程序-收听->活动频道

[3] 数据库程序-写入->用户表

[4] 事件控制器-收听->事件频道

[5] 事件控制器-调用->事件处理程序

以上方法可以提供声明式(数据驱动)方法来注册事件处理程序,并提供与写入DB并行处理事件的性能优势;但是缺点是,如果您期望事务性行为,那么写入数据库和处理事件可能需要付出额外的努力。