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);
и с тех пор эта проблема, похоже, решена. Не совсем понимаю почему, но пока всё выглядит хорошо :)
Поделиться Редактировать Удалить