AWS: ランタイムセグメンテーション違反により API ゲートウェイ 502 エラーがランダムに発生する

AWS: ランタイムセグメンテーション違反により API ゲートウェイ 502 エラーがランダムに発生する

私は AWS を使用しており、node.js Lambda 関数を呼び出す API ゲートウェイ経由で呼び出される API があります。

非常に頻繁に、しかしランダムに 502 応答が返されますが、すぐにまったく同じリクエストを再試行すると、通常の応答が返されます。そこで、ログを検索して問題がないか確認することにしました。

リクエストの 1 つについて、次のことが分かりました。

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);

それ以来、この問題は解決されたようです。理由はよく分かりませんが、今のところは良さそうです :)

共有 編集 削除

関連情報