活动采购 - 如何应对竞争条件和http交付?

时间:2014-04-21 02:17:35

标签: rest concurrency cqrs event-sourcing

我尝试了解如何使用Web应用程序进行事件采购。据我所知,事件源是关于在事件存储中以事件的形式存储db更新。我想可能是通过守护进程来完成状态与读取数据库的同步,该守护进程从事件存储中读取最新事件并在读取数据库上执行更改。

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

我该如何解决这些问题?

我仍然认为这是一个很好的方法来存储事件中的所有内容并为数据读取添加一些缓存,但我真的不明白我应该如何实现它。我认为事件采购非常适合websockets + zmq + nodejs或类似系统,但不适合rest + php ......也许我通过阅读过多关于cqrs和事件采购的内容而忽略了这一点......:S

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

我找到了答案here

  

一致性模型是一项商业决策,因为它会直接影响   用户体验。最终一致的模型需要不同的模型   用户体验比直接用户体验,这不是你的事   可以“滑入”您的用户,或尝试模仿。如果你是   试图最终模仿立即的一致性   一致的模型,你做错了。

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