使用 Node.js 从 AWS Lambda 函数连接到 MySql 数据库,没有连接回调

Posted

技术标签:

【中文标题】使用 Node.js 从 AWS Lambda 函数连接到 MySql 数据库,没有连接回调【英文标题】:Connecting to MySql database from AWS Lambda function using Node.js, no connect callback 【发布时间】:2021-07-02 01:39:58 【问题描述】:

我正在尝试使用 nodejs14.x 环境从用 Node.js 编写的 AWS Lambda 函数连接外部(不是 AWS)mysql 服务器,但未调用 connect() 回调。

几天以来我一直在努力解决这个问题,有很多类似问题的参考资料,但我真的尝试了我找到的所有可能的解决方案排列。

我正在使用 SAM 进行部署,并在本地机器和真实 AWS 上进行测试。

这里是 lambda 助手的示例代码

    const mysql = require('mysql');

    exports.helloFromLambdaHandler = async () => 

    const message = 'Hello from Lambda!';

    console.info(`$message`);
    
    var sql = "SELECT 1+? AS sum";
    var values = [1];

    console.log("Doing createConnection");
    const connection = mysql.createConnection(
        /* my connection data */
      );
    
    console.log("Doing connect");
    connection.connect( (err) => 
        console.log("Inside connection callback");
        console.log('connected as id ' + connection.threadId);

        if(!err) 
          console.log("DB connected, thread id is "  + connection.threadId);
          console.log("Doing query");

          connection.query(sql, values, (err, result, values) => 
            console.log("Inside query callback");
            if(!err) 
              console.log("Query ok!");
              console.log(result);
              connection.end();
             else 
              console.log("Error executing query: " + err.message);
                   
          );
          
         else 
          console.log("Error connecting db: "+ err.message);
        
      );

    console.log ("Returning...");
    return message;


日志是

Hello from Lambda!
Doing createConnection
Doing connect
Returning...

预期的行为是,在“返回...”之后,我应该看到日志“内部连接回调”,然后是“内部查询回调”,然后是“查询正常!”。

相反,connect() 的回调似乎没有被调用。

我知道我可以直接调用query() 跳过connect() 但这样做我也会遇到同样的问题。

有什么线索吗?

谢谢!

解决方案

正如接受的答案所建议的那样,返回一个承诺是让 Node 完成所有队列的解决方案。不幸的是,据我所知,不可能完成 Lambda 并让它以安全的方式在后台运行。

我正在研究替代解决方案,例如:

mysql2 原生支持 Promise 的库 serverless-mysql 处理共享数据库连接的 npm 包

下面是运行的演示代码

const mysql = require('mysql');

exports.helloFromLambdaHandler = async (event, context) => 

    const message = 'Hello from Lambda!';

    console.info(`$message`);
    
    var sql = "SELECT 1+? AS sum";
    var values = [1];

    console.log("Doing createConnection");
    const connection = mysql.createConnection(
        /* my connection data */
      );
    
    console.log("Doing query");

    const promise = new Promise( (resolve, reject) => 
        connection.query(sql, values, (err, result, values) => 
        console.log("Inside query callback");
        if(!err) 
            console.log("Query ok!");
            console.log(result);
            connection.end();
            resolve(message);
         else 
            console.log("Error executing query: " + err.message);
            reject(err);
               
        );
    );

    console.log ("Returning...");
    return promise;

【问题讨论】:

一般来说:从 lambda 返回后,lambda 完成,它不会做任何进一步的工作,它的内存/磁盘被冻结,直到下一次 lambda 调用。 正如 Marcin 的回应所指出的,这是由于将处理程序声明为异步的行为!删除该关键字允许在返回后处理节点队列! :) 【参考方案1】:

您正在使用async handler,因此您的函数可能在您的connect() 有机会执行之前完成。

要尝试解决此问题,您可以使用Promise,如AWS docs 所示。

【讨论】:

谢谢!只需删除处理程序声明中的关键字 async 就可以按预期处理我的所有节点队列!现在我将调查我是否真的需要异步处理程序,我会相应地跟进! 我所面临的问题的详细说明在下面的链接中,再次感谢您为我指明正确的方向!!! levelup.gitconnected.com/…

以上是关于使用 Node.js 从 AWS Lambda 函数连接到 MySql 数据库,没有连接回调的主要内容,如果未能解决你的问题,请参考以下文章

错误:“无法从上下文中获取当前子/段”在 Lambda 中使用 AWS X-ray 和 node.js

如何从 AWS lambda 发布到 Node.js 中的云观察指标

使用带有 Node.js 的 AWS Lambda 函数从 S3 存储桶中提取 zip 文件并上传到另一个存储桶

从本地系统而不是S3上运行的node.js应用程序调用AWS Lambda

重新开始继续准备AWS Dev认证考试:AWS Lambda 环境变量

使用 Node.JS 调用 AWS 胶水的 lambda 函数不使用 console.log 的原因是啥?