为什么 Amazon SNS 不调用我的 AWS Lambda 函数,我该如何解决问题?

上次更新时间:2021 年 6 月 3 日

我正在使用 AWS Lambda 函数来处理 Amazon Simple Notification Service (Amazon SNS) 通知,但我的 Amazon SNS 主题没有调用该函数。如何对未调用 Lambda 函数的 Amazon SNS 通知进行故障排除?

简短描述

Amazon SNS 消息事件无法调用订阅了 SNS 主题的 Lambda 函数有五个原因:

解决方法

重要提示:如果您尚未这样做,请为 Amazon SNS 主题配置 Amazon CloudWatch 交付状态日志记录。有关更多信息,请参阅使用 CloudWatch 监控 Amazon SNS 主题

确认向 SNS 主题发布的 IAM 身份具有发布到 SNS 主题所需的权限

请查看适用于 Amazon SNS 的 Amazon CloudWatch 指标中的 NumberOfMessagesPublished 的指标。如果您用来调用函数的 IAM 实体发出的发布请求没有记录在 NumberOfMessagesPublished 指标中,请执行以下操作:

1.    确认发出 Publish API 请求的 IAM 实体具有发布到 SNS 主题所需的权限。有关更多信息和具体策略声明示例,请参阅 Amazon SNS 访问控制示例案例

2.    确认 SNS 主题的权限策略允许进行 Publish API 调用的 IAM 实体使用 “SNS:Publish”操作。有关更多信息和示例权限策略,请参阅 Amazon SNS 的权限主题

确认您的 Lambda 函数具有允许 Amazon SNS 调用该函数所需的权限

要查看函数的权限策略,请按照对 AWS Lambda 使用基于资源的策略中的说明进行操作。如果函数的策略不包括 SNS 主题的“lambda:invokeFunction”操作,请更新策略以包含所需的权限

请确认您的 Lambda 函数的筛选条件策略与从 SNS 主题发送的消息属性匹配

查看适用于 Amazon SNS 的 CloudWatch 指标中的 NumberOfNotificationsFilteredOut 指标。如果您用来调用函数并由 IAM 实体发出的发布请求出现在 NumberOfNotificationsFilteredOut 指标中,请执行以下操作:

1.    通过执行以下操作查看 Lambda 函数的 SNS 主题订阅筛选条件策略:
打开 Amazon SNS 控制台
在左侧导航窗格上,选择 Subscriptions(订阅)。
Edit 页面上,展开 Subscription filter policy(订阅筛选条件策略)部分。

2.    查看订阅筛选条件策略以确认 Publish 请求消息属性与筛选条件策略所要求的属性匹配。如果属性不匹配,请更新 Publish 请求消息属性,使其与筛选条件策略所需的属性匹配。

注意:有关更多信息,请参阅 Amazon SNS 订阅筛选条件策略

确认您的 Lambda 函数没有受到限制

(对于在商业区域中托管的 SNS 主题)确认您的 Lambda 函数与 SNS 主题位于同一个区域

注意:托管在商业 AWS 区域中的 Amazon SNS 主题无法调用不在商业区域内的 Lambda 函数。有关 Amazon SNS 支持的 AWS 区域的当前列表,请参阅 Amazon Simple Notification Service 终端节点和配额

查看您的 Lambda 函数的 Amazon Resource Name (ARN) 和 Amazon SNS 主题。如果 Amazon SNS 主题托管在商业 AWS 区域中,并且该函数托管在选择加入区域中,请执行以下操作:

1.    在与 Amazon SNS 主题所在相同的区域中创建新的 Lambda 函数

2.    配置函数的设置,以便它对托管在选择加入区域中的函数进行 Invoke API 调用。

重要提示:确保更新 SDK 区域设置

用于更改区域设置的 Python (Boto 3) 命令示例

#us-east-1 client
lambda_us_east_1_client = boto3.client('lambda',  region_name='us-east-1')
#us_west_1 client
lambda_us_west_1_client = boto3.client('lambda',  region_name='us-west-1')

用于更改区域设置的 JavaScript/Node.js 命令示例

//us-east-1 client
var lambda_us_east_1_client = new AWS.Lambda({apiVersion: '2015-03-31',region: 'us-east-1'});
//us_west_1 client
var lambda_us_east_1_client = new AWS.Lambda({apiVersion: '2015-03-31', region: 'us-west-1'});

这篇文章对您有帮助吗?


您是否需要账单或技术支持?