使用 Lambda 函数作为应用程序负载均衡器的目标 - Elastic Load Balancing

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

使用 Lambda 函数作为应用程序负载均衡器的目标

您可以将 Lambda 函数注册为目标并将侦听器规则配置为将请求转发到 Lambda 函数的目标组。当负载均衡器将请求转发给以 Lambda 函数为目标的目标组时,它会调用您的 Lambda 函数并将请求内容以格式传递给 Lambda 函数。JSON

限制
  • Lambda 函数和目标组必须位于同一账户中,且位于同一区域中。

  • 您可以发送到 Lambda 函数的请求正文的最大大小为 1 MB。有关相关的大小限制,请参阅HTTP标题限制

  • Lambda 函数可以发送的最大响应JSON大小为 1 MB。

  • WebSockets 不支持。升级请求被拒绝,代码为 HTTP 400。

  • 不支持本地区域。

  • 不支持自动目标权重 (ATW)。

有关演示,请参阅 Application Load Balancer 上的 Lambda 目标

准备 Lambda 函数

如果您将 Lambda 函数与 Application Load Balancer 一起使用,则以下建议适用。

调用 Lambda 函数的权限

如果使用 AWS Management Console创建目标组并注册 Lambda 函数,控制台会代表您将所需的权限添加到 Lambda 函数策略。否则,在创建目标组并使用注册函数后,必须使用添加权限命令授予 Elastic Load Balancing 调用您的 Lambda 函数的权限。 AWS CLI我们建议您使用 aws:SourceAccountaws:SourceArn 条件键限制对指定目标组的函数调用。有关更多信息,请参阅IAM用户指南》中的副手困惑问题

aws lambda add-permission \ --function-name lambda-function-arn-with-alias-name \ --statement-id elb1 \ --principal elasticloadbalancing.amazonaws.com \ --action lambda:InvokeFunction \ --source-arn target-group-arn \ --source-account target-group-account-id
Lambda 函数版本控制

您可以为每个目标组注册一个 Lambda 函数。为确保您可以更改您的 Lambda 函数并且负载均衡器始终调用当前版本的 Lambda 函数,请在向负载均衡器注册 Lambda 函数时ARN创建函数别名并在函数中包含该别名。有关更多信息,请参阅AWS Lambda 开发人员指南中的AWS Lambda 函数版本控制和别名以及使用别名的流量转移

函数超时

负载均衡器会一直等待,直到您的 Lambda 函数响应或超时。建议您根据预期运行时间配置 Lambda 函数的超时。有关默认超时值以及如何更改该值的信息,请参阅基本 AWS Lambda 函数配置。有关可配置的最大超时值的信息,请参阅 AWS Lambda 限制

为 Lambda 函数创建目标组

创建一个要在请求路由中使用的目标组。如果请求内容与侦听器规则匹配并且具有将该内容转发到此目标组的操作,则负载均衡器会调用已注册的 Lambda 函数。

要使用控制台创建目标组并注册 Lambda 函数
  1. 打开 Amazon EC2 控制台,网址为https://console.aws.amazon.com/ec2/

  2. 在导航窗格上的 Load Balancing (负载均衡) 下,选择 Target Groups (目标组)。

  3. 选择 Create target group (创建目标组)

  4. 对于选择目标类型,选择 Lambda 函数

  5. 对于 Target group name,键入目标组的名称。

  6. (可选)要启用运行状况检查,请在 Health checks(运行状况检查)部分中选择 Enable(启用)。

  7. (可选) 添加一个或多个标签,如下所示:

    1. 展开标签部分。

    2. 选择 Add tag (添加标签)

    3. 输入标签键和标签值。

  8. 选择下一步

  9. 指定单个 Lambda 函数,或者忽略此步骤并在以后指定 Lambda 函数。

  10. 选择创建目标组

使用 AWS CLI创建目标组并注册 Lambda 函数

使用create-target-group注册目标命令

从负载均衡器接收事件

负载均衡器支持通过和对请求进行 Lambda 调用。HTTP HTTPS负载均衡器以JSON格式发送事件。负载均衡器将以下标头添加到每个请求:X-Amzn-Trace-IdX-Forwarded-ForX-Forwarded-PortX-Forwarded-Proto

