由AWS Lambda Warm Start引起的node.js的const问题

本文是用来记录曾经遇到的一个由AWS Lambda Warm Start而引起的node.js的const问题。

AWS Lambda Function内容概述:简单地说就是输入event中有个dbName参数用于连接不同的database,因为参数在执行过程中不会变化,所以我们就写成了

const dbName = event.dbName;Code language: JavaScript (javascript)

问题描述:我们的程序并发非常高,结果发现只有一个database成功存储了Lambda写入的数据,其他database都是空的,而AWS CloudWatch显示每次Lambda都执行成功了。

原因:因为这是一篇回顾文章,所以具体的排查过程就不写了,大概用了一天的时间发现问题是出在AWS Lambda Warm Start机制和const上面。

简单地说,AWS Lambda有分Cold Start和Warm Start两种。Cold Start就是指完整的初始化一个新环境并运行你的代码;而Warm Start是指,当一个Lambda运行结束进入销毁阶段时,系统会延时等一段时间再销毁,如果此时这个Lambda Function有一个新的执行请求过来,那系统就会复用这个待销毁的环境,把他拉过去直接运行。因为Warm Start直接使用上一个用过的环境,所以const这个用法就引起了麻烦,本意是想每次接收的参数是固定不变的,结果在Warm Start情况下却成了const使用上一次的环境值且本次运行无法改变,所以每次就只能重复写入一个database。

解决方案:用let代替const接收传入的参数,使他的作用于限制在本次运行的Lambda Function中。

经验总结:由于Cloud和Serverless的开发越来越得多,运行环境和方式和传统的多进程有很大的变化,尤其是这种复用之前的运行环境的Warm Start更是对全局和局部的变量、常量使用带来了新的问题。因此在使用const(或readonly等)时应该更加小心,基本上除了hardcode的内容,其他不再推荐使用const(或readonly)。

参考资料

Lambda execution environments – AWS Lambda (amazon.com)


评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理