有状态异步调用可以实时感知业务状态、控制执行函数,让您对一些异常情况进行更好的处理,例如报警通知、自动化重试等情况。本文介绍函数计算有状态异步调用的最佳实践。

背景信息

FaaS早期主要支持无状态、短时和轻量级的计算能力,例如API后端、图片处理和数据流式处理等。在各类场景中,对于FaaS函数的调用方式可分为异步调用和同步调用。同步调用和异步调用存在的差异是同步调用会立即执行函数,而异步调用则会立刻返回调用方202 HttpCode,并将异步调用消息入队,由后端服务排队处理。

使用场景

随着业务的发展,一些在线直播场景的用户在慢慢迁移至FaaS内,这类业务场景通常具有执行时间长、对延时敏感和可用性要求高等特征,开发人员需实时感知业务状态和控制函数的执行。由于异步调用对延时不敏感,同步调用长链接的稳定性比较差,并且占用客户端资源,所以既无法使用异步调用也无法使用同步调用。但由于异步调用在大量突增流量的离线业务下,具有削峰填谷的特点,可以平滑缓冲对业务下游系统的缓冲,所以函数计算对异步调用进行相关拓展,引入有状态异步调用。有状态异步调用适用于以下业务场景:
  • 对执行具有可观测性
    • 在执行过程中您可以实时查看执行的状态,例如是否已出队、是否已触发函数执行和执行结果是否已正常发送Destination目标。
    • 业务具有明显的任务属性,如下所示:
      • 可以查看某个执行的触发事件和实时的执行日志。
      • 可以根据执行的名称、执行的时间或执行的状态等过滤查询历史记录。
  • 对执行具有可操作性
    业务具有明显的任务类属性,如下所示:
    • 当执行时间较长时,可以在一些情况下能够手动停止执行函数。
    • 可以重新执行历史失败或成功的执行。

关于有状态异步调用的详细信息,请参见函数调用概述

示例

本文以异步调用目标MNS队列为例,介绍如何结合使用Funcraft工具和函数计算控制台实现异步调用。

您可以通过有状态异步调用实现以下效果:
  • 函数开始异步执行后,您可以通过函数计算控制台、SDK或API查看操作执行。
  • 当函数执行失败或手动停止后,函数计算系统会将异步消息推送至MNS队列中实现死信队列的功能,方便您感知异步函数执行失败的消息并进行后续处理。

操作步骤

  1. 创建MNS队列,例如创建的队列名称为stateful-invocation-dlq。详细信息,请参见创建队列
  2. 执行以下命令克隆项目工程。
    git clone https://github.com/awesome-fc/Stateful-Async-Invocation.git
  3. 修改template.yml文件,将文件内的{please_replace_me}替换为实际队列的名称。
  4. 在目标目录中执行以下命令部署函数。
    fun deploy --use-ros --stack-name demo-1
    部署成功后,您可以登录函数计算控制台,查看是否成功创建函数和是否成功开启有状态异步调用。

更多信息

  • 异步配置仅在异步调用时才会成功生效。您可以通过SDK或CLI工具发送异步调用请求。
    本示例中您可以在示例工程的目标目录中执行以下命令发送异步触发请求,并查看消息队列MNS。
    invk main -t Async -s '{"failure":true}'
  • 您可以在函数计算控制台查看、操作异步调用。
    • 查看异步调用配置情况。
    • 查看异步调用执行状态。
    • 停止进行中的异步调用。
    • 查看历史执行列表和某具体执行的结果信息。
    • 复制payload。
    • 重新触发异步调用。
    说明 如果您需要查看详细信息例如函数日志,您需要为函数配置日志服务。详细信息,请参见配置并查看函数日志
  • 当函数执行完成后,如已配置了Destination目标,则可前往目标查看推送记录。
    本文示例中,如果配置了Destination目标,您可以在MNS控制台接收Destination推送的信息,如下所示。
    {
      "timestamp":xxxx,
      "requestContext":{
        "requestId":"xxxx",
        "functionArn":"acs:fc:::services/Stateful-Invocation-demo.LATEST/functions/main",
        "condition":"UnhandledInvocationError",
        "approximateInvokeCount":1
      },
      "requestPayload":"{\"failure\":true}",
      "responseContext":{
        "statusCode":200,
        "functionError":"UnhandledInvocationError"
      },
      "responsePayload":"{\"errorMessage\":\"Process exited unexpectedly before completing request (duration: 13689ms, maxMemoryUsage: 10.86MB)\"}"
    }
     
    说明 当异步调用失败或手动终止后,您可以在消息服务MNS中接收到异步调用时间的详细错误信息。