AWS Lambda递归调用效果不错?

时间:2016-11-21 16:02:45

标签: node.js amazon-web-services aws-lambda

我们正在使用SQS队列来处理异步消息,并且需要Lambda函数来对某些队列进行一些转换和记录消息。 经过大量的研究后,我决定使用递归的Lambda函数,因为消息并不是真正关键的,并且在它们之间使用SNS或SWF似乎过于复杂(而且我希望亚马逊很快会添加一个Lambda触发器)对于SQS)。

Lambda函数的每个请求的最大执行持续时间应该是300秒(5分钟),因此我想要重新调用Lambda,然后将Cloudwatch触发器设置为5分钟以重新触发Lambda又跑了5分钟。

然而,Lambda只是继续运行(没有Cloudwatch触发器)。我昨天对它进行了测试,并且当它持续超过300秒并且已经运行超过24小时时感到惊讶......

所以,问题是,为什么它一直在运行? 我假设每次调用它时Lambda都认为它是一个新请求。由于SQS长轮询超时是20秒,我也在超时后调用(如果没有新消息),它会继续作为新请求,对吗?

另外,如果我以5分钟的间隔添加Cloudwatch触发器,那么我是否会启动相同Lambda函数的多个实例?

(是的,我知道我正在为运行时间付费,但它仍然比EC2实例便宜,即使每天24小时运行)

修改: 添加显示调用和递归运行的Cloudwatch日志:

  

15时48分22秒    START RequestId:ee3f71df-b001-11e6-a0d6-bffc6057d58c版本:$ LATEST

     

15点48分42秒   2016-11-21T15:48:42.188Z ee3f71df-b001-11e6-a0d6-bffc6057d58c再次呼叫......再次......

     

15点48分42秒   END RequestId:ee3f71df-b001-11e6-a0d6-bffc6057d58c

     

15点48分42秒   REPORT RequestId:ee3f71df-b001-11e6-a0d6-bffc6057d58c持续时间:20115.93 ms结算时长:20200 ms内存大小:128 MB最大内存:37 MB

     

15点48分42秒    START RequestId:fa443a44-b001-11e6-bea9-4fe2d7bd8fe7版本:$ LATEST

     

15时49分02秒   2016-11-21T15:49:02.386Z fa443a44-b001-11e6-bea9-4fe2d7bd8fe7再次打电话......再次......

     

15时49分02秒   END RequestId:fa443a44-b001-11e6-bea9-4fe2d7bd8fe7

     

15时49分02秒   报告RequestId:fa443a44-b001-11e6-bea9-4fe2d7bd8fe7持续时间:20156.93 ms结算时长:20200 ms内存大小:128 MB最大使用内存:37 MB

     

15时49分02秒    START RequestId:0647caad-b002-11e6-adc9-73ebc92281fd版本:$ LATEST

     

15点49分22秒   2016-11-21T15:49:22.601Z 0647caad-b002-11e6-adc9-73ebc92281fd再次呼叫......再次......

     

15点49分22秒   END RequestId:0647caad-b002-11e6-adc9-73ebc92281fd

     

15点49分22秒   报告RequestId:0647caad-b002-11e6-adc9-73ebc92281fd持续时间:20179.49 ms结算时长:20200 ms内存大小:128 MB最大使用内存:37 MB

1 个答案:

答案 0 :(得分:1)

如果正如您在评论中所说,您的函数是自我调用的,那么添加触发器将导致lambdas的新每隔几分钟启动一次。就目前而言,您当前的功能应该永远运行(直到崩溃)。

如果你想在lambda中拥有像flock安全这样的东西,你可以做一些事情:

  1. 创建一个由cloudwatch调用的触发器lambda。这个lambda所做的就是检查一个到期的密钥(可以使用S3,SQS或elasticache)来查看在最后X分钟内是否调用了另一个lambda。如果没有,请启动新副本。

  2. 如果队列为空,则删除lambda中的递归。

  3. 保持两者,但只允许最大递归深度。这与#2略有不同,因为在长时间运行期间(IE:当你在SQS中有数据时),你可以设置它,使得多个lambda同时运行等待空队列。但是,它也降低了产生无限lambda的轻微错误的可能性。

  4. 独立于此,我认为在递归深度上有一个没有硬帽的递归lambda听起来非常危险。