介绍 亚马逊云科技 Lambda 响应直播

作者: 朱利安·伍德 |

今天, 亚马逊云科技 L am bda 宣布支持响应负载流。响应流是一种新的调用模式,它允许函数逐步将响应有效负载流回客户端。

您可以使用 Lambda 响应负载流式传输在响应数据可用时将其发送给呼叫者。这可以提高 Web 和移动应用程序的性能。响应流还允许您构建返回更大有效载荷的函数,并在报告增量进度的同时执行长时间运行的操作。

在传统的请求-响应模型中,在将响应返回给客户端之前,需要完全生成和缓冲响应。这可能会在客户端等待响应生成时延 第一字节 时间 (TTFB) 性能。Web 应用程序对 TTFB 和页面加载性能特别敏感。响应流允许您在准备就绪时将部分响应发送回客户端,从而将 TTFB 延迟缩短到几毫秒以内。对于 Web 应用程序,这可以改善访客体验和搜索引擎排名。

其他应用程序可能具有较大的有效负载,例如图像、视频、大型文档或数据库结果。响应流允许您将这些有效负载传输回客户端,而不必将整个负载缓冲到内存中。您可以使用响应流发送大于 Lambda 的 6 MB 响应负载限制的响应,最大软限制为 20 MB。

响应流目前支持 Node.js 14.x 和后续的托管运行时。您还可以使用自定义运行时实现响应流。您可以通过 Lambda 函数网址(包括作为 亚马逊 CloudFront 源网址 )以及使用 亚马逊云科技 开发工具包或 Lambd a 的调用 API 逐步传输响应有效负载。您不能使用 Amazon API Gateway 应用程序负载均衡器 逐步传输响应负载,但您可以使用该功能通过 API Gateway 返回更大的有效负载。

编写支持响应流的函数

为响应流函数编写处理程序与典型的节点处理程序模式不同。要向运行时指示 Lambda 应该流式传输函数的响应,您必须使用 stre amify Response () 装饰器封装函数处理程序。 这告诉运行时使用正确的流逻辑路径,从而允许函数流式传输响应。

这是启用响应流的示例处理程序:

exports.handler = awslambda.streamifyResponse(
    async (event, responseStream, context) => {
        responseStream.setContentType(“text/plain”);
        responseStream.write(“Hello, world!”);
        responseStream.end();
    }
);

除了默认的节点处理 器参数、 事件和上下文外,Streamify Respon se 装饰器还接受以下附加参数 ResponseStream

新的 Res ponseStrea m 对象提供了一个流对象,您的函数可以向其写入数据。写入此流的数据会立即发送到客户端。您可以选择设置响应的 Content-Type 标头,以向您的客户端传递有关直播内容的更多元数据。

写入响应流

Resp onseStream 对象实现了节点 的可写 流 API。这提供了一个 write () 方法来向流写入信息。但是,我们建议您 尽可能使用 pipeline () 来写入流。这可以提高性能,确保更快的可读流不会压倒可写流。

使用 pip eline () 的示例函数 显示了如何流式传输压缩数据:

const pipeline = require("util").promisify(require("stream").pipeline);
const zlib = require('zlib');
const { Readable } = require('stream');

exports.gzip = awslambda.streamifyResponse(async (event, responseStream, _context) => {
    // As an example, convert event to a readable stream.
    const requestStream = Readable.from(Buffer.from(JSON.stringify(event)));
    
    await pipeline(requestStream, zlib.createGzip(), responseStream);
});

结束响应流

使用 w rite () 方法时,必须在处理程序返回之前结束流。使用 re sponseStream.end () 来表示你不再向数据流写入任何数据。如果您使用 pip eline () 向流写入数据,则不需要这样做

阅读直播回复

响应直播引入了新的 invo keWithResponse Stream API您可以通过 Lambda 函数 URL 从您的函数中读取流式响应,也可以使用 亚马逊云科技 开发工具包直接调用新 API。

API Gateway 和 Lambda 与应用程序负载均衡器的目标集成都不支持分块传输编码。因此,它不支持更快的 TTFB 进行流式响应。但是,您可以在 API Gateway 中使用响应流来返回更大的负载响应,最高可达 API Gateway 的 10 MB 上限。 要实现这一点,您必须在 API 网关和 Lambda 函数网址之间配置 HTTP_PROX Y 集成,而不是使用 LAMBDA_PROXY 集成。

您还可以使用函数 URL 作为源来配置 CloudFront。通过函数 URL 和 CloudFront 流式传输响应时,您可以获得更快的 TTFB 性能并返回更大的负载大小。

使用带有函数网址的 Lambda 响应流

