为什么 Amazon SNS 不在 CloudWatch 警报触发 Lambda 函数时调用该函数?

2 分钟阅读
0

我希望 Amazon Simple Notification Service (Amazon SNS) 在 Amazon CloudWatch 警报触发 AWS Lambda 函数时调用该函数。

简短描述

以下情况会阻止您调用 Lambda 函数:

  • Lambda 函数的资源策略尚未授予从 SNS 主题调用该函数的权限。对于此种情况,请完成查看 Lambda 函数基于资源的策略文档部分中的步骤。
  • Lambda 函数调用出现延迟。对于此种情况,请完成查看您的 Amazon SNS 传输日志部分中的步骤。

**注意:**以下解决方法假设您可以在 SNS 主题上调用 Publish API,但在 Amazon SNS 和 Lambda 集成之间出现错误。如果在 SNS 主题上看不到任何活动,请参阅为什么在 CloudWatch 警报触发时,我没有收到 SNS 通知?该活动可以包括以下 CloudWatch 指标: NumberOfMessagesPublishedNumberOfNotificationsDeliveredNumberOfNotificationsFailed

解决方法

**注意:**如果您在运行 AWS 命令行界面(AWS CLI)命令时收到错误,请参阅排查 AWS CLI 错误。此外,请确保您使用的是最新版本的 AWS CLI

查看 Lambda 函数基于资源的策略文档

当 Amazon SNS 异步调用 Lambda 函数时,Lambda 会将 202 HTTP 状态代码返回给 Amazon SNS。状态代码显示 Lambda 已接受该消息供以后处理。有关更多信息,请参阅 Asynchronous invocation。如果响应失败,请查看 Amazon SNS 传输日志以了解更多信息。

根据账户中的情况选择解决方法。

如果 SNS 主题和 Lambda 函数位于同一个账户中,请执行下列操作:

1.    打开 Lambda 控制台

2.    在导航窗格上,选择函数,然后选择您的函数。

3.    选择配置选项卡,然后选择权限

4.    在基于资源的策略部分中,从语句 ID 列中选择策略语句,以查看您的策略文档。您会看到以下策略文档:

statement id
your-statement-id

principal:
sns.amazonaws.com

effect
allow

action
Lambda:InvokeFunction

conditions
{ "arnlike": { "aws:sourcearn": "arn:aws:sns:your-aws-region:your-aws-account-id:your-sns-topic-name" }

注意:要以 JSON 格式查看策略文档,请在基于资源的策略部分选择查看策略文档

如果您缺少授予 Amazon SNS 调用该函数的权限的 Lambda 资源策略,请将以下函数添加到您的策略文档中。请使用 Lambda 控制台或者 AWS CLIAWS CloudShell

使用以下命令行:

aws lambda add-permission \
--function-name your-lambda-function-name \
--statement-id triggerfromsns-statement-id \
--action lambda:invokefunction \
--principal sns.amazonaws.com \
--source-arn arn:aws:sns:your-aws-region:your-aws-account-id:your-sns-topic-name

**注意:**请将 your-lambda-function-nameyour-aws-regionyour-aws-account-idyour-sns-topic-name 替换为您的值。AWS CLI 命令使用默认 AWS 区域。如果 Lambda 函数位于其他区域,可以使用 --region 标志覆盖默认区域。

按如下方式,使用 Lambda 控制台:

1.    打开 Lambda 控制台

2.    在导航窗格上,选择函数,然后选择您的函数。

3.    选择配置选项卡,然后选择权限

4.    在基于资源的策略部分,选择添加权限

5.    对于主体,选择 sns.amazonaws.com

6.    对于操作,选择 Lambda:InvokeFunction

7.    对于语句 ID,输入唯一 ID。

8.    选择保存

如果 SNS 主题和 Lambda 函数位于不同的账户中,请执行下列操作:

1.    设置跨账户权限

2.    在 CloudWatch 日志中,使用传输状态日志记录验证 Amazon SNS 是否已成功向 Lambda 或 NumberOfNotificationsDelivered CloudWatch 指标发送消息。

Amazon SNS 和 Lambda 之间的成功响应示例:

{
    "notification": {
        "messagemd5sum": "your-md5-sum",
        "messageid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
        "topicarn": "arn:aws:sns:your-aws-region:your-aws-account-id:your-sns-topic",
        "timestamp": "2021-04-04 14:08:48.083"
    },
    "delivery": {
        "deliveryid": "your-sns-delivery-id",
        "destination": "arn:aws:lambda:your-aws-region:your-aws-account-id:function:your-function-name",
        "providerresponse": "{\ "lambdarequestid\":\ "your-lambda-request-id\"}",
        "dwelltimems": 92,
        "attempts": 1,
        "statuscode": 202
    },
        "status": "success"
}

查看 Amazon SNS 传输日志

查看您的 SNS 主题针对 Lambda 函数的传输日志。 如果响应成功,您会看到 202 状态代码。

要查看 SNS 主题的 CloudWatch 日志,请执行以下操作:

1.    打开 CloudWatch 控制台

2.    在导航窗格上,展开日志,然后选择日志组

3.    在筛选条件搜索框中,输入 SNS 主题的名称。将显示 SNS 主题的两个日志组:一个为成功日志组,一个为失败日志组。

4.    选择成功日志组。

5.    在日志流部分中,选择全部搜索

注意:您还可以在上次事件时间列中查看请求的时间戳。然后,搜索 Lambda 函数的 Amazon 资源名称(ARN)和名称。

6.    从日志流列中,选择日志流以将其打开。

如果未显示任何结果,请执行以下操作:

1.    选择日志组,然后选择失败日志组。

2.    在日志流部分中,选择全部搜索

3.    从日志流列中,选择日志流以将其打开。

要排查失败的日志组,请执行以下操作:

1.    检查 Lambda 函数的 X-Ray 跟踪停留时间是否较长。如果是,请使用 CloudWatch 控制台验证您在该区域的 Lambda 函数的错误和限制数是否最少。请务必选择所有函数,然后选择错误限制指标。

**注意:**当异步调用函数之间的数百个错误和限制时,内部 Lambda 队列会进行备份。  此备份可能会导致函数调用延迟。最佳做法是将错误和限制率保持最低水平,以避免不必要的延迟。有关更多信息,请参阅 Asynchronous invocation

2.    设置目标 Amazon Simple Queue Service (Amazon SQS) 队列或 Lambda 函数以进行单独处理。这可以防止消息丢失,而且这样做是因为对于 Lambda 函数来说,异步事件最长可持续 6 个小时。

AWS 官方
AWS 官方已更新 3 个月前