AWS Lambda函数生存期

时间:2016-01-19 21:07:42

标签: amazon-web-services aws-lambda

考虑以下AWS Lambda函数:

var i = 0;
exports.handler = function (event, context) {
    context.succeed(++i);
};

多次执行此功能,我最终输出类似如下的输出:

> 0
> 1
> 2
> 0
> 1
> 0
> 3
> 2
> 4
> 1
> 2

正如你所看到的,似乎脚本中有3个单例,当我执行该函数时,我随机结束其中一个。

这是预期的行为吗?我在文档中找不到任何相关信息。

我问这个是因为我打算连接到MySQL并保留一个连接池:

var MySQL = require('mysql');
var connectionPool = MySQL.createPool({
   connectionLimit: 10,
   host: '*****',
   user: '*****',
   pass: '*****',
   database: '*****'
});

function logError (err, callback) {
    console.error(err);
    callback('Unable to perform operation');
}

exports.handler = function (event, context) {
    connectionPool.getConnection(function (err, connection) {
        err && logError(err, context.fail);
        connection.query('CALL someSP(?)', [event.user_id], function (err, data) {
            err && logError(err, context.fail);
            context.succeed(data[0]);
            connection.release();
        });
    });
};

需要使用connectionPool.end()处理连接池,但我应该在哪里执行此操作?

如果我在脚本末尾添加它(在处理程序之后),那么当lambda函数首次执行时,连接池将立即关闭。

如果我将连接池部署在处理程序中,那么将关闭连接池以供将来请求使用。

此外,我应该处理它吗?如果我不处理它,连接将是池中和内存中的kepts,但正如您在第一个代码示例中看到的那样,AWS保留了我模块的~3个单例,这意味着我最终会3个不同的连接池,每个连接10个连接。

1 个答案:

答案 0 :(得分:4)

除非我误解了你的问题,否则这是有充分记录和预期的lambda行为。见这里:https://aws.amazon.com/lambda/faqs/

Lambda旋转容器的实例以匹配lambda函数的使用模式。如果此时没有使用它,那么它会将其旋转,如果它被大量使用,那么将创建更多的容器。你永远不应该依赖lambda函数中的持久状态。如果它是用于函数的生命周期,或者您正在优化某些东西,则可以使用state。

据我所知,您无法在任何给定时间控制内存中的函数实例数,因此如果您担心使用mysql连接,则应相应地进行设计。

来自文档:

“AWS Lambda可以根据需要启动尽可能多的功能副本,而无需冗长的部署和配置延迟。扩展功能没有根本限制.AWS Lambda将动态分配容量以匹配传入事件的速率。”

直接应用于你的mysql问题,我总是会在你使用它之后将你的连接返回到池中。然后我会做一些关于你期望有多少并发请求的计算,并相应地计划你的mysql服务器配置。