【问题标题】:Emitting AWS CloudWatch metrics from AWS Lambda within synchronous functions在同步函数中从 AWS Lambda 发出 AWS CloudWatch 指标
【发布时间】:2021-05-30 15:40:36
【问题描述】:

我正在寻找一种解决方案,以便我可以在同步代码中安全(并且几乎可靠地)发出 CW 指标 (putMetricData)。我的用例如下:

// Lambda Main Handler

export const handler = async () => {
    await step1Aync();
    step2Sync();
    step3Sync();
    return {};
}

async function step1Aync() { 
    await doSomething();
    await doSomething();
    // could await this call, but dont want to since I dont need the value, nor do I want to handle failures
    cloudwatch.putMetricData();
}

function step2Sync() { 
    doSomething();
    // do not want to make this function async to use await here
    cloudwatch.putMetricData();
}

function step3Sync() { 
    doSomething();
    // do not want to make this function async to use await here
    cloudwatch.putMetricData();
}

我的理解是,当putMetricData 请求被推送到 Lambda 的事件循环中时,不能保证它们最终会向 CW 发送 HTTP 请求(因为 Lambda 执行上下文可能会在请求发生之前冻结)。当然,除非我使 step2Syncstep3Sync 异步并为每个 Promise 使用 await

我的部分理由是我想通过专门不处理来自 CloudWatch 的响应来减少 Lambda 的响应时间。这个 Lambda 是一个时间敏感的 API(API 网关)。如果对 CW 的“某些”请求失败(少于 1%),那没关系。

我读到如果再次使用相同的 Lambda 上下文,它将清空事件循环。但是,不能保证。我不知道这里的 SLA 是什么,可以这么说。

简而言之,当我没有明确需要时,我不想使用异步函数。我的理解正确吗?

【问题讨论】:

    标签: javascript node.js aws-lambda amazon-cloudwatch


    【解决方案1】:

    可能的解决方案:

    定义一个持续添加的全局数组,然后在函数末尾的一次Promise.all 调用中将该数组刷新到 CloudWatch。我们仍然需要等待调用,但它会在最后同时或并行完成(取决于底层芯片)。

    // 全局指标数组

    export const PENDING_METRICS: PutMetricDataInput[] = [];
    

    // 处理程序

    // Lambda Main Handler
    
    export const handler = async () => {
        await step1Aync();
        step2Sync();
        step3Sync();
        
        // emit all of the metrics
        await Promise.all( PENDING_METRICS.map(emitMetricToCloudWatch) );
        
        // clear the global array for safety
        PENDING_METRICS.length = 0;
        return {};
    }
    
    async function step1Aync() { 
        await doSomething();
        await doSomething();
        PENDING_METRICS.push(PutMetricDataInput)
    }
    
    function step2Sync() { 
        doSomething();
        PENDING_METRICS.push(PutMetricDataInput)
    }
    
    function step3Sync() { 
        doSomething();
        PENDING_METRICS.push(PutMetricDataInput)
    }
    

    // CloudWatch 代码

    export const emitMetricToCloudWatch = async (client, input) => client.putMetricData(input);
    

    注意:全局对象可以渗透到其他执行上下文中。因此,需要在发出每个指标后清空数组。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-08-23
      • 2018-02-26
      • 1970-01-01
      • 2017-07-05
      • 1970-01-01
      • 2020-04-20
      • 1970-01-01
      相关资源
      最近更新 更多