【问题标题】:Cloudwatch putMetricData hanging within LambdaCloudwatch putMetricData 挂在 Lambda 中
【发布时间】:2020-12-27 22:38:54
【问题描述】:

我正在尝试设置一个 lambda 来定期查询我们的队列服务并将消息计数报告回 Cloudwatch,以便我们可以监控队列大小。

当使用无服务器框架在本地调用代码时,所有代码都可以正常工作。但是,当从 Lambda 本身触发时,对 AWS Cloudwatch 的请求永远不会完成,并且 lambda 会超时。

import {Callback, Context, Handler} from 'aws-lambda';
import {CloudWatch} from 'aws-sdk';

const queueReporter: Handler = async (event: any, context: Context, callback: Callback) => {
    // TRUNCATED - GET Queue counts

    const cloudwatch = new CloudWatch({region: 'eu-west-1'})
    const date = new Date();

    // convert queue data into cloudwatch metrics
    const metricData: CloudWatch.Types.MetricData = queues.map((queue): CloudWatch.Types.MetricDatum => ({
        MetricName: queue.name,
        Timestamp: date,
        Unit: 'Count',
        Value: queue.messages,
    }));

    console.log('add metrics'); // This prints out

    return await cloudwatch.putMetricData(
        {
            MetricData: metricData,
            Namespace: 'Queue_Messages'
        }).promise().then((response) => {
            const result = JSON.stringify(response);

            console.log(result); // this does not print out

            callback(null, result);

            return result;
        }
    );
};

我怀疑这是某种权限问题,因为当我没有在笔记本电脑上配置访问密钥时,我在本地看到了类似的问题。
但是该政策包括我认为应该足够的声明

{
    "Action": [
        "cloudwatch:PutMetricData"
    ],
    "Resource": "*",
    "Effect": "Allow"
}

为了访问队列的 API,此 lambda 已添加到 VPC 和安全组。然而,这个安全组没有传出限制,只有传入。

任何帮助将不胜感激

【问题讨论】:

    标签: node.js aws-lambda serverless-framework


    【解决方案1】:

    我首先要看的是简化异步处理的不匹配。您正在等待调用 lambda 回调的 Promise,但 lambda 函数被定义为异步,因此 AWS 期望返回一个 Promise。您应该将 lambda 定义为异步并忽略回调,或者定义不带异步的 lambda 并使用回调。

    试试这个:

    const queueReporter: Handler = async (event: any, context: Context) => {
        // TRUNCATED - GET Queue counts
    
        const cloudwatch = new CloudWatch({region: 'eu-west-1'})
        const date = new Date();
    
        // convert queue data into cloudwatch metrics
        const metricData: CloudWatch.Types.MetricData = queues.map((queue): CloudWatch.Types.MetricDatum => ({
            MetricName: queue.name,
            Timestamp: date,
            Unit: 'Count',
            Value: queue.messages,
        }));
    
        const response = await cloudwatch.putMetricData({
                MetricData: metricData,
                Namespace: 'Queue_Messages'
        }).promise();
    
        const result = JSON.stringify(response);
        console.log(result); 
        return result;
    };
    

    【讨论】:

    • 感谢您的建议。我已经厌倦了这两种形式(只是异步/等待,只是回调),没有任何乐趣。每次尝试 6 秒后,lambda 都会超时。
    • 什么是 lambda 超时?也许增加它?
    【解决方案2】:

    您需要将 VPC 端点添加到监控服务以避免超时并连接到 CloudWatch。

    VPC endpoint selection

    然后您可以在 SDK 配置中提及端点的私有 DNS 名称。

    var cloudwatch = new AWS.CloudWatch({
        apiVersion: '2010-08-01',
        endpoint: `https://monitoring.${process.env.REGION}.amazonaws.com`,
        region: process.env.REGION
    });
    

    【讨论】:

      猜你喜欢
      • 2020-04-19
      • 2020-06-25
      • 2019-10-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-20
      • 1970-01-01
      • 1970-01-01
      • 2021-04-09
      相关资源
      最近更新 更多