在后台,AWS Lambda 函数在容器中执行,该容器将它们与其他函数隔离并提供函数配置中指定的资源,例如内存。
处理函数之外的任何变量都将是'frozen' https://docs.aws.amazon.com/lambda/latest/dg/runtimes-context.html在 Lambda 调用之间possibly重复使用。可能是因为根据执行量,容器几乎总是被重用,尽管这不能保证。
您可以通过多次使用以下源代码调用 Lambda 并查看响应来亲自测试这一点:
let counter = 0
exports.handler = async (event) => {
counter++
const response = {
statusCode: 200,
body: JSON.stringify(counter),
};
return response;
};
这还包括您可能想要在处理程序外部创建的数据库连接,以最大限度地提高调用之间重用的机会并避免每次都创建新连接。
无论是否重用 Lambda 函数,当 AWS 终止 Lambda 容器时,在处理程序外部建立的连接最终都会关闭。当然,当连接被重用时,“僵尸”连接的问题会少得多,但它仍然存在。
当您开始达到大量并发 Lambda 执行时,主要问题是如何结束已终止的 Lambda 函数容器剩余的未使用连接。 AWS Lambda 非常擅长在容器过期时可靠地终止连接,但您仍然可能会遇到接近您的容器的问题。max_connections
limit.
当 Lambda 冷启动时,我们如何关闭之前打开的不再使用的连接?
没有本地解决方法通过您的应用程序代码或 Lambda 设置来完全摆脱这些僵尸连接,除非您自己处理打开和关闭它们,并承受创建新连接的额外持续时间(仍然是一个非常小的数字)。
要清除僵尸连接(如果必须的话),解决方法将会是触发 Lambda,然后列出、检查并终止空闲的剩余连接。您可以通过按计划运行的 EventBridge 规则触发此操作,也可以在接近达到最大数据库连接时触发此操作。
这些也是值得遵循的重要准则:
-
确保您的 Lambda 并发执行限制不超过数据库最大连接数限制:这是为了防止数据库达到最大连接数
-
减少数据库超时(如果支持):限制连接空闲和保持打开状态的时间,例如在 MySQL 中调整wait_timeout
从默认的 28800 秒(8 小时)到 900 秒(15 分钟)的变量可能是一个很好的开始
-
减少数据库连接数量:通过良好的应用程序设计和缓存,尽力减少需要与数据库建立的连接
-
如果所有其他方法都失败,请考虑增加数据库的最大连接数限制