事件溯源 - 如何处理竞争条件和 HTTP 交付



我试图了解如何在 Web 应用程序中使用事件溯源。据我所知,事件溯源是关于在事件存储中以事件的形式存储数据库更新。我想将状态与读取数据库同步可能是由守护程序完成的,该守护程序从事件存储中读出最新事件并对读取数据库执行更改。

我有很多问题,但我认为如果我们谈论一个示例场景是最好的。例如,我想构建一个具有用户的 REST 服务。我有一个约束,用户名应该是唯一的。我有一个事件存储,并且我已经读取了设置约束的数据库。好的,现在我发送一个POST /users请求,其中包含已存储在数据库中的用户名。首先,我将UserCreated事件存储在事件存储中,现在该怎么办?我可以使用我猜到的事件存储生成资源 ID,因此我可以在 GET /users/{id} 链接中使用 201 created 标头将其发回。客户端获取该链接,单击它(可能是自动的,或者我什至可以发回位置标头(,但读取的数据库尚未同步,因此会收到404 not found错误...好的,我们可以设置客户端,等待响应。我不明白,我应该在哪些渠道发回关于同步结果的响应?通过带有线程的语言,如 java,或带有事件循环的语言,如 nodejs,没关系,我可以添加事件和事件处理程序,但通过仅具有进程的语言,例如 php,我必须构建一些具有巨大内存泄漏的同步守护进程,并找到一种方法来构建事件总线。这是可以做到的,但这将是艰难和血腥的。所以在那之后我会得到一个正确的回应,比如500 internal server error,或者类似的东西。所以最后我最终得到了一个损坏的事件存储,一个无效的UserCreated事件,我无法将其与我的读取数据库同步......

我该如何解决这类问题?

仍然认为将所有内容存储在事件中并为数据读取添加一些缓存是一个很好的方法,但我真的不明白我应该如何实现这一点。我认为事件溯源可以非常适合websockets + zmq + nodejs或类似的系统,但不适合rest + php......也许我因为阅读太多关于 cqrs 和事件源的信息而失去了重点...... :S

如您所注意的,在 REST 体系结构中,请求是对特定资源(如/users/123(或资源类别(如 /users/ (发出的。执行添加、删除、更新/users/124等资源操作时,可能存在对这些事件感兴趣的客户端。如果捕获了事件,则可以近乎实时地通知感兴趣的客户端。这称为基于事件的体系结构。

基于

事件的体系结构提供了一种有效的方法来保持事件生产者和事件使用者客户端的状态与系统同步,而不是系统定期处理来自事件使用者客户端(即基于轮询的客户端(的完整状态请求。通常,事件驱动和轮询驱动的方法都用于将客户端与系统同步。

我在这里找到了答案。

一致性模型是一项业务决策,因为它直接影响 用户体验。最终一致的模型需要不同的 用户体验比直接的,这不是你的东西 可以只是"溜进"给你的用户,或者尝试模仿。如果你是 试图在最终模拟即时一致性 一致的模型,你做错了什么。

事件溯源需要最终一致性,而 REST 可以同时实现最终一致性和即时一致性。例如,可以返回 202 接受标头以指示最终一致性。通常我们(至少我(在发送 POST 时会想到 REST,然后我返回一个带有指向新创建的资源的超媒体的 201 标头,因此我可以向该资源添加更多内容,修改它,等等......这样我就可以保持我的表单小...通过最终一致性,我必须以单个形式或至少在单个请求中添加所有这些内容,除非我不想等待事件源的读写同步......我认为为您的应用程序选择一致性模型是一个很大的挑战,以后它可能会与维护冲突。例如,您打算添加具有即时一致性的功能,但您已经选择了最终一致性...

最新更新