为什么 Amazon SNS 不在 CloudWatch 警报触发 Lambda 函数时调用该函数?
我希望 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 指标:NumberOfMessagesPublished、NumberOfNotificationsDelivered 或 NumberOfNotificationsFailed。
解决方法
注意:如果您在运行 AWS Command Line Interface (AWS CLI) 命令时遇到错误,请确保您使用的是最新版 AWS CLI。
查看 Lambda 函数基于资源的策略文档
当 Amazon SNS 异步调用 Lambda 函数时,Lambda 将 202 HTTP 状态代码返回给 Amazon SNS。状态代码显示 Lambda 已接受该消息供以后处理。有关更多信息,请参阅异步调用。如果响应失败,可以查看 Amazon SNS 传输日志以了解更多信息。
根据账户中的情况选择解决方法。
如果您的 SNS 主题和 Lambda 函数位于同一账户中:
1. 打开 Lambda 控制台。
2. 在导航窗格上选择 Functions (函数),然后选择您的函数。
3. 选择 Configuration (配置) 选项卡,然后选择 Permissions (权限)。
4. 在基于资源的策略部分中,从 Statement ID (声明 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 CLI 或 AWS 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-name、your-aws-region、your-aws-account-id 和 your-sns-topic-name 替换为您的值。AWS CLI 命令使用默认 AWS 区域。如果 Lambda 函数位于其他区域,可以使用 --region 标记覆盖默认区域。
打开 Lambda 控制台:
1. 打开 Lambda 控制台。
2. 在导航窗格上选择 Functions (函数),然后选择您的函数。
3. 选择 Configuration (配置) 选项卡,再选择 Permissions (权限)。
4. 在基于资源的策略部分中,选择 Add permissions (添加权限)。
5. 对于 Principal (委托人),请选择 sns.amazonaws.com。
6. 对于 Actions (操作),请选择 Lambda:InvokeFunction。
7. 对于 Statement ID (声明 ID),请输入唯一 ID。
8. 选择 Save (保存)。
如果您的 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. 在导航窗格上,展开 Logs (日志),然后选择 Log groups (日志组)。
3. 在筛选器搜索框中,输入 SNS 主题的名称。将显示 SNS 主题的两个日志组:一个为成功日志组,一个为失败日志组。
4. 选择成功日志组。
5. 在 Log streams (日志流) 部分,选择 Search all (搜索所有)。
**注意:**您还可以在 Last event time (上次事件时间) 列中查看请求的时间戳。然后,搜索 Lambda 函数的 Amazon Resource Name (ARN) 和名称。
6. 从 Log stream (日志流) 列中,选择日志流以将其打开。
如果未显示任何结果,请执行以下操作:
1. 选择 Log groups (日志组),然后选择失败日志组。
2. 在 Log streams (日志流) 部分,选择 Search all (搜索所有)。
3. 从 Log stream (日志流) 列中,选择日志流以将其打开。
要排查失败的日志组,请执行以下操作:
1. 检查 Lambda 函数的 X-Ray 跟踪的停留时间是否较长。如果停留时间较长,请使用 CloudWatch 控制台验证您在该区域的 Lambda 函数的错误和限制数是否最少。请务必选择所有函数,然后选择 Errors (错误) 和Throttles (限制) 指标。
**注意:**异步调用的函数之间存在数百个错误和限制会备份内部 Lambda 队列,从而导致函数调用延迟。将错误和限制率保持最低水平是最佳做法,这样就可避免函数调用的不必要延迟。有关更多信息,请参阅异步调用。
2. 设置目标 Amazon Simple Queue Service (Amazon SQS) 队列或 Lambda 函数以进行单独处理。这可以防止消息丢失,而且这样做是因为对于 Lambda 函数来说,异步事件最长可持续 6 个小时。

相关内容
- 已提问 1 个月前lg...
- 已提问 4 个月前lg...
- 已提问 3 个月前lg...
- 已提问 4 个月前lg...
- 已提问 4 个月前lg...
- AWS 官方已更新 5 个月前
- AWS 官方已更新 1 年前
- AWS 官方已更新 7 个月前