【问题标题】:Async response from API Gateway in microservices来自微服务中 API 网关的异步响应
【发布时间】:2019-02-08 07:22:48
【问题描述】:

在微服务架构中,建议:

  1. 客户端应用程序到 API 网关的通信应该是同步的(例如 REST over http)。

  2. 微服务通信的API网关也应该是 同步

  3. 但是服务到服务的通信应该是异步的。

您应该尽可能遵循的另一条规则是使用 只有内部服务之间的异步消息传递,并使用 同步通信(例如 HTTP)仅从客户端应用程序到 前端服务(API 网关加上第一级 微服务)。

https://docs.microsoft.com/en-us/dotnet/standard/microservices-architecture/architect-microservice-container-applications/asynchronous-message-based-communication

现在,如果我理解正确的话,当用户请求 API 网关,然后它调用第一个服务时,它会返回一个确认(带有一些 GUID),该确认将被传递给客户端应用程序。但是服务将继续执行请求。 现在弹出一个问题,当请求处理完成时,他们将如何通知客户端应用程序。一种方法是客户端可以使用传递给它的 GUID 检查状态。

但是可以通过一些推送通知来完成吗?我们如何集成服务器到服务器的推送通知?

【问题讨论】:

  • 这个建议是错误的。不可能给出这样一个普遍的指导方针。适当的沟通方式取决于每个单独沟通路径的具体情况。
  • @usr,明白你的意思。这将取决于用例。但是让我们假设这个用例有一个场景,解决方案是什么。

标签: microservices


【解决方案1】:

您正在描述一个场景,其中系统与外部参与者(粗鲁地说,用户)之间的整个交互遵循异步模型。这是完全合理的,但如果你真的需要它。事实上,如果您选择让“外部”通过 REST API 与您的系统交互,那么您可能根本不需要它。

如果系统通过同步应用端点接收请求,例如REST端点,它必须在发送响应之前完成请求,否则将毫无意义。考虑一个类似的 API

发布用户/:用户名/通知

通知本质上是同步的,但请求只是声明“应将新通知附加到用户的通知集合中”。 API 响应 201 表示“好的,通知已经与用户关联,最终将在某个频道上推送”。这是描述异步交互的“事务”方式

当用户想要订阅通知频道时,会出现另一种情况。我希望这将通过双向、异步、pubsub 通信协议(例如 websockets)来实现。

然而,在这两种情况下,微服务如何相互通信并不重要,如果请求是同步的,“链”的第一个服务应该等到准备好响应。这是因为 API 网关在 http 中转发请求的原因。

另一方面,异步通信可用于强制服务之间的一致性,而不是进行实际通信。假设 Orders 服务向代理发送数据。每次更改 orders[orderId] 上的某些属性时,它都会在 /orders/:orderId 主题中发布更改。同时,暴露一个内部http点。每个服务缓存来自依赖的服务的数据。用户服务生成一个 GET /orders/:orderId ,同时向请求者发送响应,将数据放入本地缓存并订阅 orders/:orderId 主题。每次在此主题上发送“突变”时,用户服务都会捕获它并将突变应用于相应的缓存对象。通信同步,保持同步,管理相对简单;同时你的系统可以保存复制的数据并且仍然[最终]一致

【讨论】:

    【解决方案2】:

    我对此有一点不同的理解,因为它说服务之间的通信应该是异步的,而与 API 网关和 API 网关到服务的通信应该是 REST API。 所以我们不需要做任何事情,因为这些是简单的 API 调用,管道将处理请求-响应跟踪,而服务之间的异步调用将增加服务的吞吐量。

    【讨论】:

      【解决方案3】:

      现在,如果我理解正确的话,当用户请求 API 网关,然后它调用第一个服务时,它会返回一个确认(带有一些 GUID),该确认将被传递给客户端应用程序。但服务会继续执行请求。

      不,微服务不应该继续执行请求,它已经完成了。当远程数据发生变化时,他们将在需要时更新所需远程数据(来自执行请求的微服务的数据)的内部缓存(更准确地说是本地表示)。进行该更新的最佳方法是使用集成事件(即,当微服务执行更改数据的请求时,它会向订阅的微服务发布事件)。

      微服务不应该为了满足网关或客户端的请求而进行异步通信。他们应该使用后台任务提前准备好数据,以备有请求时使用。

      【讨论】:

      • 当我说“继续执行”时,我的意思是服务会通过中间件调用另一个服务。例如,客户端应用程序点击订单服务下订单,订单服务确认订单请求并返回响应(确认)。在内部,它通过将消息传递给库存服务来检查库存。因此,这是异步处理的。用户请求已得到处理。检查库存后,订单服务将确认订单。重点是,如何将此确认信息传达给客户?
      • @Pragmatic so,问题其实是“如何通知用户业务流程的状态变化?”
      • @Pragmatic 您可以向客户端返回一个 URL,它可以在其中轮询进程状态或使用客户端和 API 网关之间的服务器发送事件 (SSE)。
      • 这就是我的想法,提供一个 url(和一些 GUID)。想知道,我们是否可以自己通知应用程序,或者客户端是否可以在处理请求后公开我们都可以公开的任何 url。我想,调用客户端 Url(类似于 webhook)似乎是一个不错的选择,
      • @Pragmatic 您对“调用客户端网址”的确切含义是什么?
      猜你喜欢
      • 2020-02-06
      • 2017-10-10
      • 1970-01-01
      • 2019-09-12
      • 2020-02-02
      • 1970-01-01
      • 2016-03-27
      • 2022-06-18
      • 2020-02-29
      相关资源
      最近更新 更多