您可以配置函数 URL 来调用您的函数,并通过分块传输编码将原始字节串流回您的 HTTP 客户端。 通过将函数网址的 调用模式从默认 BUFFERED 更改为 RESPONSE_STREAM,可以将函数网址配置为使用新的 invokeWithResponseStream API。

如果您使用 stream i fyResponse () 装饰器封装函数,RESPONSE_ STREAM 可以让您的函数在有效负载结果可用时对其进行流式 传输。 Lambda 使用 invokeWithResponseStream API 调用您的函数。 如果 inv okeWithResponseStream 调用未包含 stre amifyResponse () 的函数,则 Lambda 不会流式传输响应 。 但是,此响应受到 invokeWithResponseStream API 端点的 20MB 软限制,而不是 6 MB 的大小限制。

使用 亚马逊云科技 无服务器应用程序模型 (亚马逊云科技 SAM) 或 AW S CloudFormation,设置 invokeMode 属性

  MyFunctionUrl:
    Type: AWS::Lambda::Url
    Properties:
      TargetFunctionArn: !Ref StreamingFunction
      AuthType: AWS_IAM
      InvokeMode: RESPONSE_STREAM

使用带有函数 URL 的通用 HTTP 客户端库

每种语言或框架可能使用不同的方法来形成 HTTP 请求并解析流式响应。有些 HTTP 客户端库仅在服务器关闭连接后才返回响应正文。这些客户端不使用返回响应流的函数。要获得响应流的好处,请使用递增返回响应数据的 HTTP 客户端。 许多 HTTP 客户端库已经支持流式响应,包括 适用于 Java 的 Apache H ttpClient 、Node 的内置 htt p 客户端以及 Python 的 请求 和 urllib3 包。 请查阅您正在使用的 HTTP 库的文档。

示例应用程序

无服务器 模式集合中有许多示例 Lambda 流式传输应用程序。 他们使用 亚马逊云科技 SAM 在您的 亚马逊云科技 账户中构建和部署资源。

克隆存储库并浏览示例。每个模式文件夹中的 README 文件都包含其他信息。

git clone https://github.com/aws-samples/serverless-patterns/ 
cd serverless-patterns

使用 write () 转到第一个字节的时间

  1. 要展示直播如何缩短第一口的时间,请部署 lambda-stre aming-ttfb- write-sam 模式。
  2. cd lambda-streaming-ttfb-write-sam
  3. 使用 亚马逊云科技 SAM 将资源部署到您的 亚马逊云科技 账户。运行引导式部署以设置首次部署的默认参数。
  4. sam deploy -g --stack-name lambda-streaming-ttfb-write-sam

    对于后续部署,你可以使用 sam deploy

  5. 输入堆 栈名称 并接受初始默认值。
  6. 亚马逊云科技 SAM 部署了一个支持流媒体和函数 URL 的 Lambda 函数。

    AWS SAM deploy --g

    亚马逊云科技 SAM 部署 —g

    部署完成后,亚马逊云科技 SAM 会提供资源的详细信息。

    AWS SAM resources

    亚马逊云科技 SAM 资源

    亚马逊云科技 SAM 的输出返回一个 Lambda 函数网址。

  7. curl 与您的 亚马逊云科技 证书一起使用来查看直播响应,因为该网址使用 亚马逊云科技 身份和访问管理 (IAM) 进行 授权。替换部署的 URL 和区域参数。
curl --request GET https://<url>.lambda-url.<Region>.on.aws/ --user AKIAIOSFODNN7EXAMPLE:wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY --aws-sigv4 'aws:amz:<Region>:lambda'

你可以看到流媒体响应的逐渐显示。

Using curl to stream response from write () function

使用 curl 流式传输来自 write () 函数的响应

使用 pipeline () 转换第一个字节的时间

  1. 要尝试使用 pip eline () 的示例 ,请部署 lambda-stre aming-ttfb- pipeline-sam 模式。
  2. cd ..
    cd lambda-streaming-ttfb-pipeline-sam
  3. 使用 亚马逊云科技 SAM 将资源部署到您的 亚马逊云科技 账户。运行引导式部署以设置首次部署的默认参数。
  4. sam deploy -g --stack-name lambda-streaming-ttfb-pipeline-sam
  5. 输入堆 栈名称 并接受初始默认值。
  6. 使用 带有 亚马逊云科技 证书的 curl 来查看直播响应。替换部署的 URL 和区域参数。
curl --request GET https://<url>.lambda-url.<Region>.on.aws/ --user AKIAIOSFODNN7EXAMPLE:wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY --aws-sigv4 'aws:amz:<Region>:lambda'

你可以看到返回的管道响应流。

Using curl to stream response from function

