

# 使用 Amazon SNS 通知调用 Lambda 函数
<a name="with-sns"></a>

您可以使用 Lambda 函数处理 Amazon Simple Notification Service (Amazon SNS) 通知。Amazon SNS 支持将 Lambda 函数作为发送到主题的消息的目标。您可以将函数订阅到同一账户或其他 Amazon 账户中的主题。有关详细的演练过程，请参阅[教程：将 Amazon Lambda 与 Amazon Simple Notification Service 结合使用](with-sns-example.md)。

Lambda 仅支持标准 SNS 主题的 SNS 触发器。不支持 FIFO 主题。

Lambda 通过对消息进行排队和处理重试来异步处理 SNS 消息。如果无法联系到 Lambda 或消息被拒绝，Amazon SNS 将在几个小时内以递增的间隔重试。有关详细信息，请参阅 Amazon SNS 常见问题中的[可靠性](https://www.amazonaws.cn/sns/faqs/#Reliability)。

**警告**  
Lambda 异步调用至少处理每个事件一次，有可能出现重复处理记录的情况。为避免与重复事件相关的潜在问题，我们强烈建议您将函数代码设为幂等性。要了解更多信息，请参阅 Amazon 知识中心的[如何让我的 Lambda 函数保持幂等性](https://repost.aws/knowledge-center/lambda-function-idempotent)。

## Powertools for Amazon Lambda 中的幂等性实用程序
<a name="services-sns-powertools-idempotency"></a>

Powertools for Amazon Lambda 中的幂等性实用程序使您的 Lambda 函数具有等性。它适用于 Python、TypeScript、Java 和 .NET。有关更多信息，请参阅 *Powertools for Amazon Lambda (Python) 文档*中的[幂等性实用程序](https://docs.powertools.aws.dev/lambda/python/latest/utilities/idempotency/)、*Powertools for Amazon Lambda (TypeScript) 文档*中的[幂等性实用程序](https://docs.amazonaws.cn/powertools/typescript/2.1.1/utilities/idempotency/)、*Powertools for Amazon Lambda (Java) 文档*中的[幂等性实用程序](https://docs.powertools.aws.dev/lambda/java/latest/utilities/idempotency/)以及*Powertools for Amazon Lambda (.NET) 文档*中的[幂等性实用程序](https://docs.powertools.aws.dev/lambda/dotnet/utilities/idempotency/)。

**Topics**
+ [Powertools for Amazon Lambda 中的幂等性实用程序](#services-sns-powertools-idempotency)
+ [使用控制台为 Lambda 函数添​​加 Amazon SNS 主题触发器](#sns-trigger-console)
+ [为 Lambda 函数手动添加 Amazon SNS 主题触发器](#sns-trigger-manual)
+ [示例 SNS 事件形状](#sns-sample-event)
+ [教程：将 Amazon Lambda 与 Amazon Simple Notification Service 结合使用](with-sns-example.md)

## 使用控制台为 Lambda 函数添​​加 Amazon SNS 主题触发器
<a name="sns-trigger-console"></a>

要添加 SNS 主题作为 Lambda 函数的触发器，最简单的方法是使用 Lambda 控制台。当您通过控制台添加触发器时，Lambda 会自动设置必要的权限和订阅以开始从 SNS 主题接收事件。

**添加 SNS 主题作为 Lambda 函数的触发器（控制台）**

1. 打开 Lamba 控制台的[函数页面](https://console.amazonaws.cn/lambda/home#/functions)。

1. 选择您要为其添加触发器的函数的名称。

1. 选择**配置**，然后选择**触发器**。

1. 选择**添加触发器**。

1. 在**触发器配置**下的下拉菜单中，选择 **SNS**。

1. 对于 **SNS 主题**，请选择要订阅的 SNS 主题。

## 为 Lambda 函数手动添加 Amazon SNS 主题触发器
<a name="sns-trigger-manual"></a>

要手动为 Lambda 函数设置 SNS 触发器，您需要完成以下步骤：
+ 为函数定义基于资源的策略，以允许 SNS 调用该函数。
+ 将 Lambda 函数订阅至 Amazon SNS 主题。
**注意**  
如果您的 SNS 主题和 Lambda 函数位于不同的 Amazon 账户中，则还需要授予额外权限以允许跨账户订阅 SNS 主题。有关更多信息，请参阅[授予 Amazon SNS 订阅的跨账户权限](with-sns-example.md#with-sns-subscription-grant-permission)。

您可以使用 Amazon Command Line Interface（Amazon CLI）来完成这两个步骤。首先，要为允许 SNS 调用的 Lambda 函数定义基于资源的策略，请使用以下 Amazon CLI 命令。请务必将 `--function-name` 的值替换为您的 Lambda 函数名称，将 `--source-arn` 的值替换为您的 SNS 主题 ARN。

```
aws lambda add-permission --function-name example-function \
    --source-arn arn:aws:sns:us-east-1:123456789012:sns-topic-for-lambda \
    --statement-id function-with-sns --action "lambda:InvokeFunction" \
    --principal sns.amazonaws.com
```

要将您的函数订阅到 SNS 主题，请使用以下 Amazon CLI 命令。将 `--topic-arn` 的值替换为您的 SNS 主题 ARN，将 `--notification-endpoint` 的值替换为您的 Lambda 函数 ARN。

```
aws sns subscribe --protocol lambda \
    --region us-east-1 \
    --topic-arn arn:aws:sns:us-east-1:123456789012:sns-topic-for-lambda \
    --notification-endpoint arn:aws:lambda:us-east-1:123456789012:function:example-function
```

## 示例 SNS 事件形状
<a name="sns-sample-event"></a>

Amazon SNS 通过包含消息和元数据的事件[异步](invocation-async.md)调用您的函数。

**Example Amazon SNS 消息事件**  

```
{
  "Records": [
    {
      "EventVersion": "1.0",
      "EventSubscriptionArn": "arn:aws:sns:cn-north-1:123456789012:sns-lambda:21be56ed-a058-49f5-8c98-aedd2564c486",
      "EventSource": "aws:sns",
      "Sns": {
        "SignatureVersion": "1",
        "Timestamp": "2019-01-02T12:45:07.000Z",
        "Signature": "tcc6faL2yUC6dgZdmrwh1Y4cGa/ebXEkAi6RibDsvpi+tE/1+82j...65r==",
        "SigningCertUrl": "https://sns.cn-north-1.amazonaws.com.cn/SimpleNotificationService-ac565b8b1a6c5d002d285f9598aa1d9b.pem",
        "MessageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e",
        "Message": "Hello from SNS!",
        "MessageAttributes": {
          "Test": {
            "Type": "String",
            "Value": "TestString"
          },
          "TestBinary": {
            "Type": "Binary",
            "Value": "TestBinary"
          }
        },
        "Type": "Notification",
        "UnsubscribeUrl": "https://sns.cn-north-1.amazonaws.com.cn/?Action=Unsubscribe&amp;SubscriptionArn=arn:aws:sns:cn-north-1:123456789012:test-lambda:21be56ed-a058-49f5-8c98-aedd2564c486",
        "TopicArn":"arn:aws:sns:cn-north-1:123456789012:sns-lambda",
        "Subject": "TestInvoke"
      }
    }
  ]
}
```