Rest 事件来源-如何处理竞争条件和http交付?

Rest 事件来源-如何处理竞争条件和http交付?,rest,concurrency,cqrs,event-sourcing,Rest,Concurrency,Cqrs,Event Sourcing,我试图了解如何在web应用程序中使用事件源。据我所知,事件源是以事件的形式将数据库更新存储在事件存储器中。我猜将状态与读取数据库同步可能是由守护进程完成的,守护进程从事件存储中读取最新事件,并对读取数据库执行更改 我有很多问题,但我认为最好是讨论一个示例场景。例如,我想构建一个REST服务,它有用户。我有一个限制,用户名应该是唯一的。我有一个事件存储,我已经读取了设置约束的db。好的,现在我发送一个POST/users请求,请求中包含一个已经存储在数据库中的用户名。首先,我将UserCreate

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

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

我怎样才能解决这些问题


我仍然认为将所有内容存储在事件中并添加一些缓存用于数据读取是一种很好的方法,但我真的不明白应该如何实现这一点。我认为事件源非常适合
websockets+zmq+nodejs
,或者类似的系统,但不适合
rest+php
。。。也许我读了太多关于CQR和事件来源的文章,因此失去了重点…:正如您所注意到的,在REST体系结构中,对特定资源(如
/users/123
)或资源类别(如
/users/
)进行请求。当执行添加、删除、更新
/users/124
等资源操作时,可能会有客户机对这些事件感兴趣。如果捕获到事件,可以近实时地通知感兴趣的客户。这称为基于事件的体系结构

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

我找到了答案

一致性模型是一项业务决策,因为它直接影响 用户体验。一个最终一致的模型需要一个不同的模型 用户体验比即时体验更重要,这不是你想要的 你可以直接“溜进”你的用户,或者尝试模仿。如果你是 试图在一个系统中模拟即时一致性 一致的模型,你做错了什么


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

在应用程序中适当的地方,没有任何东西可以阻止您使用这两种体系结构。您可以以一致的方式管理userId唯一性约束,然后引发UserRegistered事件,供其他所有感兴趣的方使用。您可以发送有关这些混合解决方案的链接吗?我想读更多关于这个。。。在多次搜索后,我找到了您所谈论的内容:幻灯片83…:-)实际上,对于简单的项目,您可以在客户端聚合事件,并在会话中存储快照,而不是在服务器端使用读取模型,因此,通过使用WebSocket,例如聊天、机器人或任何适合的问题域,这种方法都是有用的。。。不仅仅是需要高可用性的项目。。。