是否有可能在lambda函数被杀死并冷启动之前截获终止信号以关闭数据库连接?

Vin*_*yak 10 python signals amazon-web-services python-2.7 aws-lambda

为了加快Lambda的执行速度,我尝试将Python代码的某些部分移至处理函数之外

根据Lambda的文档

执行Lambda函数后,AWS Lambda会在一段时间内维护执行上下文,以等待另一个Lambda函数调用。实际上,如果AWS Lambda在再次调用Lambda函数时选择重用上下文,则该服务会在Lambda函数完成后冻结执行上下文,并解冻该上下文以进行重用。这种执行上下文重用方法具有以下含义:

Lambda函数代码中的所有声明(在处理程序代码之外,请参阅编程模型)都将保持初始化,从而在再次调用该函数时提供其他优化。例如,如果您的Lambda函数建立数据库连接,而不是重新建立连接,则在后续调用中将使用原始连接…

按照他们的示例,我将数据库连接逻辑移到了处理程序函数之外,因此该函数的后续WARM运行可以重新使用该连接,而不是每次执行该函数时都创建一个新的连接。

但是,AWS Lambda无法保证启动COLD的函数的所有后续调用都将正常运行,因此,如果Lambda认为有必要启动COLD,我的代码将重新创建数据库连接。

发生这种情况时,我假设Lambda拆除的函数的先前(WARM)实例将与数据库保持有效连接,而该连接从未关闭,并且如果该模式不断重复,我怀疑我会有很多孤立的DB连接。

Python中是否有一种方法可以检测Lambda是否试图杀死我的函数实例(也许它们发送了SIGTERM信号?)并关闭了活动的数据库连接?

我正在使用的数据库是Postgres。

Kit*_*nde 13

接受的答案不再正确,可能在过去是正确的,但今天您的 lambda 应该会收到SIGTERMAWS 打算终止的消息。

AWS 在此处提供了有关处理 Python 和其他语言的正常关闭的官方示例:

https://github.com/aws-samples/graceful-shutdown-with-aws-lambda/tree/main/python-demo

但实际上你这样做:

import signal

def exit_gracefully(signum, frame):
  print('SIGTERM RECEIVED')

signal.signal(signal.SIGTERM, exit_gracefully)
Run Code Online (Sandbox Code Playgroud)

这会在容器关闭时调用,并且您有 300 毫秒的时间进行清理。


Dud*_*let 7

没有办法知道何时会损坏lambda容器。

因此,冷启动和数据库连接都是使用Lambda讨论的话题。最糟糕的是,没有确定的答案,应该在用例的基础上进行处理。

我个人认为,解决此问题的最佳方法是根据postgres超时来建立连接并杀死空闲的连接。为此,我指导您如何自动关闭PostgreSQL中的空闲连接?

您可能还想微调在任何时间点运行了多少个lambda。为此,我建议您在lambda aws-docs中设置并发级别。这样,您可以限制正在运行的lambda的数量,并且可能不会淹没您的数据库服务器的连接。

杰里米·戴利(Jeremy Daly)(无服务器英雄)对此发表了精彩的博文。如何:通过AWS Lambda无服务器功能管理RDS连接

不幸的是,他在节点上还有一个项目,它是mysql连接的包装器。这将监视连接并自动管理它们,例如杀死僵尸serverless-mysql。您可能会发现与python类似的东西。