【发布时间】:2017-01-18 10:29:44
【问题描述】:
我正在构建一个无服务器网络跟踪系统,该系统使用 AWS API Gateway 为其跟踪像素提供服务,该网关在跟踪请求到达时调用 Lambda 函数将跟踪事件写入 Kinesis 流。
Lambda 函数本身并没有做任何花哨的事情。它只是接受传入事件(它自己的参数)并将其写入流。本质上,它只是:
import boto3
kinesis_client = boto3.client("kinesis")
kinesis_stream = "my_stream_name"
def return_tracking_pixel(event, context):
...
new_record = ...(event)
kinesis_client.put_record(
StreamName=kinesis_stream,
Data=new_record,
PartitionKey=...
)
return ...
有时我会在 Lambda 执行持续时间中遇到一个奇怪的峰值,这会导致我的一些 Lambda 函数调用超时并丢失跟踪请求。
这是受影响时间段内 Lambda 函数的 1 分钟调用计数图表:
在 20:50 和 23:10 之间我突然看到很多调用错误(1 分钟错误计数):
这显然是由 Lambda 执行超时引起的(最大持续时间以 1 分钟为间隔):
我的 Kinesis 流(数据输入、放置记录的数量、put_record 成功计数等,一切看起来都正常)和我的 API GW(调用次数对应于 API GW 的数量)都没有什么奇怪的调用,完全在 API GW 的限制范围内)。
什么可能导致 Lambda 函数执行持续时间突然(并且看似随机发生)峰值?
编辑:lambda 函数都没有被限制,这是我的第一个想法。
【问题讨论】:
-
这个函数记录了什么有趣的事情?在你的代码中加入一些不必要的日志,至少可以帮助你证明函数到达的点。如果在 VPC 中并且分配了多个子网,则其中一个子网可能配置错误并且无法访问 Kinesis。将超时时间(暂时)增加到最大值可能会让您记录当前未引发的实际错误、异常、堆栈跟踪等,因为平台使您的执行超时的速度快于引发错误的速度。
-
@Michael-sqlbot 我会尝试记录更多,但整个函数实际上只有大约 5 行代码......其中发生的仅有的两个复杂操作是
kinesis_client = boto3.client("kinesis")和kinesis_client.put_record(...)...我真的无法避免这些,可以吗? -
您说得对,它看起来确实非常简单明了,但是准确地确定您的代码通过这几个步骤取得了多少进展至关重要。如果
put_record()调用发生超时或重试,您需要知道它实际上开始尝试,并且您需要更多运行时间来让请求真正失败而不是被 Lambda 超时终止。 -
我同意您应该在函数中添加一些日志记录,以隔离函数中的任何潜在问题。此外,Lambda 冷启动行为可能会出现临时峰值,但这对于接收一致流量的 API 来说应该可以忽略不计。
-
还有其他人在写 kinesis 流吗?您是否有可能达到某种限制,您需要增加流上的分片数量?
标签: amazon-web-services aws-lambda aws-api-gateway amazon-kinesis