如何通过代理集成从 API 网关调用 AWS Lambda 保暖
How can I keep warm an AWS Lambda invoked from API Gateway with proxy integration
我已经定义了一个 lambda 函数,该函数从 API 具有代理集成的网关调用。因此,我为它定义了一个热切的资源路径:
并引用了我的 lambda 函数:
我的 lambda 能够处理像 GET /myresource
、POST /myresource
.
这样的请求
我已经尝试过这种保暖策略,如 acloudguru 中所述。它包括设置一个 CloudWatch 事件规则,该规则每 5 分钟调用一次 lambda 以使其保持温暖。不幸的是,它不起作用。
这是我见过的行为:
一段时间后,比方说 20 分钟,我从 API 网关调用 GET /myresource
,大约需要 15 秒。后续请求持续约 30 毫秒。 CloudWatch 事件没有任何区别...
让我们假设另一个长时间没有调用网关。如果我转到 Lambda 控制台并直接调用它(测试按钮),它会立即(不到 1 毫秒)回答 404(这很正常,因为我的 lambda 期望 GET /myresource
或 POST /myresource
)。
在这个 lambda 控制台执行后,我立即从 API 网关调用 GET /myresource
,它仍然需要大约 20 秒。也就是说,尽管已从 Lambda 控制台调用该函数,但它仍然很冷。这可能解释了为什么 CloudWatch 事件不起作用,因为它调用了 lambda 而没有设置 method/resource-url.
那么,我如何使用 API 具有代理集成的网关 + Lambda 保持温暖以防止那些缓慢的第一个请求?
截至目前(2019-02-27)[1],周期性 CloudWatch 事件规则无法确定性地解决冷启动问题。但是周期性的 CloudWatch 事件规则会降低冷启动的概率。
原因是由 Lambda 服务器决定是否使用新的 Lambda 容器而不是现有容器来处理传入请求。 [1]
中解释了有关如何重用 Lambda 容器的一些相关细节
为了减少冷启动时间(不是减少冷启动次数),你可以尝试以下方法吗? 1. 增加分配给函数的内存,2. 减少部署包的大小(例如 - 删除不必要的依赖项),以及 3. 使用像 NodeJS 这样的语言,Python 而不是 Java,.Net
[1]根据 reinvent session,(https://www.youtube.com/watch?v=QdzV04T_kec 39:50),Lambda 团队希望改善 Lambda 中的 VPC 冷启动延迟。
[2] https://aws.amazon.com/blogs/compute/container-reuse-in-lambda/
Denis 关于 CloudWatch 事件命中的容器数量的非确定性 lambda 行为是非常正确的。我会听从他的建议来改善启动时间。
另一方面,我已经设法使我的 CloudWatch 事件正确命中 lambda 函数,减少(在许多情况下)冷启动的次数。
我只需要添加一个映射到“/”的附加控制器,并带有硬编码响应:
@Controller("/")
class WarmUpController {
private val logger = LoggerFactory.getLogger(javaClass)
@Get
fun warmUp(): String {
logger.info("Warming up")
return """{"message" : "warming up"}"""
}
}
有了这个,来自 CloudWatch 的默认 (/) 调用确实在大多数时间保持容器温暖。
我已经定义了一个 lambda 函数,该函数从 API 具有代理集成的网关调用。因此,我为它定义了一个热切的资源路径:
并引用了我的 lambda 函数:
我的 lambda 能够处理像 GET /myresource
、POST /myresource
.
我已经尝试过这种保暖策略,如 acloudguru 中所述。它包括设置一个 CloudWatch 事件规则,该规则每 5 分钟调用一次 lambda 以使其保持温暖。不幸的是,它不起作用。
这是我见过的行为:
一段时间后,比方说 20 分钟,我从 API 网关调用
GET /myresource
,大约需要 15 秒。后续请求持续约 30 毫秒。 CloudWatch 事件没有任何区别...让我们假设另一个长时间没有调用网关。如果我转到 Lambda 控制台并直接调用它(测试按钮),它会立即(不到 1 毫秒)回答 404(这很正常,因为我的 lambda 期望
GET /myresource
或POST /myresource
)。
在这个 lambda 控制台执行后,我立即从 API 网关调用 GET /myresource
,它仍然需要大约 20 秒。也就是说,尽管已从 Lambda 控制台调用该函数,但它仍然很冷。这可能解释了为什么 CloudWatch 事件不起作用,因为它调用了 lambda 而没有设置 method/resource-url.
那么,我如何使用 API 具有代理集成的网关 + Lambda 保持温暖以防止那些缓慢的第一个请求?
截至目前(2019-02-27)[1],周期性 CloudWatch 事件规则无法确定性地解决冷启动问题。但是周期性的 CloudWatch 事件规则会降低冷启动的概率。
原因是由 Lambda 服务器决定是否使用新的 Lambda 容器而不是现有容器来处理传入请求。 [1]
中解释了有关如何重用 Lambda 容器的一些相关细节为了减少冷启动时间(不是减少冷启动次数),你可以尝试以下方法吗? 1. 增加分配给函数的内存,2. 减少部署包的大小(例如 - 删除不必要的依赖项),以及 3. 使用像 NodeJS 这样的语言,Python 而不是 Java,.Net
[1]根据 reinvent session,(https://www.youtube.com/watch?v=QdzV04T_kec 39:50),Lambda 团队希望改善 Lambda 中的 VPC 冷启动延迟。
[2] https://aws.amazon.com/blogs/compute/container-reuse-in-lambda/
Denis 关于 CloudWatch 事件命中的容器数量的非确定性 lambda 行为是非常正确的。我会听从他的建议来改善启动时间。
另一方面,我已经设法使我的 CloudWatch 事件正确命中 lambda 函数,减少(在许多情况下)冷启动的次数。
我只需要添加一个映射到“/”的附加控制器,并带有硬编码响应:
@Controller("/")
class WarmUpController {
private val logger = LoggerFactory.getLogger(javaClass)
@Get
fun warmUp(): String {
logger.info("Warming up")
return """{"message" : "warming up"}"""
}
}
有了这个,来自 CloudWatch 的默认 (/) 调用确实在大多数时间保持容器温暖。