如何在事件驱动的微服务架构中进行查询?

How to query in a Event Driven Microservice architecture?

假设以下基于 CQRS 架构的简单 UC:

我们有一个后端管理业务对象,比方说电影。

一个简单的方法是:

好的,现在我想以更事件驱动的方式改造这个 UC。这是新流程:

此时,由于这种流程是异步的,因此前端不再等待响应。我们如何完成此流程才能将用户转到电影信息网页?在查询 QueryManager 之前,我们应该等待创建过程完成。

通俗点说,在基于bus/event的异步架构中,如何执行用于提供网页信息的Query?

At this point, the frontend is no more waiting for a response due to the fact that this kind of flow is asynchronous. How could we complete this flow in order to forward the user to the Movie Information Web page? We should wait that the creation process is done before querying the QueryManager.

简答:明确协议。

更长的答案:在这里寻找灵感的好地方是 HTTP。

前端向源站发起POST;结果,源服务器在队列中放置了一条消息,sends a response back.

The representation sent with this response ought to describe the request's current status and point to (or embed) a status monitor that can provide the user with an estimate of when the request will be fulfilled.

然后客户端可以轮询端点以了解取得的进展。

例如,端点可能是对数据存储的查询,它寻找命令管理器已处理原始命令的证据;或者它可能是一个正在监视 MovieCreated 消息总线的端点,并根据它是否看到该消息来更改其答案。

如果它之前处理过该邮件的副本,可能有助于澄清调查 idempotent request handling; when the Command Manager pulls a message off of its queue, how does it know 的事情?您的轮询端点应该能够使用相同的信息让消费者知道消息已被成功处理。

除了@VoiceOfUnreason的回答,

如果两个微服务是 RESTFul,CommandManager 可以 return 一个 202 Accepted 和一个 link 指向将在中创建的资源未来。然后客户端可以轮询该资源,直到服务器响应 200 OK.

另一种解决方案是 CommandManager 将 return 一个 202 Accepted,link 指向一个 command/status 端点。客户端将轮询该端点,直到状态为 command-processed(包括对实际资源的 URL)或 command-failed(包括失败的描述性消息)。

可以通过使用 Server Sent Events 发送所有已处理命令的状态来增强这些解决方案。这样,客户端无需轮询即可得到通知。

如果客户端不知道架构是异步的,解决方案是使用 API 网关阻塞客户端的请求,直到上游微服务处理命令,然后用完整的资源数据响应.

除了@Constantin Galbenu 的回答之外,我还想投入我的两分钱。

我强烈建议您查看一种名为 "BFF" (Backend-For-Frontend) 模式的微服务模式。您可以让每个用例有一个 API,而不是让一个厚厚的 API 网关来完成所有工作。例如:在您的情况下,您可以使用一个名为 "CreateMovieBFFHandler" 的 API 来接收来自前端的 POST 请求,然后这个人会与系统中的其他事物(如消息队列)进行协调,事件等来跟踪提交请求的状态。 UI 可能与此 BFFhandler 有一个协议,如果响应没有在 X 秒内返回,那么前端将认为它失败并且如果此处理程序能够从消息队列中获得成功处理的消息或此键的 "MovieCreated" 事件,然后它可以返回 200 OK,然后您可以重定向页面以调用写入端,然后填充 UI。

有用Link:https://samnewman.io/patterns/architectural/bff/