AWS: случайная ошибка API-шлюза 502 из-за ошибок сегментации во время выполнения

Я использую AWS и имею API, который вызывается через шлюз API, который вызывает лямбда-функцию node.js.

Очень часто, но случайно, я получаю 502 ответа, но когда я сразу же пытаюсь повторить тот же запрос, я получаю нормальный ответ. Поэтому я решил поискать в журналах, чтобы посмотреть, смогу ли я найти какие-либо проблемы.

Вот что я нашел по одному из запросов:

      RequestId: xxxxx Error: Runtime exited with error: signal: segmentation fault Runtime.ExitError

а также:

      xxxx    ERROR   Uncaught Exception  
{
    "errorType": "Error",
    "errorMessage": "Quit inactivity timeout",
    "code": "PROTOCOL_SEQUENCE_TIMEOUT",
    "fatal": true,
    "timeout": 30000,
    "stack": [
        "Error: Quit inactivity timeout",
        "    at Quit.<anonymous> (/opt/nodejs/node_modules/mysql/lib/protocol/Protocol.js:160:17)",
        "    at Quit.emit (node:events:527:28)",
        "    at Quit.emit (node:domain:475:12)",
        "    at Quit._onTimeout (/opt/nodejs/node_modules/mysql/lib/protocol/sequences/Sequence.js:124:8)",
        "    at Timer._onTimeout (/opt/nodejs/node_modules/mysql/lib/protocol/Timer.js:32:23)",
        "    at listOnTimeout (node:internal/timers:559:17)",
        "    at processTimers (node:internal/timers:502:7)"
    ]
}

Ниже приведен мой многоразовый соединитель sql:

      const CustomSecret = require('../secrets/CustomSecret');
const mysql = require("mysql");

module.exports = class MySqlConnect {

    databaseCredObject;

    constructor() {
    }

    async queryDb(sql, args) {

        if (!this.databaseCredObject) {
            await this.fetchSecret();
        }

        let connection = null;
        const connection_settings = {
            host: this.databaseCredObject.host,
            user: this.databaseCredObject.username,
            password: this.databaseCredObject.password,
            database: 'logbook'
        };

        connection = mysql.createConnection(connection_settings);

        return new Promise((resolve, reject) => {
            connection.connect(function (err) {
                if (err) {
                    console.log('error when connecting to db:', err);
                } else {
                    console.log('Connected');
                    connection.query(sql, args, function (err, result) {
                        connection.end();
                        if (err) {
                            return reject(err);
                        }
                        return resolve(result);
                    });
                }
            });
        });
    }

    async fetchSecret() {
        const databaseCredString = await CustomSecret.getSecret('secretname', 'eu-west-2');
        this.databaseCredObject = JSON.parse(databaseCredString);
    }
}

Наконец, это пример моей лямбда-функции (сокращенная версия):

      const {compress, decompress} = require("compress-json");

const MySqlConnect = require("customPackagePath/MySqlConnect");
const CustomJwt = require("customPackagePath/CustomJwt");
const AWS = require("aws-sdk");
const warmer = require("lambda-warmer");

exports.handler = async (event) => {


    if (await warmer(event)) {
        console.log("Warming");
        return 'warmed';
    }

    let responseCode = 200;
    let response = {};

    response.headers = {
        'Content-Type': 'application/json',
        'Access-Control-Allow-Origin': '*'
    };

    const bodyContent = JSON.parse(event.body);
    const dataType = bodyContent.dataType;
    const webAuth = new CustomJwt();
    const decodedToken = webAuth.decodeToken(event.headers.Authorization);
    const userUUID = decodedToken['uuid'];
    
    
    const connection = new MySqlConnect();
    
    let sql;

    switch (dataType) {
        case 'userPreferences':
            sql = await connection.queryDb('SELECT * FROM user WHERE uuid = ?', [userUUID]);
            break;
    }


    let data = [];

    for (let index in sql) {
        data.push(JSON.parse(JSON.stringify(sql[index])));

    }


    const returnData = {
        data
    };


    let compressed = compress(returnData);

    response.statusCode = responseCode;
    response.body = JSON.stringify(compressed);


    return response;
};

Я новичок в инфраструктурных вопросах. Но мне кажется, что после вызова лямбда-функции она не закрывается и не завершается правильно. Кроме того, я использую подогреватель лямбды, чтобы поддерживать температуру функций, как видно из лямбда-кода, и не уверен, вызывает ли это какие-либо проблемы.

Буду признателен за любую помощь в этом, поскольку я, похоже, не могу в этом разобраться.

Спасибо

1 ответ

Проведя дополнительные исследования, я решил добавить это в свою функцию Lambda:

      exports.handler = async (event, context, callback) => {

и возврат такой

      callback(null, response);

и с тех пор эта проблема, похоже, решена. Не совсем понимаю почему, но пока всё выглядит хорошо :)

Поделиться Редактировать Удалить

Другие вопросы по тегам