如果 content-encoding 标头存在,负载均衡器会对正文进行 Base64 编码并将 isBase64Encoded 设置为 true

如果 content-encoding 标头不存在,Base64 编码取决于内容类型。对于以下类型,负载均衡器按原样发送正文并将其设置isBase64Encodedfalse:text/*,。application/json, application/javascript, and application/xml否则,负载均衡器会对正文进行 Base64 编码并将 isBase64Encoded 设置为 true

以下是示例事件。

{ "requestContext": { "elb": { "targetGroupArn": "arn:aws:elasticloadbalancing:region:123456789012:targetgroup/my-target-group/6d0ecf831eec9f09" } }, "httpMethod": "GET", "path": "/", "queryStringParameters": {parameters}, "headers": { "accept": "text/html,application/xhtml+xml", "accept-language": "en-US,en;q=0.8", "content-type": "text/plain", "cookie": "cookies", "host": "lambda-846800462-us-east-2.elb.amazonaws.com", "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6)", "x-amzn-trace-id": "Root=1-5bdb40ca-556d8b0c50dc66f0511bf520", "x-forwarded-for": "72.21.198.66", "x-forwarded-port": "443", "x-forwarded-proto": "https" }, "isBase64Encoded": false, "body": "request_body" }

响应负载均衡器

来自 Lambda 函数的响应必须包含 Base64 编码状态、状态代码和标头。您可以省略正文。

要在响应的正文中包含二进制内容,您必须对内容进行 Base64 编码并将 isBase64Encoded 设置为 true。负载均衡器对内容进行解码以检索二进制内容,并在HTTP响应正文中将其发送给客户端。

负载均衡器不支持 hop-by-hop标头,例如ConnectionTransfer-Encoding。您可以省略 Content-Length 标头,因为负载均衡器会在将响应发送到客户端之前计算它。

以下是来自基于 nodejs 的 Lambda 函数的示例响应。

{ "isBase64Encoded": false, "statusCode": 200, "statusDescription": "200 OK", "headers": { "Set-cookie": "cookies", "Content-Type": "application/json" }, "body": "Hello from Lambda (optional)" }

有关与应用程序负载均衡器配合使用的 Lambda 函数模板,请参阅 github 上的 application-load-balancer-serverless- app。或者,打开 Lambda 控制台,依次选择应用程序创建应用程序,然后从  AWS Serverless Application Repository 中选择下列项目之一:

  • ALB-Lambda-Target-UploadFileto

  • ALB-Lambda Target BinaryResponse

  • ALB-Lambda-Target-IP WhatisMy

多值标头

如果来自客户端的请求或来自 Lambda 函数的响应包含具有多个值的标头或多次包含同一标头,或包含同一键具有多个值的查询参数,则可启用对多值标头语法的支持。启用多值标头后,负载均衡器和 Lambda 函数之间交换的标头和查询参数将使用数组而不是字符串。如果您没有启用多值标头语法,并且标头或查询参数具有多个值,则负载均衡器将使用其收到的最后一个值。

包含多值标头的请求

用于标头和查询字符串参数的字段名称根据是否为目标组启用了多值标头而有所不同。

以下示例请求具有两个查询参数和同一个键:

http://www.example.com?&myKey=val1&myKey=val2

对于默认格式,负载均衡器将使用客户端发送的最后一个值,并使用 queryStringParameters 向您发送包含查询字符串参数的事件。例如:

"queryStringParameters": { "myKey": "val2"},

如果启用了多值标头,则负载平衡器将使用客户端发送的两个键值,并使用 multiValueQueryStringParameters 向您发送包含查询字符串参数的事件。例如:

"multiValueQueryStringParameters": { "myKey": ["val1", "val2"] },

同样,假设客户端发送标头中包含两个 Cookie 的请求:

"cookie": "name1=value1", "cookie": "name2=value2",

对于默认格式,负载均衡器将使用客户端发送的最后一个 Cookie,并使用 headers 向您发送包含标头的事件。例如:

"headers": { "cookie": "name2=value2", ... },

如果启用了多值标头,负载均衡器将使用客户端发送的两个 Cookie 并使用 multiValueHeaders 向您发送包含标头的事件。例如:

"multiValueHeaders": { "cookie": ["name1=value1", "name2=value2"], ... },

如果查询参数是 URL-编码的,则负载均衡器不会对其进行解码。您必须在 Lambda 函数中对它们进行解码。

包含多值标头的响应

用于标头的字段名称根据是否为目标组启用了多值标头而有所不同。如果启用了多值标头,则必须使用 multiValueHeaders,否则使用 headers

对于默认格式,您可以指定单个 Cookie:

{ "headers": { "Set-cookie": "cookie-name=cookie-value;Domain=myweb.com;Secure;HttpOnly", "Content-Type": "application/json" }, }

如果启用了多值标头,您必须指定多个 Cookie,如下所示:

{ "multiValueHeaders": { "Set-cookie": ["cookie-name=cookie-value;Domain=myweb.com;Secure;HttpOnly","cookie-name=cookie-value;Expires=May 8, 2019"], "Content-Type": ["application/json"] }, }

负载均衡器向客户端发送标头时所遵循的顺序可能与 Lambda 响应负载中指定的顺序不同。因此,不要指望按特定顺序返回标头。

启用多值标头

您可以对目标类型为 lambda 的目标组启用或禁用多值标头。

使用控制台启用多值标头
  1. 打开 Amazon EC2 控制台,网址为https://console.aws.amazon.com/ec2/

  2. 在导航窗格上的负载均衡下,选择目标组

  3. 选择目标组的名称以打开其详细信息页面。

  4. 组详细信息选项卡的属性部分中,选择编辑

  5. 选择或清除多值标头

  6. 选择 Save changes(保存更改)

要启用多值标头,请使用 AWS CLI

使用带有lambda.multi_value_headers.enabled属性的modify-target-group-attributes命令。

启用运行状况检查

默认情况下,对类型为 lambda 的目标组禁用运行状况检查。您可以启用运行状况检查,以便使用 Amazon Route 53 实现DNS故障转移。Lambda 函数可以在响应运行状况检查请求之前检查下游服务的运行状况。如果来自 Lambda 函数的响应指示运行状况检查失败,则运行状况检查失败会传递到 Route 53。您可以将 Route 53 配置为故障转移到备份应用程序堆栈。

您需要支付运行状况检查的费用,就像您支付任何 Lambda 函数调用的费用一样。

以下是发送到您的 Lambda 函数的运行状况检查事件的格式。要检查事件是否为运行状况检查事件,请检查 user-agent 字段的值。运行状况检查的用户代理为 ELB-HealthChecker/2.0

{ "requestContext": { "elb": { "targetGroupArn": "arn:aws:elasticloadbalancing:region:123456789012:targetgroup/my-target-group/6d0ecf831eec9f09" } }, "httpMethod": "GET", "path": "/", "queryStringParameters": {}, "headers": { "user-agent": "ELB-HealthChecker/2.0" }, "body": "", "isBase64Encoded": false }
使用控制台为目标组启用运行状况检查
  1. 打开 Amazon EC2 控制台,网址为https://console.aws.amazon.com/ec2/

  2. 在导航窗格上的负载均衡下,选择目标组

  3. 选择目标组的名称以打开其详细信息页面。

  4. 组详细信息选项卡的运行状况检查设置部分中,选择编辑

  5. 对于运行状况检查,选择启用

  6. 选择 Save changes(保存更改)

要为目标群体启用健康检查,请使用 AWS CLI

使用带--health-check-enabled选项的modify-target-group命令。

注销 Lambda 函数

如果您不再需要向您的 Lambda 函数发送流量,则可以将其取消注册。注销 Lambda 函数后,正在进行的请求会失败HTTP,并出现 5XX 错误。

要替换 Lambda 函数,建议您创建新的目标组,向新目标组注册新函数,并将侦听器规则更新为使用新目标组而不是现有目标组。

使用控制台取消注册 Lambda 函数
  1. 打开 Amazon EC2 控制台,网址为https://console.aws.amazon.com/ec2/

  2. 在导航窗格上的负载均衡下,选择目标组

  3. 选择目标组的名称以打开其详细信息页面。

  4. Targets (目标) 选项卡上,选择 Deregister (取消注册)

  5. 当系统提示您确认时,选择 Deregister (取消注册)

要取消注册 Lambda 函数,请使用 AWS CLI

使用 deregister-targets 命令。