【问题标题】:What happens if timeout handler is not cancelled inside lambda function?如果超时处理程序没有在 lambda 函数内取消会发生什么?
【发布时间】:2021-02-06 13:44:29
【问题描述】:

我有一个 lambda 函数,它在开始时设置具有一定延迟(60 秒)的超时处理程序。 我想知道当超时处理程序在 lambda 返回响应(不到 60 秒)之前未取消时,lambda 的确切行为是什么。特别是当有数百个 lambda 调用时,前一个 lambda 执行中未取消的超时处理程序会影响下一个在同一实例上运行的进程吗?更多信息 - 异步调用 lambda 函数。

【问题讨论】:

    标签: amazon-web-services aws-lambda


    【解决方案1】:

    您没有提及您使用的是哪种语言,也没有提供任何代码来说明您如何创建超时,但一般过程在AWS Lambda execution environment 中进行了描述。

    Lambda 会在调用后冻结执行环境并保持冻结状态,直至达到某个最大时间量(15 分钟 afaik),如果新的调用发生得足够快,并且重新使用先前的执行环境,则它会被解冻.

    文档中的一个关键引述是:

    如果 Lambda 重用执行环境,则由您的 Lambda 函数启动且在函数结束时未完成的后台进程或回调[将]恢复。确保代码中的所有后台进程或回调在代码退出之前都已完成。

    【讨论】:

    • 我认为这里的语言不是问题,但您的回答是有道理的。谢谢!
    • 不客气。该文档页面很好读。我希望说明的一点是,如果没有实际代码,我们无法确定这个超时处理程序是什么,因此我们无法确定它的行为是什么。如果这是 C++ 并且表示超时处理程序的对象超出范围,则其析构函数可能会取消超时。显然,这是一种不太可能发生的情况,并且几乎可以肯定与您的情况无关,但是了解我们正在处理的内容(例如 JavaScript 和 setTimeout)总是会更好。总之,没什么大不了的。
    • 是的,lambda 代码是用 Python 编写的。再次感谢您的解释!
    【解决方案2】:

    正如您在 cmets 中所写,lambda 是用 python 编写的。 这个简单的例子表明事件正在传递到下一次调用:

    代码:

    import json
    import signal 
    import random
    
    def delayed(val):
        print("Delayed:", val)
    
    def lambda_handler(event, context):
        r = random.random()
        print("Generated", r)
        signal.signal(signal.SIGALRM, lambda *args: delayed(r))
        signal.setitimer(signal.ITIMER_REAL, 1)
        return {'statusCode': 200}
    

    产量: Cloudwatch logs

    想想 AWS 实现 lambda 的方式: 当一个 lambda 被调用时,一个容器被提升并且环境开始初始化(这是cold-start 阶段)。 在此初始化期间,python 解释器正在启动,并且在后台,AWS 代码从 lambda 服务获取事件并触发您的处理程序。 这种初始化成本很高,因此 AWS 更愿意使用相同的“过程”等待下一个事件。在快乐的流程上,它在前一个完成之后“足够快”到达,所以他们省去了初始化,每个人都很开心。 否则,在一小段时间后,他们将关闭容器。 只要解释器​​仍然打开 - 我们在一次调用中触发的信号就会泄漏到下一次调用。

    还要注意 lambdas 的并发性 - 两个并行运行的调用在不同的容器上运行,因此具有不同的解释器,并且此警报不会泄漏。

    【讨论】:

      猜你喜欢
      • 2011-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多