1

我正在设计一个系统,该系统使用基于事件的通信(使用 Google Cloud Pub/Sub)的微服务架构。

每个服务都在侦听和发布消息,因此服务之间的一切都非常好。

最重要的是,我想提供一个 REST API,用户可以在不破坏基于事件的方法的情况下使用它。但是,如果我有一个触发事件 X 的端点,我将如何将响应发送给用户?为“ProcessXComplete”事件创建订阅者并返回 200 OK 是否有意义?

例如:

我有以下微服务:

  1. 服务A
  2. 服务乙
  3. 前端服务 - REST 端点

我想发送这个请求“POST /posts”——这个请求发送到前端服务。前端服务应该触发“NewPostEvent”。Service A 和 Service B 都会监听这个事件并做一些事情。

到目前为止,一切都很好,但这就是我开始变得混乱的地方。现在我想向发出请求的用户返回操作完成的有效响应。我怎么知道所有服务都完成了它们的任务,以及如何创建处理程序来返回这个响应?

这样做是否有意义,或者是否有更好的设计来实现服务之间基于事件的通信并提供 REST API

4

2 回答 2

1

您所描述的绝对是基于事件的编程的挑战之一,以及最终一致性(和缺乏原子性)如何与本质上同步的 UI/UX 协调。

举办活动通常是有意义的EventXComplete。我们的微服务在完成任何可能失败的事情时发布事件。因此,有很多ServiceA.EventXSuccess事件流经队列。我对 Google Cloud PubSub 并不特别熟悉,但总的来说,在消息传递系统中,在订阅者很少(或没有)需要计算能力的情况下发布消息几乎没有额外成本。因此,默认情况下,我们倾向于过度表达服务状态;稍后再回来并根据需要淡化消息传递很容易。事实上,我们的一些较新的服务具有可通过管理 API 配置的消息详细程度。

前端服务(这里可能被认为是Gateway ServiceFacade Layer)承担了作为 UI 响应式支持的责任,因此它实际上需要响应式。在这个例子中,我希望它能够坚持用户的 POST 请求,返回一个200响应,然后根据它从 ServiceA 和 ServiceB 订阅的事件更新其请求的本地副本。它还需要提供一种机制(事件、电子邮件、webhook、gRPC 等),以便在发生故障时(甚至可能发生成功)从前端服务与任何 UI 进行通信。您使用哪种通信方式取决于通知的重要性和时间敏感性。一个很好的例子是收到一封来自亚马逊的电子邮件,说您下的订单的计费失败。他们会在几分钟内通过电子邮件通知您,但不会让您等待ExecuteOrderBilling消息在 UI 中得到处理。

将微服务连接到 UI 一直是我们特定旅程中最具挑战性的方面之一;避免模​​型/数据结构的紧密耦合,独立于微服务流程的 UI 工作流,也许对我们来说最困难的一个:授权。这些是这种分布式架构模式隐藏的阴暗面,但它们也可以被克服。可能需要对您的特定系统进行一些实验。

于 2019-09-15T14:49:07.973 回答
0

这实际上取决于您的业务案例。如果 REST svc 正在消息队列中删除消息,那么在删除消息后,我们只需返回客户端可以轮询以检查进度的参考 ID。

例如航班搜索,您的系统必须调用 100 多个后端服务来向您显示航班交易。搜索 api 会将消息放入队列中,并使用一些参考 ID 将其保存在数据库中,然后您将相同的 id 返回给客户端。一旦工作人员处理完消息,他们将使用结果更新 DB 中的引用,同时您的客户端将轮询(或最好是 Web 套接字)以使用结果更新 UI。

这个想法是你不能阻止请求并保持一切异步,这将使系统可扩展。

于 2019-09-15T23:25:29.427 回答