を待つことなく


AWSラムダからHTTP/REST URLを呼び出す最速の方法は何ですか?
応答が必要な場合は、答えはかなりまっすぐです.
しかし、あなたが返信を待つ必要がない場合はどうですか?

非待機HTTP


処理した後にいくつかのメトリクスを蓄積して、それらを処理のための残りのアグリゲータサービスに戻すラムダ関数の場合を考えてください.メトリクスがカウンタであるならば、メトリクス要求が時折失敗するならば、それは重要でないかもしれません.これらのような場合には、HTTPレスポンスを待たない方が速いでしょう.

So how would we do this in NodeJS?


最初にレスポンスを待ちます.
この例のために、我々が待つことができる約束を返す非同期「要求」ノード機能を作成します.
const https = require('https')
const URL = require('url')

async function request(url, data) {
    return new Promise((resolve, reject) => {
        let req = https.request(URL.parse(url), function (res) {
            let body = ''
            res.on('data', (chunk) => { body += chunk })
            res.on('end', () => { resolve(body) })
        })
        req.write(data)
        req.end()
    })
}
それから、ラムダは次のようになります.
exports.handler = async (event, context) {
    ...
    let result = await request('https://metric-service.com', metrics)
    return result
}
ラムダ内でHTTPリクエストを呼び出すには、リクエストを発行し、応答を待つ「wait」を使用します.
メトリックAggregatorサービスが要求を処理して、ステータスコードを返すために950ミリ秒かかるならば、我々はすべての呼び出しに関して追加の第2のために請求されます.この待ち時間の間、我々のラムダ機能は眠っています、しかし、AWSはまだその時私たちを請求しています.AWSラムダを使用すると、使用されるCPU時間の経過時間のために請求されます.ラムダは非常に安価で、高いトランザクションのボリュームで、950ミリ秒のこれらの短い待ち時間は、重要な法案に追加することができます.

待つな


それで、我々が単に「待つ」という電話をしないならば、何が起こるか、そして、このように我々のHTTPリクエストからの応答で待つことはありませんか?
exports.handler = async (event, context) {
    /* nowait */ request('https://example.com', metrics)
    return 'done'
}

Strange things happen.


時々、リクエストは送られます、そして、時々、要請はそうでありません.
時々、リクエストはメトリクスアグリゲータによってすぐに受信されます、そして、時々、我々のラムダが走らせたあと、リクエストは受け取られます.何が起こっているのか

冷凍ラムダ容器


ラムダ関数はAWSの爆竹コンテナ内で動作します.ラムダ関数から戻ると、AWSはすぐにコンテナとそのグローバル状態を凍結します.ラムダが次に呼び出されると、コンテナを解凍して新しい呼び出しをサービスします.
我々がHTTPリクエストを送って、その要求が完全にネットワークを通じて送られないなら、ラムダ関数から戻るならば、AWSはすぐにラムダコンテナを中断します、そして、部分的に送られた要求は同様に中断されます.ラムダが次に呼び出されるまで、リクエストは凍結し続け、ノードイベントループは処理を再開し、リクエストは完全に送信されます.

どのように解決するには?


我々は短い睡眠を要求するための時間を与えるために送信することができますか?しかし、どのくらい待ちますか.
exports.handler = async (event, context) {
    /* nowait */ request('https://example.com', metrics)
    await sleep(100)
    return 'done'
}

This hardly seems reliable.


リクエスト送信待ち


正しい解決策は、ノードreqを使用することです.end (コールバック) APIとリクエストが完全に送信されるまで待ちますが、応答を受信するのを待ちません.以下はサンプルです.
const https = require('https')
const URL = require('url')

async function request(url, data) {
    return new Promise((resolve, reject) => {
        let req = https.request(URL.parse(url))
        req.write(data)
        req.end(null, null, () => {
            /* Request has been fully sent */
            resolve(req)
        })
    })
}
リクエストは前の例の「res」オブジェクトではなく、“req”オブジェクトのend callbackを通して解決されることに注意してください.
この変更されたリクエスト関数は“wait”と共にラムダによって呼び出されるべきです.この場合、HTTPレスポンスを待つのではなく、完全に要求されたリクエストに対して待機します.これは、通常、20ミリ秒未満で、我々のメトリクス反応を受け取る750ミリ秒より非常に速いです.
exports.handler = async (event, context) {
    await request('https://example.com', metrics)
    return 'done'
}

代替デザインパターン


また、待ち行列関数や待ち行列を使用したり、待ち行列なしでイベントとしてラムダ関数を直接呼び出すなどのラムダ関数を待ち、ブロックするのを避ける他の多くの方法があります.あなたのアプリケーションのための最善のアプローチを検討するが、HTTPを使用する必要がありますし、応答を待つ必要がない場合は、上記のテクニックを考慮して待つ時間とAWSの法案を下げる.

センセーグディープ


我々のSensedeep Serverless Studioは、あなたのランムダス、ランニング警報とIngests LogデータをモニターするWatcherラムダで、このテクニックを使用します.私たちは、ウォッチャーが例外的に速くて、どんなREST/HTTP APIリクエストも待つ必要がなかった.したがって、監視者はsensedeepサービスにステータスを送り返すとき、この非待機技術を使用します.

Sensedeep Serverlessトラブルシューティングプラットフォームについての詳細は、無料でお試しください.
あなたが似ているか別のテクニックを使用して任意のコメントがある場合は私に知らせてください.https://www.sensedeep.com .

[email protected] 参考文献


ここではいくつかの他の良い読み書きラムダとAWS非同期プログラミングです.
  • ノードイベントループ凍結:
  • ラムダ請求:
    https://levelup.gitconnected.com/avoiding-the-pitfalls-of-async-node-js-functions-in-aws-lambda-941220582e7a
  • Asyncプログラミング
    https://www.jeremydaly.com/serverless-tip-dont-overpay-when-waiting-on-remote-api-calls/
  • ステップ関数の危険性
    https://read.acloud.guru/save-time-and-money-with-aws-lambda-using-asynchronous-programming-3548ea65f751
  • ラムダの非同期を呼び出します.
    https://blog.scottlogic.com/2018/06/19/step-functions.html
  • ラムダの呼び出しの概要
    https://docs.aws.amazon.com/lambda/latest/dg/invocation-async.html