[AWS] Node.jsからLambdaを起動したら同時に50までしか起動しない問題

スポンサーリンク

EC2上のNode.jsからaws-sdkを利用して、Lambdaを複数同時起動しようとしたところ、同時実行数が50で頭打ちになってしまいました・・・

いろいろ調べて解決したので、備忘録として残しておこうと思います!

事象

試したのは以下のようなソースです。

const aws = require('aws-sdk');

const callLambda = async(arn, data) => {
    aws.config.update({ region: 'ap-northeast-1'});
    var lambda = new aws.Lambda({ apiVersion: '2015-03-31' });

    const params = {
        FunctionName: arn,
        InvocationType: "RequestResponse",
        Payload: JSON.stringify(data)
    };

    return new Promise((resolve, reject) => {
        lambda.invoke(params, (err, data) => {
            if (err) {
                console.log(err, err.stack);
                reject(err);
            } else {
                console.log(data);
                resolve(data);
            }
        });
    });
}

const main = async() => {
    const arn = "呼び出すLambdaのARN";

    for (let i = 0; i < 200; i++) { 
        const param = { key: i};
        callLambda(arn, param);
    }
}
main();

上記を実行してもLambdaの「Concurrent executions」が50以上に上がらない状態に。

同時実行数には余裕があるので、上限になったわけではなさそう。

スポンサーリンク

原因

aws-sdkは裏でhttpsアクセスをしてLambdaを起動しているようなのですが、そこで利用しているhttpクライアントの最大接続数がデフォルトで50になっているようです。

さらにRequestResponse形式で呼びだしていたことにより、呼び出したLambdaの処理が終了しないと次のLambdaが呼び出せない⇒1接続あたり処理中のLambdaは1つだけ⇒最大50しか起動できないとなっていた模様。

スポンサーリンク

解決策

最大接続数の数を増やすことで解決しました!

以下のURLに変更方法が記載されています。
https://docs.aws.amazon.com/ja_jp/sdk-for-javascript/v2/developer-guide/node-configuring-maxsockets.html

上記を参考に書き換えたのが以下。


const aws = require('aws-sdk');

const https = require('https');
const agent = new https.Agent({
    maxSockets: 200
});

const callLambda = async(arn, data) => {
    aws.config.update({ region: 'ap-northeast-1'});
    var lambda = new aws.Lambda({ 
        apiVersion: '2015-03-31',
        httpOptions:{
            agent: agent
        }
    });

    const params = {
        FunctionName: arn,
        InvocationType: "RequestResponse",
        Payload: JSON.stringify(data)
    };

    return new Promise((resolve, reject) => {
        lambda.invoke(params, (err, data) => {
            if (err) {
                console.log(err, err.stack);
                reject(err);
            } else {
                console.log(data);
                resolve(data);
            }
        });
    });
}

const main = async() => {
    const arn = "呼び出すLambdaのARN";

    for (let i = 0; i < 200; i++) { 
        const param = { key: i};
        callLambda(arn, param);
    }
}
main();

 

上記を実行したところ、Lambdaの同時実行数が200になりました(^ ^)v

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です