使用 curl 流式传输来自函数的响应

大型有效载荷

  1. 要展示流式传输如何使您能够返回更大的有效负载,请部署 lambda-stream ing-large-sam 应用程序。亚马逊云科技 SAM 部署了一个 Lambda 函数,该函数返回一个 7 MB 的 PDF 文件,该文件大于 Lambda 的非流式 6 MB 响应负载限制。
  2. cd ..
    cd lambda-streaming-large-sam
    sam deploy -g --stack-name lambda-streaming-large-sam
  3. 亚马逊云科技 SAM 的输出返回一个 Lambda 函数网址。使用 带有 亚马逊云科技 证书的 curl 来查看直播响应。
curl --request GET https://<url>.lambda-url.<Region>.on.aws/ --user AKIAIOSFODNN7EXAMPLE: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY --aws-sigv4 'aws:amz:<Region>:lambda' -o SVS401-ri22.pdf -w '%{content_type}'

这会将 PDF 文件 SVS401-ri22.pdf 下载 到您的当前目录,并将内容类型显示为 应用程序/ pdf。

您还可以使用 API 网关返回与 Lambda 函数 URL 集成 HTTP_PROXY 的大型负载。

使用 亚马逊云科技 开发工具包调用带有响应流的函数

您可以使用 亚马逊云科技 开发工具包直接流式传输来自新的 Lambda inv okeWithResponseStream API 的响应。这提供了其他功能,例如处理中游错误。例如,在构建内部微服务时,这可能很有用。适用于 Java 的 亚马逊云科技 开发工具包 2.x 、适用于 Java S cript v3 的 亚马逊云科技 开发工具包 以及适用于 Go 的 亚马逊云科技 开发工具包 版本 1 和 版本 2 支持响应流。

SDK 响应会返回一个事件流,您可以从中读取。事件流包含两种事件类型。 PayloadChunk 包含原始二进制缓冲区,其中包含客户端收到的部分响应数据。 invokeCompl ete 表示该函数已完成数据的发送。它还包含其他元数据,例如函数在流中间是否遇到错误。错误可能包括函数代码引发的未处理异常和函数超时。

使用适用于 JavaScript 的 亚马逊云科技

  1. 要了解如何使用 亚马逊云科技 开发工具包流式传输来自函数的响应,请部署 lambda-stream ing-sam 模式。
  2. cd ..
    cd lambda-streaming-sdk-sam
    sam deploy -g --stack-name lambda-streaming-sdk-sam
  3. 输入堆 栈名称 并接受初始默认值。
  4. 亚马逊云科技 SAM 部署了三个支持流媒体的 Lambda 函数。

  • HappyPathFunction :返回完整直播。
  • midstreamerRorFunction :模拟 中游错误。
  • 超时功能 :函数 在流完成之前超时。
  • 运行 SDK 示例应用程序,该应用程序调用每个 Lambda 函数并输出结果。
  • npm install @aws-sdk/client-lambda
    node index.mjs

    您可以看到每个函数以及如何将中游和超时错误返回到 SDK 客户端。

    Streaming midstream error

    直播中游错误

    Streaming timeout error

    直播超时错误

    配额和定价

    流式响应会产生响应负载的网络传输的额外费用。根据您的 Lambda 函数在前 6 MB 内生成和流式传输的字节数向您收费。有关更多信息,请参阅 Lambda 定价。

    初始最大响应大小为 20 MB,这是一个可以提高的软限制。响应负载的前 6MB 在没有任何带宽限制的情况下进行流式传输。超过 6MB,最大带宽吞吐量限制为 16 Mbps(2 Mb/s)。

    结论

    今天, 亚马逊云科技 L ambda 宣布支持响应负载流,以便在响应可用时向呼叫者发送部分响应。这可以提高 Web 和移动应用程序的性能。您还可以使用响应流来构建函数,这些函数可以返回更大的有效负载,并在报告增量进度的同时执行长时间运行的操作。通过 Lambda 函数 URL 或使用 亚马逊云科技 开发工具包流式传输部分响应。响应流目前支持 Node.js 14.x 和后续运行时以及自定义运行时。

    无服务器模式集合 中有许多示例 Lambda 流媒体应用程序 可供探索这些功能。

    许多 亚马逊云科技 Lambda 合作伙伴也提供 Lam bda 响应流支持,例如 D atadog 、D yn atrace、New Reli c Pulumi 和 L umigo。

    如需更多无服务器学习资源,请访问 无服务器世界


    *前述特定亚马逊云科技生成式人工智能相关的服务仅在亚马逊云科技海外区域可用,亚马逊云科技中国仅为帮助您发展海外业务和/或了解行业前沿技术选择推荐该服务。