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

上次更新日期:2022 年 11 月 4 日

我正在使用 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 函数没有受到限制

确认您的 Lambda 函数与 SNS 主题位于同一个区域

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

查看您的 Lambda 函数的 Amazon 资源名称(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'});

这篇文章对您有帮助吗?


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