AWS Lambda - 主体尺寸太大错误,但主体尺寸低于限制

Joh*_*ohn 6 rest amazon-web-services python-2.7 aws-lambda

我正在使用 lambda 函数来服务 REST API。在一个端点中,我将“body size is too long”打印到 cloudwatch 日志中。

我从该函数得到的响应是带有响应正文的状态代码 502 { "message": "Internal server error" }。如果我调用相同的端点但使用过滤器,则响应正文大小为 2.26MB 并且有效。这排除了我达到异步响应正文限制的情况。

出错时的响应正文大小为 5622338 字节 (5.36 MB)。

这就是我计算响应大小的方式(python 2.7):

import urllib2
...

out = {}
resp = urllib2.urlopen(req)
out.statusCode = resp.getcode()
out.body = resp.read()
print("num bytes: " + str(len(bytearray(out.body, 'utf-8'))))
Run Code Online (Sandbox Code Playgroud)

公布的同步调用最大响应正文大小为 6MB。据我了解,我不应该收到错误。 https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-limits.html

其他信息:

持续时间:22809.11 毫秒 计费持续时间:22810 毫秒 内存大小:138 MB 最大已用内存:129 MB 初始化持续时间:1322.71 毫秒

任何帮助,将不胜感激。


21 年 4 月 22 日更新

经过进一步研究,我发现如果响应的大小为 1,048,574 字节 (0.999998 MB) 或更大,则 lambda 函数会出错。

如果响应为 1,048,573 字节 (0.999997 MB) 或更少,则可以正常工作。

这就是我返回回复的方式。我对视图函数进行硬编码以返回bytearray特定大小的视图。前任。

return bytearray(1048573)
Run Code Online (Sandbox Code Playgroud)

我打开了正在使用的 AWS Gateway Stage 的日志记录,并且以下错误被写入日志。这意味着该函数出错了。不是函数的调用:由于客户函数错误,Lambda 执行失败,状态为 200:主体大小太长。

据我了解,AWS Lambda 函数的最大响应大小为 6MB,AWS 网关的最大响应大小为 10MB。

AWS Lambda:调用有效负载响应 https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-limits.html

API Gateway:用于配置和运行 REST API 的 API Gateway 配额 -> 负载大小 https://docs.aws.amazon.com/apigateway/latest/developerguide/limits.html

我是否误解了限制?

Joh*_*ohn 6

我为 python 3.7 创建了一个新的 lambda 函数,发现它返回更具描述性的错误。我能够确定 lambda 函数在离开 lambda 函数后会增加大约 1 MB 的响应大小,这解释了为什么它在 lambda 函数中出错,但在端点代码中却没有出错。在一种情况下,它增加了 0.82MB,在另一种情况下,它增加了 0.98MB。这似乎是基于响应的大小。我怀疑响应正在进行 base64 编码、URL 编码或类似的内容。我没有找到可以回答这个问题的文档,并且响应在接收端没有以任何方式进行编码。

使用 python 3.7 构建 lambda 函数返回的错误消息:

响应负载大小(8198440 字节)超出了允许的最大负载大小(6291556 字节)。

Lambda函数代码:

import requests, base64, json

def lambda_handler(event, context):
    
    headers = {...}
    url = ...
    
    response = requests.get(url, headers=headers)
    
    print (len(response.content))
    print (len(response.content.decode("utf-8")))

    
    return response.content.decode('UTF-8')
Run Code Online (Sandbox Code Playgroud)

下面是在 lambda 函数内部打印时的响应大小以及由错误消息中的 lambda 确定的响应大小。

我使用这两个打印语句来确定响应的大小,并且这两个打印语句将始终返回相同的长度。Response.content 是一个字节数组,所以我的思考过程是获取它的长度将返回响应中的字节数: print (len(response.content)) print (len(response.content.decode("utf- 8")))

例 1.

在 lambda 函数内部打印时的大小:

7,165,488 (6.8335 MB)

错误消息中定义的大小:

8,198,440 (7.8186 MB)

额外的:

1,032,952 (0.9851 MB)

错误信息:

响应负载大小(8198440 字节)超出了允许的最大负载大小(6291556 字节)。

Ex 2. 在 lambda 函数内部打印时的大小:

5,622,338 (5.3619 MB)

错误消息中定义的大小:

6,482,232 (6.1819 MB)

额外的:

859,894 (0.820059 MB)

错误信息:

响应负载大小(6482232 字节)超出了允许的最大负载大小(6291556 字节)。

我决定将端点代码中的软限制再降低 1 MB (4.7MB),以防止达到 lambda 函数中的限制。