云架构(四)异步请求-应答模式

Asynchronous Request-Reply pattern - Azure Architecture Center | Microsoft Learn

把后台处理和前端解耦,后台处理需要异步处理,但是也需要给前端一个清晰的回应。

背景和问题 

  1. 在现代应用开发中,代码通常在浏览器中运行,依赖于远程API接口提供的业务逻辑和功能。这些API直接与应用程序有关,或者是第三方提供的共享服务。通常这些API调用通过HTTP(S)协议调用,并且遵循REST语义。
  2. 大多情况下,客户端应用程序的API被设计为快速响应,100ms甚至更少。许多因素会造成响应延迟,包括:
    1. 应用的主机堆栈
    2. 安全组件
    3. 调用者和后台的相对物理位置
    4. 网络基础设施
    5. 当前负荷
    6. 请求有效负荷大小
    7. 处理队列长度
    8. 后台处理时间
  3. 任何一个因素都可以增加系统延迟。有一些可以通过扩展后台来缓解。其他的例如网络设施,已经超出了应用程序开发者的控制。大部分API可以很快的响应,以便通过同一连接返回。程序代码可以通过非阻塞的方式制作一个异步API请求,提供异步处理外观,这被推荐在IO操作上使用。
  4. 有时候,后台完成需要很长时间运行,在秒级之上,甚至可能需要执行几分钟或者几个小时。这种情况下,让请求等待完成响应是不可行的。这是任何同步请求-应答模式的潜在问题。
  5. 一些架构解决这个问题通过使用消息中间件来分开请求和响应阶段。这种分离通常使用Queue-Based Load Leveling pattern实现。这种分离可以允许客户端进程和后台API独立扩展。但是这种分离也带来了额外的复杂性,当客户端需要成功的通知,这一步需要是异步的。
  6. 针对客户机应用程序讨论的许多相同注意事项,也适用于分布式系统中的服务器到服务器REST API调用,例如,在微服务体系结构中。

解决办法 

  1. 这个问题的一个思路是使用HTTP轮询,轮询是在客户端代码使用,因为很难提供回调端点或使用长时间运行的连接。尽管回调可能能做到,但是需要额外的库和服务有时也会增加额外的复杂性。
    1. 客户端程序调用一个同步请求API,触发了后台上长时间运行的操作。
    2. API同步尽可能的快速响应。返回一个HTTP202(已接收)的状态码,确认这个请求已经被接收处理。
      1. 在开始长时间运行操作前,API应该校验请求和执行动作。如果请求是无效的,立即回应错误代码例如HTTP400(错误请求)。
    3. 响应持有本地引用指向终端,所以客户端可以轮询检查长时间运行操作的结果。
    4. API将处理工作转移给另一个组件,比如消息队列。
    5. 对于每个成功请求,状态终端会返回HTPP200。当工作还在待处理时,状态终端返回一个资源,表明工作还在处理中。一旦工作完成,状态终端要么返回一个表明完成的资源,要么跳转去另一个资源URL。例如,如果异步操作创建了一个新资源,状态终端会跳转到该资源的URL。
  2. 下面的图表展示了一个典型的流程:

 问题和考虑

  1. 有许多可能的方法可以通过HTTP实现此模式,但并不是所有的上游服务都具有相同的语义。例如,当远程请求尚未完成时,大多数服务不会从GET方法返回HTTP 202响应。遵循纯REST语义,它们应该返回HTTP 404(未找到)。当您考虑到调用的结果尚未出现时,此响应是有意义的。
  2. HTTP 202响应应该指明客户端应该轮询响应的位置和频率。它应该有以下额外的响应头:
    1. Location : 客户端应该轮询响应状态的URL。
    2. Retry-After:对处理完成时间的估计。
  3. 根据所使用的底层服务,您可能需要使用处理代理或facade来操作响应头或有效负载。
  4. 如果状态端点在完成时重定向,则HTTP 302或HTTP 303是适当的返回码,具体取决于您支持的确切语义。
  5. 成功处理后,Location标头指定的资源应该返回适当的HTTP响应代码,例如200 (OK)、201(创建)或204(无内容)。
  6. 如果在处理过程中发生错误,将错误保存在Location标头中描述的资源URL中,并理想地从该资源向客户端返回适当的响应代码(4xx代码)。
  7. 并不是所有的解决方案都以同样的方式实现这个模式,有些服务将包含额外的或备用的头。例如,Azure资源管理器使用此模式的修改版本。详情查看:https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/async-operations。
  8. 历史客户端不一定支持这个模式。在这种情况下,您可能需要在异步API上放置一个facade,以便对原始客户机隐藏异步处理。例如,Azure逻辑应用程序原生支持这种模式,可以用作异步API和进行同步调用的客户端之间的集成层。详情查看:https://learn.microsoft.com/en-us/azure/logic-apps/logic-apps-create-api-app#perform-long-running-tasks-with-the-webhook-action-pattern。
  9. 在有些场景下,你可能想要提供一个客户端可以取消长时间运行请求的方式。这样的话,后台服务必须支持某种形式的取消指令。

什么时候使用 

  1. 客户端代码(例如浏览器应用)这些难以提供回调的终端,或者使用长连接增加了很多的额外的复杂性。
  2. 只允许HTTP协议调用服务,并且因为客户端的防火墙限制导致服务不可以回调。
  3. 服务调用需要适配不支持回调技术的遗留架构,例如WebSockets or webhooks。

不适用 

  1. 你可以使用为异步通知构建的服务,例如Azure Event Grid。
  2. 响应必须实时返回给客户端。
  3. 客户端需要收集很多结果,这些结果的接收延迟很重要。可以考虑使用服务总线模式。
  4. 网络设计允许你开启端口来接收异步回调或webhook。

 

欢迎大家留言沟通 

相关推荐

  1. 微软架构设计模式--前言

    2024-04-13 05:34:04       34 阅读
  2. js的异步请求

    2024-04-13 05:34:04       28 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-13 05:34:04       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-13 05:34:04       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-13 05:34:04       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-13 05:34:04       20 阅读

热门阅读

  1. Photoshop小记

    2024-04-13 05:34:04       18 阅读
  2. CentOS版本不同大小的各个版本区别

    2024-04-13 05:34:04       17 阅读
  3. Igh related:Small Bug And Notes Record.

    2024-04-13 05:34:04       17 阅读
  4. OpenCV C++ 学习笔记(一)

    2024-04-13 05:34:04       17 阅读
  5. C 共用体

    2024-04-13 05:34:04       16 阅读
  6. 常见的分类算法及其应用场景

    2024-04-13 05:34:04       16 阅读
  7. 数据仓库—ETL工具与技术:数据仓库的坚实基石

    2024-04-13 05:34:04       17 阅读
  8. 8266 Ubuntu下 arduino开发

    2024-04-13 05:34:04       13 阅读
  9. Promise学习笔记

    2024-04-13 05:34:04       13 阅读