【问题标题】:AWS Lambda function timing out after successful completion成功完成后 AWS Lambda 函数超时
【发布时间】:2019-05-21 03:26:40
【问题描述】:

我有一个可以成功运行的 lambda 函数。我能够在 S3 和另一个 FTP 服务器上创建一个文件。问题是即使在成功完成后也会超时。它只是没有完成执行。我可以从日志中看到大约需要 2 秒,指定的超时时间是 5 秒。如何让我的功能在完成后立即停止?完整代码如下:

"use strict";

var config = require('./config/dev');
var sql = require("mssql");
var AWS = require('aws-sdk');
var PromiseFtp = require('promise-ftp');
var fs = require('fs');
const request = require('request');


exports.handler = (event, context, callback) => {
    GetDataFromServer(event, context, callback);
};

function GetDataFromServer(event, context, callback) {
    console.log("Fetching data from database...");
    var keys = [], outputText = '';
    sql.connect(config.db, err => {
        if (err) {
            console.log("Error while connecting database :- " + err);
            return callback(true, 'Error in fetching records from database...');
        }
        else {
            new sql.Request()
                .input('ClientId', sql.Int, 469)
                .execute('ForesightDailyDataPull', (err, result) => {
                    if (!err) {
                        //Create Text here and assign to "outputText"
                        CreateFileOnS3(outputText, event, context, callback);
                    }
                    else {
                        console.log('Error in fetching records from database...');
                        return callback(true, 'Error in fetching records from database...');
                    }
                })
        }
    });
    sql.on('error', err => {
        console.log('Error in fetching records from database...');
        return callback(true, 'Error in fetching records from database...');
    })
}

function CreateFileOnS3(fileData, event, context, callback) {
    const fileName = generateFileName();
    console.log('Sending file to S3...');
    const s3 = new AWS.S3(config.awsCredentials);
    const params = {
        Bucket: config.app.s3Bucket,
        Key: fileName,
        Body: fileData
    };
    s3.upload(params, function (s3Err, data) {
        if (s3Err) {
            console.log('There was an error creating file on S3');
            return callback(true, 'There was an error creating file on S3');
        }
        else {
            console.log(`File uploaded successfully at ${data.Location}`);
            CreatefileOnFTP(fileData, fileName, event, context, callback);
        }
    });
}

function CreatefileOnFTP(fileData, fileName, event, context, callback) {
    console.log('Sending file to FTP...');
    var ftpObject = {
        "fileData": fileData,
        "fileName": fileName,
        "ftpURL": config.ftpDetails.ftpProtocol + "://" + config.ftpDetails.host,
        "ftpUserName": config.ftpDetails.user,
        "ftpPassword": config.ftpDetails.password
    };
    request({
        url: config.ftpUploadURL,
        method: "POST",
        json: true,
        body: ftpObject
    }, function (error, response, body) {
        if (!error) {
            console.log('File sent successfully to FTP server.');
            return callback(null, 'File sent successfully to FTP...');
        }
        else {
            console.log('An error occurred while sending file to FTP.');
            return callback(true, 'Error in sending file to FTP...');
        }
    });
}

function generateFileName() {
    var _d = new Date(),
        y = _d.getFullYear(),
        m = _d.getMonth() + 1,
        d = _d.getDate();
    return y + '-' + (m < 10 ? '0' + m : m) + '-' + (d < 10 ? '0' + d : d) + '.txt';
}

【问题讨论】:

  • AWS Lambda 继续调用 Lambda 函数,直到事件循环为空。您的好路径似乎确实以 null 作为第一个参数调用提供的回调,所以也许您的事件循环不为空?
  • @jarmod 我不确定如何让事件循环为空。有什么办法可以停止执行函数。
  • 我不能 100% 确定这是原因,但它是关于 Lambda 服务如何知道 Lambda 函数已完成的重要声明(不仅仅是函数返回或回调已完成) )。如果将超时从 5s 增加到 30s,它是否在 2s 完成处理然后在 30s 超时?我想知道您的 MySQL 和/或 FTP 客户端对象是否是原因?您可以尝试明确关闭/拆除这些以进行测试吗?我假设您肯定会在 Lambda 超时之前的某个时间看到日志“文件已成功发送到 FTP...”。

标签: node.js amazon-web-services aws-lambda


【解决方案1】:

您应该在函数完成后通过在操作解析后调用sql.close() 关闭打开的 sql 连接。

function GetDataFromServer(event, context, callback) {
    console.log("Fetching data from database...");
    var keys = [], outputText = '';
    sql.connect(config.db, err => {
        if (err) {
            console.log("Error while connecting database :- " + err);
            return callback(true, 'Error in fetching records from database...');
        }
        else {
            new sql.Request()
                .input('ClientId', sql.Int, 469)
                .execute('ForesightDailyDataPull', (err, result) => {
                    if (!err) {
                        //Create Text here and assign to "outputText"
                        CreateFileOnS3(outputText, event, context, callback);
                        sql.close() //HERE
                    }
                    else {
                        console.log('Error in fetching records from database...');
                        sql.close() //HERE
                        return callback(true, 'Error in fetching records from database...');

                    }
                })
        }
    });
    sql.on('error', err => {
        console.log('Error in fetching records from database...');
        sql.close() //HERE
        return callback(true, 'Error in fetching records from database...');
    })
}

【讨论】:

    猜你喜欢
    • 2019-04-09
    • 2019-11-09
    • 1970-01-01
    • 1970-01-01
    • 2020-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-22
    相关资源
    最近更新 更多