在 Lambda 函数中关闭 DAX 客户端
Closing DAX Client in Lambda Function
我有一个 node.js 函数,我想将其部署为 AWS Lambda 函数。我注意到当我使用 redis Elasticache 时,我必须关闭我用 redis.createClient 打开的连接,否则 Lambda 函数会超时。我通过简单地调用客户端的 quit() 方法来做到这一点。如果我在发出 Lambda 回调之前执行此操作,Lambda 函数将按预期结束。如果我不这样做,Lambda 函数会在我设置的任何超时间隔内超时。在测试设置中,我有一个在缓存上运行并在 30 毫秒后终止的 Lambda 函数。如果不调用 redis 客户端 quit() 方法,相同的 Lambda 函数将不会在 1 分钟超时之前终止。我不确定,但我假设 Lambda 函数以这种方式运行,因为它不知道该函数是否已完成执行(即使在回调之后),因为 redis 连接仍处于活动状态。
我不太关心这个,因为调用 quit() 方法很容易。我遇到的问题是当我尝试使用 DynamoDB DAX 客户端执行类似操作时。我可以让 Lambda 函数直接通过我的 VPC 端点访问 DynamoDB,一切正常。如果我使用 DAX 客户端,对 table 的修改实际上发生了(我插入了一个项目并且可以看到它在那里),但是 Lambda 函数总是超时。
下面是一些示例代码:
const AmazonDaxClient = require('amazon-dax-client');
const AWS = require('aws-sdk');
const config = require('./config');
AWS.config.update(config.aws);
var ddbClient = new AWS.DynamoDB.DocumentClient(config.dynamodb);
var dax = new AmazonDaxClient(config.dax);
var daxClient = new AWS.DynamoDB.DocumentClient({service: dax });
如果我只使用 ddbClient,一切正常。如果我使用 daxClient,一切正常(插入、删除、更新等),但 Lambda 函数超时。 daxClient 是否有类似的 quit() 方法告诉 DAX 集群我已经完成并且它可以干净地关闭所有连接?我怀疑这个问题是他们希望 daxClient 的行为与普通的 ddbClient 完全一样,并且 ddbClient 没有 quit() 方法。
据记录 here,Lambda context
属性 callbackWaitsForEmptyEventLoop
似乎与您的案例相关。默认情况下,它设置为 true
,这意味着即使您的处理程序通过回调 returns 值,只要节点事件循环中仍有任何内容,Lambda 就不会完成其执行.
将其设置为 false
将允许您的 Lambda 处理程序完成事件循环中的事情,但请注意,当 Lambda 不是 运行 时,这些逻辑线程将冻结执行。此行为可能并不适合所有库,具体取决于它们的健壮程度。
有趣的是,调用 context.succeed
(而不是 callback
)的旧 Lambda return 风格不会等待空事件循环,无论 属性的设置。 (This gist 进入一些额外的细节。)
从 DAX JS 客户端版本 1.1.2 开始,这不再是问题 - Lambda 事件循环将在使用 DAX 时正确暂停。
我有一个 node.js 函数,我想将其部署为 AWS Lambda 函数。我注意到当我使用 redis Elasticache 时,我必须关闭我用 redis.createClient 打开的连接,否则 Lambda 函数会超时。我通过简单地调用客户端的 quit() 方法来做到这一点。如果我在发出 Lambda 回调之前执行此操作,Lambda 函数将按预期结束。如果我不这样做,Lambda 函数会在我设置的任何超时间隔内超时。在测试设置中,我有一个在缓存上运行并在 30 毫秒后终止的 Lambda 函数。如果不调用 redis 客户端 quit() 方法,相同的 Lambda 函数将不会在 1 分钟超时之前终止。我不确定,但我假设 Lambda 函数以这种方式运行,因为它不知道该函数是否已完成执行(即使在回调之后),因为 redis 连接仍处于活动状态。
我不太关心这个,因为调用 quit() 方法很容易。我遇到的问题是当我尝试使用 DynamoDB DAX 客户端执行类似操作时。我可以让 Lambda 函数直接通过我的 VPC 端点访问 DynamoDB,一切正常。如果我使用 DAX 客户端,对 table 的修改实际上发生了(我插入了一个项目并且可以看到它在那里),但是 Lambda 函数总是超时。
下面是一些示例代码:
const AmazonDaxClient = require('amazon-dax-client');
const AWS = require('aws-sdk');
const config = require('./config');
AWS.config.update(config.aws);
var ddbClient = new AWS.DynamoDB.DocumentClient(config.dynamodb);
var dax = new AmazonDaxClient(config.dax);
var daxClient = new AWS.DynamoDB.DocumentClient({service: dax });
如果我只使用 ddbClient,一切正常。如果我使用 daxClient,一切正常(插入、删除、更新等),但 Lambda 函数超时。 daxClient 是否有类似的 quit() 方法告诉 DAX 集群我已经完成并且它可以干净地关闭所有连接?我怀疑这个问题是他们希望 daxClient 的行为与普通的 ddbClient 完全一样,并且 ddbClient 没有 quit() 方法。
据记录 here,Lambda context
属性 callbackWaitsForEmptyEventLoop
似乎与您的案例相关。默认情况下,它设置为 true
,这意味着即使您的处理程序通过回调 returns 值,只要节点事件循环中仍有任何内容,Lambda 就不会完成其执行.
将其设置为 false
将允许您的 Lambda 处理程序完成事件循环中的事情,但请注意,当 Lambda 不是 运行 时,这些逻辑线程将冻结执行。此行为可能并不适合所有库,具体取决于它们的健壮程度。
有趣的是,调用 context.succeed
(而不是 callback
)的旧 Lambda return 风格不会等待空事件循环,无论 属性的设置。 (This gist 进入一些额外的细节。)
从 DAX JS 客户端版本 1.1.2 开始,这不再是问题 - Lambda 事件循环将在使用 DAX 时正确暂停。