Lambda 函数即目标 - Elastic Load Balancing
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

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

Lambda 函数即目标

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

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

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

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

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

  • 不支持本地区域。

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

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

准备 Lambda 函数

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

调用 Lambda 函数的权限

如果使用 Amazon Web Services Management Console创建目标组并注册 Lambda 函数,控制台会代表您将所需的权限添加到 Lambda 函数策略。否则,在您使用 Amazon CLI 创建目标组并注册函数后,必须使用 add-permission 命令来向 Elastic Load Balancing 授予调用您的 Lambda 函数的权限。我们建议您使用 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 中包含该别名。有关更多信息,请参阅Amazon Lambda开发人员指南中的Amazon Lambda函数版本控制和别名以及使用别名的流量转移

函数超时

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

为 Lambda 函数创建目标组

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

New EC2 experience
使用新的 EC2 体验创建目标组并注册 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. 请选择 Next(下一步)

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

  10. 选择创建目标组

Old EC2 experience
使用旧有的 EC2 体验创建目标组并注册 Lambda 函数
  1. 通过以下网址打开 Amazon EC2 控制台:https://console.aws.amazon.com/ec2/

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

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

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

  5. 对于 Target type (目标类型),选择 Lambda function (Lambda 函数)

  6. 对于 Lambda function (Lambda 函数),请执行下列操作之一:

    • 选择 Lambda 函数

    • 创建新的 Lambda 函数并选择此函数

    • 创建目标组后注册 Lambda 函数

  7. (可选)要启用运行状况检查,请依次选择 Health check (运行状况检查)Enable (启用)

  8. 选择创建

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

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

从负载均衡器接收事件

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

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

如果 content-encoding 标头不存在,Base64 编码取决于内容类型。对于以下类型,负载均衡器按原样发送正文并将 isBase64Encoded 设置为 false:text/*、application/json、application/javascript 和 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 控制台,依次选择应用程序创建应用程序,然后从 Amazon Serverless Application Repository 中选择下列项目之一:

  • alb-Lambda-target-S UploadFileto

  • alb-lambda-targe 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 的目标组启用或禁用多值标头。

New EC2 experience
使用新的 EC2 体验启用多值标头
  1. 通过以下网址打开 Amazon EC2 控制台:https://console.aws.amazon.com/ec2/

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

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

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

  5. 选择或清除多值标头

  6. 选择保存更改

Old EC2 experience
使用旧有的 EC2 体验启用多值标头
  1. 通过以下网址打开 Amazon EC2 控制台:https://console.aws.amazon.com/ec2/

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

  3. 选择您的目标组。

  4. 说明选项卡上,选择编辑属性

  5. 对于 Multi value headers (多值标头),选择 Enable (启用)

  6. 选择保存

使用 Amazon 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 }
New EC2 experience
使用新的 EC2 体验为目标组启用运行状况检查
  1. 通过以下网址打开 Amazon EC2 控制台:https://console.aws.amazon.com/ec2/

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

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

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

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

  6. 选择保存更改

Old EC2 experience
使用旧有的 EC2 体验为目标组启用运行状况检查
  1. 通过以下网址打开 Amazon EC2 控制台:https://console.aws.amazon.com/ec2/

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

  3. 选择您的目标组。

  4. Health checks (运行状况检查) 选项卡上,选择 Edit health check (编辑运行状况检查)

  5. 对于 Health check (运行状况检查),选择 Enable (启用)

  6. 选择保存

使用 Amazon CLI 为目标组启用运行状况检查

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

注销 Lambda 函数

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

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

New EC2 experience
使用新的 EC2 体验取消注册 Lambda 函数
  1. 通过以下网址打开 Amazon EC2 控制台:https://console.aws.amazon.com/ec2/

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

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

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

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

Old EC2 experience
使用旧有的 EC2 体验取消注册 Lambda 函数
  1. 通过以下网址打开 Amazon EC2 控制台:https://console.aws.amazon.com/ec2/

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

  3. 选择您的目标组。

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

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

使用 Amazon CLI 取消注册 Lambda 函数

使用 deregister-targets 命令。