Jim*_*m J 1 node.js aws-lambda
我不这么认为,但对于我所观察到的情况,我没有其他好的解释。这是相关代码的粗略版本,它位于处理函数内部(即,它不会在调用之间持续存在):
const res = await graphqlClient.query({my query})
const items = res.data.items
console.log(items) // <- this is the line that logs the output below
items.push({id: 'some-id'})
const itemResults = await Promise.all(items.map((item) => etc etc)
Run Code Online (Sandbox Code Playgroud)
在我的客户连续调用(间隔不到十秒)的过程中,some-id被重复添加到items. 第一次调用时,以下是在 CloudWatch 中记录的内容const items = res.data.items:
[
{
anotherId: 'foo',
id: 'bar',
}
]
Run Code Online (Sandbox Code Playgroud)
第二次调用它时,几秒钟后,在调用之前写入日志items.push():
[
{
anotherId: 'foo',
id: 'bar',
},
{ id: 'some-id' }
]
Run Code Online (Sandbox Code Playgroud)
第三次,在调用之前再次写入日志items.push():
[
{
anotherId: 'foo',
id: 'bar',
},
{ id: 'some-id' },
{ id: 'some-id' }
]
Run Code Online (Sandbox Code Playgroud)
items永远不会写入持久存储。some-id仅修改两次:当它设置为等于 graphql 查询返回的值时,以及当我手动将另一个值推入堆栈时。我可以通过检查是否some-id已在堆栈上来防止此错误,因此我现在已解锁,但它如何在连续运行中持续存在?我从来没想到 Lambda 会有这样的行为!我认为每次调用都是无状态的。
AWS Lambda 是一种无状态的,但并不完全是无状态的。你必须小心,这确实是真的。由于上面的示例代码缺少handler function,我假设您没有提供完整的代码并且您已const items在handler function. 基于我的假设的粗略解释:
handler function第一次启动 Lambda 函数(即“冷启动”)时,外部的所有内容都会初始化一次。只要 Lambda 函数的实例保持活动状态,您就可以初始化变量、数据库连接等,并在每次调用中重复使用它们。handler function以及以后的每次调用时被调用。如果您在处理程序函数之外更改值/对象,那么它们将在当前调用中保留下来,并且您可以在下一次调用中使用它们。这样,您可以缓存一些昂贵的数据或进行一些其他优化。例如:const items = []
exports.handler = function(...) {
// ...
items.push(...)
// ...
}
Run Code Online (Sandbox Code Playgroud)
对于 Java 和 Python Lambda 函数来说也是如此,我相信对于大多数其他运行时也是如此。现在,这可能是对您所观察到的内容的解释:在一次调用中,您正在推送某些内容,items而在下一次调用中,先前的数据仍然存在,因为它存储在处理程序函数之外。
针对您的情况的建议:如果您想要完整的无状态函数,请不要修改处理程序函数之外的数据,而只在内部存储值。但请注意,如果您需要在每次调用中初始化数据,这可能会减慢 Lambda 函数的速度。
由于 AWS Lambda 的这种行为通常用于缓存数据,因此有一些博客文章也涵盖了该主题以及代码如何处理它。他们通常提供更多直观的解释和示例代码:
AWS Lambda 中的缓存(注:我自己的博客文章)
您需要了解的有关无服务器应用程序缓存的所有信息(这涵盖了有关缓存的更多内容,但其中一部分还考虑了 Lambda 函数内部的缓存)
当然,幕后还发生了更多事情。如果您对整个过程的工作原理感兴趣,我建议您查看执行环境详细信息。本文更侧重于提供构建扩展的背景以及代码外部的流程如何工作,但它可能会帮助您了解幕后发生的情况。
| 归档时间: |
|
| 查看次数: |
1065 次 |
| 最近记录: |