

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 使用 Amazon SNS 发送消息 application-to-application
<a name="sns-system-to-system-messaging"></a>

Amazon SNS 通过将发布者与订阅者分开来简化 application-to-application (A2A) 消息传递，后者支持微服务、分布式系统和无服务器应用程序。消息会发送到 Amazon SNS 主题，在那里可以对其进行筛选并发送给 Lambda、Amazon SQS 或 HTTP 端点等订阅用户。如果传输失败，消息将存储在死信队列中，以供进一步分析或重新处理。

![\[Amazon SNS 通过将发布者与使用主题的订阅者分离开来，从而为 application-to-application消息传递提供便利。来自系统或服务的消息通过 Amazon SNS 主题进行路由，在那里可以对其进行筛选并分发给 Lambda、Amazon SQS 或电子邮件系统等订阅用户。如果传输失败，消息将存储在死信队列中，以供稍后分析或重新处理。\]](http://docs.aws.amazon.com/zh_cn/sns/latest/dg/images/sns-a2a-overview.png)


# 扇出到 Firehose 传输流
<a name="sns-firehose-as-subscriber"></a>

您可以为 Amazon SNS 主题订阅[传输流](https://docs.aws.amazon.com/firehose/latest/dev/what-is-this-service.html)，从而使您能够将通知发送到其他存储和分析端点。发布到 Amazon SNS 主题的消息将发送到订阅的 Firehose 传输流，并按照 Firehose 中配置的方式传输到目标。订阅所有者最多可以为 Amazon SNS 主题订阅五个 Firehose 传输流。每个 Firehose 传输流对于每秒请求量和吞吐量都有一个[原定设置限额](https://docs.aws.amazon.com/firehose/latest/dev/limits.html)。此限制可能会导致发布的消息（入站流量）多于传输的消息（出站流量）。当入站流量多于出站流量时，您的订阅可能会累积大量的消息积压，从而可能会导致较长的消息传输延迟。您可以根据发布率请求[增加限额](https://support.console.aws.amazon.com/support/home#/case/create?issueType=service-limit-increase)，以避免对您的工作负载产生不利影响。

通过Firehose传送流，您可以将亚马逊SNS通知分发给亚马逊简单存储服务（Amazon S3）、亚马逊Redshift、亚马逊服务（服务）以及第三方OpenSearch 服务提供商，例如Datadog、 OpenSearch New Relic、MongoDB和Splunk。

例如，您可以使用此功能将发送到 Amazon S3 存储桶中的主题的消息永久存储以用于合规性、存档或其他目的。为此，请使用 Amazon S3 存储桶目标创建 Firehose 传输流，并为 Amazon SNS 主题订阅该传输流。再举一个例子，要对发送到 Amazon SNS 主题的消息进行分析，请创建带有 OpenSearch 服务索引目标的传输流。然后，您可以为 Amazon SNS 主题订阅 Firehose 传输流。

Amazon SNS 还支持针对发送到 Firehose 端点的通知进行消息传输状态日志记录。有关更多信息，请参阅 [Amazon SNS 消息传输状态](sns-topic-attributes.md)。

# 订阅 Firehose 传输流到 Amazon SNS 主题的先决条件
<a name="prereqs-kinesis-data-firehose"></a>

要订阅 SNS 主题的直播流，您 AWS 账户 必须具备以下条件：
+ 标准 SNS 主题。有关更多信息，请参阅 [创建 Amazon SNS 主题](sns-create-topic.md)。
+ Firehose 传输流。有关更多信息，请参阅《Amazon Data Firehose 开发人员指南》**中的[创建传输流](https://docs.aws.amazon.com/firehose/latest/dev/basic-create.html)和[授予应用程序对 Firehose 资源的访问权限](https://docs.aws.amazon.com/firehose/latest/dev/controlling-access.html#access-to-firehose)。
+ 信任 Amazon SNS 服务委托人并有权写入传输流的 AWS Identity and Access Management (IAM) 角色。创建订阅时，您将输入此角色的 Amazon Resource Name (ARN) 作为 `SubscriptionRoleARN`。Amazon SNS 担任此角色，它允许 Amazon SNS 将记录放入 Firehose 传输流中。

  下面的示例策略显示了建议的权限：

------
#### [ JSON ]

****  

  ```
  {
    "Version":"2012-10-17",		 	 	 
    "Statement": [
      {
        "Action": [
          "firehose:DescribeDeliveryStream",
          "firehose:ListDeliveryStreams",
          "firehose:ListTagsForDeliveryStream",
          "firehose:PutRecord",
          "firehose:PutRecordBatch"
        ],
        "Resource": [
          "arn:aws:firehose:us-east-1:111111111111:deliverystream/firehose-sns-delivery-stream"
        ],
        "Effect": "Allow"
      }
    ]
  }
  ```

------

  要提供使用 Firehose 的完全权限，您还可以使用 AWS 托管策略。`AmazonKinesisFirehoseFullAccess`或者，要为使用 Firehose 提供更严格的权限，您可以创建自己的策略。至少，策略必须提供在特定传输流上运行 `PutRecord` 操作的权限。

  在所有情况下，您都还必须编辑信任关系以包括 Amazon SNS 服务委托人。例如：

------
#### [ JSON ]

****  

  ```
  {
    "Version":"2012-10-17",		 	 	 
    "Statement": [
      {
        "Effect": "Allow",
        "Principal": {
          "Service": "sns.amazonaws.com"
        },
        "Action": "sts:AssumeRole"
      }
    ]
  }
  ```

------

  有关创建角色的更多信息，请参阅 *IAM 用户指南*中的[创建角色以向 AWS 服务委派权限](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-service.html)。

完成这些要求后，您可以[将传输流订阅到 SNS 主题](firehose-endpoints-subscribe.md)。

# 将 Firehose 传输流订阅到 Amazon SNS 主题
<a name="firehose-endpoints-subscribe"></a>

要将 Amazon SNS 通知传输至[传输流](sns-firehose-as-subscriber.md)，首先确保您已符合所有[先决条件](prereqs-kinesis-data-firehose.md)。有关受支持端点的列表，请参阅《Amazon Web Services 一般参考》**中的[端点和配额](https://docs.aws.amazon.com/general/latest/gr/fh.html)。

**将 Firehose 传输流订阅到主题**

1. 登录 [Amazon SNS 控制台](https://console.aws.amazon.com/sns/home)。

1. 在导航窗格中，选择**订阅**。

1. 在**订阅**页面上，选择**创建订阅**。

1. 在**创建订阅**页上的**详细信息**部分，执行以下操作：

   1. 对于 **Topic ARN**（主题 ARN），选择标准主题的 Amazon Resource Name (ARN)。

   1. 对于**协议**，选择 **Firehose**。

   1. 对于**端点**，选择可从 Amazon SNS 中接收通知的 Firehose 传输流的 ARN。

   1. 对于**订阅角色 ARN**，指定您为写入到 Firehose 传输流创建的 AWS Identity and Access Management （IAM）角色的 ARN。有关更多信息，请参阅 [订阅 Firehose 传输流到 Amazon SNS 主题的先决条件](prereqs-kinesis-data-firehose.md)。

   1. （可选）要从已发布消息中删除任何 Amazon SNS 元数据，请选择 **Enable raw message delivery**（启用原始消息传输）。有关更多信息，请参阅 [Amazon SNS 原始消息传输](sns-large-payload-raw-message-delivery.md)。

1. （可选）要配置筛选策略，请展开 **Subscription filter policy**（订阅筛选策略）部分。有关更多信息，请参阅 [Amazon SNS 订阅筛选策略](sns-subscription-filter-policies.md)。

1. （可选）要为订阅配置死信队列，请展开 **Redrive policy (dead-letter queue)**（重新驱动策略（死信队列））部分。有关更多信息，请参阅 [Amazon SNS 死信队列](sns-dead-letter-queues.md)。

1. 选择**创建订阅**。

控制台将创建订阅并打开订阅的 **Details**（详细信息）页面。

# 管理跨多个传送流目标的 Amazon SNS 消息
<a name="firehose-working-with-destinations"></a>

[传输流](sns-firehose-as-subscriber.md)允许您管理跨多个目的地的 Amazon SNS 消息，从而实现与亚马逊 S3、亚马逊 OpenSearch 服务、Amazon Redshift 和 HTTP 终端节点的集成，用于存储、索引和分析。通过正确配置消息格式和传送，您可以将 Amazon SNS 通知存储在 Amazon S3 中以供日后处理，使用 Amazon Athena 分析结构化消息数据，为消息编制索引以进行实时搜索和可视化， OpenSearch 在 Amazon Redshift 中结构化存档以进行高级查询。

# 分析 Amazon SNS 消息并将其存储在 Amazon S3 目标中
<a name="firehose-s3-destinations"></a>

本主题介绍传输流如何将数据发布到 Amazon Simple Storage Service（Amazon S3）。

![\[Amazon 消息处理服务的集成和工作流程。它显示了发布者如何向 Amazon SNS 主题发送消息，然后该主题将消息扇出到多个 Amazon SQS 队列和 Data Firehose 传输流。然后，可通过 Lambda 函数来处理消息，也可以永久存储在 Amazon S3 存储桶中。\]](http://docs.aws.amazon.com/zh_cn/sns/latest/dg/images/firehose-architecture-s3.png)


**Topics**
+ [格式化通知以存储在 Amazon S3 目标中](firehose-archived-message-format-S3.md)
+ [使用 Athena 分析在 Amazon S3 中存储的消息](firehose-message-analysis-s3.md)

# 格式化 Amazon SNS 通知以存储在 Amazon S3 目标中
<a name="firehose-archived-message-format-S3"></a>

以下示例显示了一条发送到 Amazon Simple Storage Service (Amazon S3) 存储桶的 Amazon SNS 通知，其中使用了缩进以增强可读性。

**注意**  
在此示例中，已发布消息的原始消息传输被禁用。禁用原始邮件传输时，Amazon SNS 会将 JSON 元数据添加到消息中，其中包括以下属性：  
`Type`
`MessageId`
`TopicArn`
`Subject`
`Timestamp`
`UnsubscribeURL`
`MessageAttributes`
有关原始消息传输的更多信息，请参阅 [Amazon SNS 原始消息传输](sns-large-payload-raw-message-delivery.md)。

```
{
    "Type": "Notification",
    "MessageId": "719a6bbf-f51b-5320-920f-3385b5e9aa56",
    "TopicArn": "arn:aws:sns:us-east-1:333333333333:my-kinesis-test-topic",     
    "Subject": "My 1st subject",
    "Message": "My 1st body",
    "Timestamp": "2020-11-26T23:48:02.032Z",
    "UnsubscribeURL": "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:333333333333:my-kinesis-test-topic:0b410f3c-ee5e-49d8-b59b-3b4aa6d8fcf5",
    "MessageAttributes": {
        "myKey1": {
            "Type": "String",
            "Value": "myValue1"
        },
        "myKey2": {
            "Type": "String",
            "Value": "myValue2"
        }
    }
 }
```

以下示例显示了通过一个传输流发送到同一 Amazon S3 存储桶的三条 SNS 消息。消息进行了缓冲，每条消息之间以换行分隔。

```
{"Type":"Notification","MessageId":"d7d2513e-6126-5d77-bbe2-09042bd0a03a","TopicArn":"arn:aws:sns:us-east-1:333333333333:my-kinesis-test-topic","Subject":"My 1st subject","Message":"My 1st body","Timestamp":"2020-11-27T00:30:46.100Z","UnsubscribeURL":"https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:313276652360:my-kinesis-test-topic:0b410f3c-ee5e-49d8-b59b-3b4aa6d8fcf5","MessageAttributes":{"myKey1":{"Type":"String","Value":"myValue1"},"myKey2":{"Type":"String","Value":"myValue2"}}}
{"Type":"Notification","MessageId":"0c0696ab-7733-5bfb-b6db-ce913c294d56","TopicArn":"arn:aws:sns:us-east-1:333333333333:my-kinesis-test-topic","Subject":"My 2nd subject","Message":"My 2nd body","Timestamp":"2020-11-27T00:31:22.151Z","UnsubscribeURL":"https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:313276652360:my-kinesis-test-topic:0b410f3c-ee5e-49d8-b59b-3b4aa6d8fcf5","MessageAttributes":{"myKey1":{"Type":"String","Value":"myValue1"}}}
{"Type":"Notification","MessageId":"816cd54d-8cfa-58ad-91c9-8d77c7d173aa","TopicArn":"arn:aws:sns:us-east-1:333333333333:my-kinesis-test-topic","Subject":"My 3rd subject","Message":"My 3rd body","Timestamp":"2020-11-27T00:31:39.755Z","UnsubscribeURL":"https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:313276652360:my-kinesis-test-topic:0b410f3c-ee5e-49d8-b59b-3b4aa6d8fcf5"}
```

# 使用 Athena 分析在 Amazon S3 中存储的 Amazon SNS 消息
<a name="firehose-message-analysis-s3"></a>

本页面介绍如何分析通过传输流发送到 Amazon Simple Storage Service（Amazon S3）目标的 Amazon SNS 消息。

**要分析通过 Firehose 传输流发送到 Amazon S3 目标的 SNS 消息**

1. 配置 Amazon S3 资源。有关说明，请参阅 *Amazon Simple Storage Service 用户指南*中的[创建存储桶](https://docs.aws.amazon.com/AmazonS3/latest/userguide/CreatingABucket.html)和 *Amazon Simple Storage Service 用户指南*中的[使用 Amazon S3 存储桶](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingBucket.html)。

1. 配置传输流。有关说明，请参阅《Amazon Data Firehose 开发人员指南》**中的[选择 Amazon S3 作为目标](https://docs.aws.amazon.com/firehose/latest/dev/create-destination.html#create-destination-s3)。

1. 使用 [Amazon Athena](https://console.aws.amazon.com/athena) 通过标准的 SQL 查询 Amazon S3 对象。有关更多信息，请参阅 *Amazon Athena 用户指南*中的[入门](https://docs.aws.amazon.com/athena/latest/ug/getting-started.html)。

## 示例查询
<a name="example-s3-query"></a>

在本示例查询中，我们假设满足以下条件：
+ 消息存储在 `default` schema 的 `notifications` 表中。
+ `notifications` 表包含一个类型为 `string` 的 `timestamp` 列。

以下查询返回在指定日期范围内收到的所有 SNS 消息：

```
SELECT * 
FROM default.notifications
WHERE from_iso8601_timestamp(timestamp) BETWEEN TIMESTAMP '2020-12-01 00:00:00' AND TIMESTAMP '2020-12-02 00:00:00';
```

# 将 Amazon SNS 消息与亚马逊 OpenSearch 服务目标集成
<a name="firehose-elasticsearch-destinations"></a>

本节介绍交付流如何将数据发布到亚马逊 OpenSearch 服务（OpenSearch 服务）。

![\[发布者向 Amazon SNS 主题发送消息，该主题随后将这些消息分发到多个 Amazon SQS 队列。来自这些队列的消息可以由 Lambda 函数处理，也可以通过 Data Firehose 传输流发送到亚马逊 OpenSearch 服务，从而创建可搜索的消息索引。此设置演示了使用 AWS 服务的高级消息路由和处理方案。\]](http://docs.aws.amazon.com/zh_cn/sns/latest/dg/images/firehose-architecture-es.png)


**Topics**
+ [存档消息格式](firehose-archived-message-format-elasticsearch.md)
+ [分析消息](firehose-message-analysis-elasticsearch.md)

# 在服务索引中 OpenSearch 存储和格式化 Amazon SNS 通知
<a name="firehose-archived-message-format-elasticsearch"></a>

以下示例演示了向名为的亚马逊 OpenSearch 服务（OpenSearch 服务）索引发送的 Amazon SNS 通知。`my-index`此索引在 `Timestamp` 字段中具有时间筛选字段。SNS 通知放置在负载的 `_source` 属性中。

**注意**  
在此示例中，已发布消息的原始消息传输被禁用。禁用原始邮件传输时，Amazon SNS 会将 JSON 元数据添加到消息中，其中包括以下属性：  
`Type`
`MessageId`
`TopicArn`
`Subject`
`Timestamp`
`UnsubscribeURL`
`MessageAttributes`
有关原始消息传输的更多信息，请参阅 [Amazon SNS 原始消息传输](sns-large-payload-raw-message-delivery.md)。

```
{
  "_index": "my-index",
  "_type": "_doc",
  "_id": "49613100963111323203250405402193283794773886550985932802.0",
  "_version": 1,
  "_score": null,
  "_source": {
    "Type": "Notification",
    "MessageId": "bf32e294-46e3-5dd5-a6b3-bad65162e136",
    "TopicArn": "arn:aws:sns:us-east-1:111111111111:my-topic",
    "Subject": "Sample subject",
    "Message": "Sample message",
    "Timestamp": "2020-12-02T22:29:21.189Z",
    "UnsubscribeURL": "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:111111111111:my-topic:b5aa9bc1-9c3d-452b-b402-aca2cefc63c9",
    "MessageAttributes": {
      "my_attribute": {
        "Type": "String",
        "Value": "my_value"
      }
    }
  },
  "fields": {
    "Timestamp": [
      "2020-12-02T22:29:21.189Z"
    ]
  },
  "sort": [
    1606948161189
  ]
}
```

# 分析服务目标的 Amazon SNS OpenSearch 消息
<a name="firehose-message-analysis-elasticsearch"></a>

本主题介绍如何分析通过传送流发送到亚马逊 OpenSearch 服务（OpenSearch 服务）目标的 Amazon SNS 消息。

**分析通过 Firehose 发送到服务目标的传送流 OpenSearch 的 SNS 消息**

1. 配置您的 OpenSearch 服务资源。有关说明，请参阅《[亚马逊 OpenSearch 服务*开发者指南》中的 “亚马逊 OpenSearch 服务*入门](https://docs.aws.amazon.com/opensearch-service/latest/developerguide/es-gsg.html)”。

1. 配置传输流。有关说明，请参阅 *Amazon Data Firehose 开发者*指南中的[为您的目的地选择 OpenSearch 服务](https://docs.aws.amazon.com/firehose/latest/dev/create-destination.html#create-destination-elasticsearch)。

1. 使用 OpenSearch 服务查询和 Kibana 运行查询。有关更多信息，请参阅《*亚马逊 OpenSearch 服务开发者*指南》[中的步骤 3：在 OpenSearch 服务域中搜索文档](https://docs.aws.amazon.com/opensearch-service/latest/developerguide/es-gsg-search.html)和 [Kibana](https://docs.aws.amazon.com/opensearch-service/latest/developerguide/es-kibana.html)。

## 示例查询
<a name="example-es-query"></a>

以下示例查询指定日期范围内接收的所有 SNS 消息的 `my-index` 索引：

```
POST https://search-my-domain.us-east-1.es.amazonaws.com/my-index/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "range": {
            "Timestamp": {
              "gte": "2020-12-08T00:00:00.000Z",
              "lte": "2020-12-09T00:00:00.000Z",
              "format": "strict_date_optional_time"
            }
          }
        }
      ]
    }
  }
}
```

# 在 Amazon Redshift 目标中配置 Amazon SNS 消息传输和分析
<a name="firehose-redshift-destinations"></a>

本主题介绍如何将 Amazon SNS 通知扇出到传输流，然后传输流将数据发布到 Amazon Redshift。通过此设置，您可以连接到 Amazon Redshift 数据库，并使用 SQL 查询工具检索符合特定标准的 Amazon SNS 消息。

![\[发送者向 Amazon SNS 主题发布的消息将分发到多个 Amazon SQS 队列由 Lambda 函数进行处理，还会通过 Data Firehose 传输流发送到 Amazon Redshift 集群，以便在消息数据仓库中存储和分析。此设置使用 AWS 服务演示了强大的消息处理和数据仓库架构。\]](http://docs.aws.amazon.com/zh_cn/sns/latest/dg/images/firehose-architecture-rs.png)


**Topics**
+ [在 Amazon Redshift 表中构造消息归档](firehose-archive-table-structure-redshift.md)
+ [分析存储在 Amazon Redshift 目标中的消息](firehose-message-analysis-redshift.md)

# 在 Amazon Redshift 表中构造 Amazon SNS 消息归档
<a name="firehose-archive-table-structure-redshift"></a>

对于 Amazon Redshift 端点，Amazon SNS 消息会作为表中的行进行归档。下面是数据存储方式的示例：

**注意**  
在此示例中，已发布消息的原始消息传输被禁用。禁用原始邮件传输时，Amazon SNS 会将 JSON 元数据添加到消息中，其中包括以下属性：  
`Type`
`MessageId`
`TopicArn`
`Subject`
`Message`
`Timestamp`
`UnsubscribeURL`
`MessageAttributes`
有关原始消息传输的更多信息，请参阅 [Amazon SNS 原始消息传输](sns-large-payload-raw-message-delivery.md)。  
尽管 Amazon SNS 使用此列表中显示的大写向邮件添加了属性，但 Amazon Redshift 表中的列名称以所有小写字符显示。要转换 Amazon Redshift 终端节点的 JSON 元数据，您可以使用 SQL `COPY` 命令。有关更多信息，请参阅 *Amazon Redshift 数据库开发人员指南*中的[从 JSON 中复制示例](https://docs.aws.amazon.com/redshift/latest/dg/r_COPY_command_examples.html#r_COPY_command_examples-copy-from-json)和[使用“auto ignorecase”选项从 JSON 数据中加载](https://docs.aws.amazon.com/redshift/latest/dg/r_COPY_command_examples.html#copy-from-json-examples-using-auto-ignorecase)。


|  类型  |  messageid  |  topicarn  |  subject  |  message  |  timestamp  |  unsubscribeurl  |  messageattributes  | 
| --- | --- | --- | --- | --- | --- | --- | --- | 
|  通知  |  ea544832-a0d8-581d-9275-108243c46103  |  arn:aws:sns:us-east-1:111111111111:my-topic  |  示例主题  |  示例消息  |  2020-12-02T00:33:32.272Z  |  https://sns.us-east-1.amazonaws.com/？ Action=unsubscribe& =arnSubscriptionArn: aws: sns: us-east-1:111111111111:my-topic: 326deeeb-cbf4-45da-b92b-ca77a247813b  |  \$1\$1"my\$1attribute\$1":\$1\$1"Type\$1":\$1"String\$1",\$1"Value\$1":\$1"my\$1value\$1"\$1\$1  | 
|  通知  |  ab124832-a0d8-581d-9275-108243c46114  |  arn:aws:sns:us-east-1:111111111111:my-topic  |  示例主题 2  |  示例消息 2  |  2020-12-03T00:18:11.129Z  |  https://sns.us-east-1.amazonaws.com/？ Action=unsubscribe& =arnSubscriptionArn: aws: sns: us-east-1:111111111111:my-topic: 326deeeb-cbf4-45da-b92b-ca77a247813b  |  \$1\$1"my\$1attribute2\$1":\$1\$1"Type\$1":\$1"String\$1",\$1"Value\$1":\$1"my\$1value\$1"\$1\$1  | 
|  通知  |  ce644832-a0d8-581d-9275-108243c46125  |  arn:aws:sns:us-east-1:111111111111:my-topic  |  示例主题 3  |  示例消息 3  |  2020-12-09T00:08:44.405Z  |  https://sns.us-east-1.amazonaws.com/？ Action=unsubscribe& =arnSubscriptionArn: aws: sns: us-east-1:111111111111:my-topic: 326deeeb-cbf4-45da-b92b-ca77a247813b  |  \$1\$1"my\$1attribute3\$1":\$1\$1"Type\$1":\$1"String\$1",\$1"Value\$1":\$1"my\$1value\$1"\$1\$1  | 

有关向 Amazon Redshift 终端节点扇出通知的更多信息，请参阅 [在 Amazon Redshift 目标中配置 Amazon SNS 消息传输和分析](firehose-redshift-destinations.md)。

# 分析存储在 Amazon Redshift 目标中的 Amazon SNS 消息
<a name="firehose-message-analysis-redshift"></a>

本主题介绍如何分析通过传输流发送到 Amazon Redshift 目标的 Amazon SNS 消息。

**要分析通过 Firehose 传输流发送到 Amazon Redshift 目标的 SNS 消息**

1. 配置您的 Amazon Redshift 资源。有关说明，请参阅 *Amazon Redshift 入门指南*中的[Amazon Redshift 入门](https://docs.aws.amazon.com/redshift/latest/gsg/getting-started.html)。

1. 配置传输流。有关说明，请参阅《Amazon Data Firehose 开发人员指南》**中的[选择 Amazon Redshift 作为目标](https://docs.aws.amazon.com/firehose/latest/dev/create-destination.html#create-destination-redshift)。

1. 运行查询。有关更多信息，请参阅《Amazon Redshift 管理指南》**中的 [使用查询编辑器查询数据库](https://docs.aws.amazon.com/redshift/latest/mgmt/query-editor.html)。

## 示例查询
<a name="example-rs-query"></a>

在本示例查询中，我们假设满足以下条件：
+ 消息存储在默认 `public` schema 的 `notifications` 表中。
+ SNS 消息的 `Timestamp` 属性存储在表的 `timestamp` 列中，其列数据类型为 `timestamptz`。
**注意**  
要转换 Amazon Redshift 终端节点的 JSON 元数据，您可以使用 SQL `COPY` 命令。有关更多信息，请参阅 *Amazon Redshift 数据库开发人员指南*中的[从 JSON 中复制示例](https://docs.aws.amazon.com/redshift/latest/dg/r_COPY_command_examples.html#r_COPY_command_examples-copy-from-json)和[使用“auto ignorecase”选项从 JSON 数据中加载](https://docs.aws.amazon.com/redshift/latest/dg/r_COPY_command_examples.html#copy-from-json-examples-using-auto-ignorecase)。

以下查询返回在指定日期范围内收到的所有 SNS 消息：

```
SELECT *
FROM public.notifications
WHERE timestamp > '2020-12-01T09:00:00.000Z' AND timestamp < '2020-12-02T09:00:00.000Z';
```

# 配置到 HTTP 目标的 Amazon SNS 消息传输
<a name="firehose-http-destinations"></a>

本主题介绍传输流如何将数据发布到 HTTP 端点。

![\[Amazon SNS 主题的发布者，该主题随后会将这些消息分发到多个 Amazon SQS 队列。这些消息由 Lambda 函数处理，也通过 Data Firehose 传输流发送到 HTTP 端点。此设置展示了 AWS 服务 如何协同工作以促进消息处理以及与外部 HTTP 服务的集成。\]](http://docs.aws.amazon.com/zh_cn/sns/latest/dg/images/firehose-architecture-http.png)


**Topics**
+ [传送到 HTTP 目标的通知格式](firehose-delivered-message-format-http.md)

# 传送至 HTTP 目标的 Amazon SNS 通知格式
<a name="firehose-delivered-message-format-http"></a>

以下是通过传输流发送到 HTTP 端点的 Amazon SNS 的 HTTP POST 请求正文示例。Amazon SNS 通知被编码为 base64 格式的有效载荷，存放在 records 属性中。

**注意**  
在此示例中，已发布消息的原始消息传输被禁用。有关原始消息传输的更多信息，请参阅 [Amazon SNS 原始消息传输](sns-large-payload-raw-message-delivery.md)。

```
"body": {
    "requestId": "ebc9e8b2-fce3-4aef-a8f1-71698bf8175f",
    "timestamp": 1606255960435,
    "records": [
      {
        "data": "eyJUeXBlIjoiTm90aWZpY2F0aW9uIiwiTWVzc2FnZUlkIjoiMjFkMmUzOGQtMmNhYi01ZjYxLTliYTItYmJiYWFhYzg0MGY2IiwiVG9waWNBcm4iOiJhcm46YXdzOnNuczp1cy1lYXN0LTE6MTExMTExMTExMTExOm15LXRvcGljIiwiTWVzc2FnZSI6IlNhbXBsZSBtZXNzYWdlIGZvciBBbWF6b24gS2luZXNpcyBEYXRhIEZpcmVob3NlIGVuZHBvaW50cyIsIlRpbWVzdGFtcCI6IjIwMjAtMTEtMjRUMjI6MDc6MzEuNjY3WiIsIlVuc3Vic2NyaWJlVVJMIjoiaHR0cHM6Ly9zbnMudXMtZWFzdC0xLmFtYXpvbmF3cy5jb20vP0FjdGlvbj1VbnN1YnNjcmliZSZTdWJzY3JpcHRpb25Bcm49YXJuOmF3czpzbnM6MTExMTExMTExMTExOm15LXRvcGljOjAxYjY5MTJjLTAwNzAtNGQ4Yi04YjEzLTU1NWJmYjc2ZTdkNCJ9"
      }
    ]
  }
```

# Amazon SNS 消息归档和分析：航空票务平台示例应用场景
<a name="firehose-example-use-case"></a>

本主题提供用于归档和分析 Amazon SNS 消息的常见使用案例教程。

此使用案例的设置是一个在受监管环境中运行的航空公司票务平台。

1. 该平台受合规性框架的约束，要求公司将所有售票记录存档至少五年。

1. 为了实现数据留存方面的合规性目标，该公司将传输流订阅到现有的 SNS 主题。

1. 传输流的目标是 Amazon Simple Storage Service (Amazon S3) 存储桶。通过此配置，发布到 SNS 主题的所有事件都将存档到 Amazon S3 存储桶中。

下图显示了此配置的架构：

![\[航空公司票务平台的 AWS 架构，说明了机票销售数据的处理和存档方式。它显示了从 Lambda 函数流经 Amazon SNS 主题的数据流，然后该主题将消息分发到 Amazon SQS 队列进行付款处理和欺诈检测，由相应的 Lambda 函数处理。数据还通过 Data Firehose 流式传输到 Amazon S3 存储桶进行长期归档，从而支持遵守数据留存要求。此设置使平台能够使用诸如 Amazon Athena 之类的工具对门票销售数据进行详细分析。\]](http://docs.aws.amazon.com/zh_cn/sns/latest/dg/images/sns-archiving-use-case.png)


为了运行分析并了解门票销售的情况，该公司使用 Amazon Athena 运行 SQL 查询。例如，公司可以通过查询来了解最受欢迎的目的地和最频繁的旅客。

要为此用例创建 AWS 资源，您可以使用 AWS 管理控制台 或 CloudFormation 模板。

**Topics**
+ [设置用于邮件存档和分析的初始 AWS 资源](firehose-example-initial-resources.md)
+ [设置用于消息归档的 Firehose 传输流](firehose-example-create-delivery-stream.md)
+ [将传输流订阅到主题](firehose-example-subscribe-delivery-stream-to-topic.md)
+ [测试和查询配置以实现有效的数据管理](firehose-example-test-and-query.md)
+ [使用模板自动归档邮件 CloudFormation](firehose-example-cfn.md)

# 为 Amazon SNS 消息存档和分析设置初始 AWS 资源
<a name="firehose-example-initial-resources"></a>

本主题介绍如何为[消息归档和分析示例使用案例](firehose-example-use-case.md)创建所需资源：
+ 一个 Amazon Simple Storage Service (Amazon S3) 存储桶
+ 两个 Amazon Simple Queue Service (Amazon SQS) 队列
+ 一个 Amazon SNS 主题
+ 对 Amazon SNS 主题的两个 Amazon SQS 订阅

**要创建起始资源**

1. 创建 Amazon S3 存储桶：<a name="firehose-use-case-create-bucket"></a>

   1. 打开 [Amazon S3 控制台](https://console.aws.amazon.com/s3/home)。

   1. 选择**创建存储桶**。

   1. 对于 **Bucket name**（存储桶名称），请输入全局唯一名称。保留其他字段作为默认值。

   1. 选择 **创建存储桶 **。

   有关 Amazon S3 存储桶的更多信息，请参阅 *Amazon Simple Storage Service 用户指南*中的[创建存储桶](https://docs.aws.amazon.com/AmazonS3/latest/userguide/CreatingABucket.html)和 *Amazon Simple Storage Service 用户指南*中的[使用 Amazon S3 存储桶](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingBucket.html)。

1. 创建两个 Amazon SQS 队列：

   1. 打开 [Amazon SQS 控制台](https://console.aws.amazon.com/sqs/home)。

   1. 选择**创建队列**。

   1. 对于 **Type**（类型），选择 **Standard**（标准）。

   1. 对于**名称**，请输入 **ticketPaymentQueue**。

   1. 在 **Access policy**（访问策略）下，对于 **Choose method**（选择方法），选择 **Advanced**（高级）。

   1. 在 JSON 策略框中，粘贴以下策略：

------
#### [ JSON ]

****  

      ```
      {
        "Version":"2012-10-17",		 	 	 
        "Statement": [
          {
            "Effect": "Allow",
            "Principal": {
              "Service": "sns.amazonaws.com"
            },
            "Action": "sqs:SendMessage",
            "Resource": "*",
            "Condition": {
              "ArnEquals": {
                "aws:SourceArn": "arn:aws:sns:us-east-1:123456789012:ticketTopic"
              }
            }
          }
        ]
      }
      ```

------

      在此访问策略中，将 AWS 账户 数字 (*123456789012*) 替换为您自己的数字，然后相应地更改 AWS 区域 (*us-east-1*)。

   1. 选择**创建队列**。

   1. 重复这些步骤以创建第二个名为 **ticketFraudQueue** 的 SQS 队列。

   有关创建 SQS 队列的更多信息，请参阅 *Amazon Simple Queue Service 开发人员指南*中的[创建 Amazon SQS 队列（控制台）](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-configure-create-queue.html)。

1. 创建 SNS 主题：

   1. 打开 Amazon SNS 控制台中的[主题](https://console.aws.amazon.com/sns/home#/topics)页面。

   1. 选择**创建主题**。

   1. 在 **Details**（详细信息）下，对于 **Type**（类型），选择 **Standard**（标准）。

   1. 对于**名称**，请输入 **ticketTopic**。

   1. 选择**创建主题**。

   有关创建 SNS 主题的更多信息，请参阅 [创建 Amazon SNS 主题](sns-create-topic.md)。

1. 同时为两个 SQS 队列订阅 SNS 主题。

   1. 在 [Amazon SNS 控制台](https://console.aws.amazon.com/sns/home#/topics)上的在 **ticketTopic** 主题的详细信息页面，选择 **Create subscription**（创建订阅）。

   1. 在 **Details**（详细信息）下，对于 **Protocol**（方案），选择 **Amazon SQS**。

   1. 对于**终端节点**，选择队列的亚马逊资源名称 (ARN)。**ticketPaymentQueue**

   1. 选择**创建订阅**。

   1. 重复这些步骤，使用队列的 ARN 创建第二个订阅。**ticketFraudQueue**

      有关订阅 SNS 主题的更多信息，请参阅 [在 Amazon SNS 主题中创建订阅](sns-create-subscribe-endpoint-to-topic.md)。您还可以从 Amazon SQS 控制台为 SQS 队列订阅 SNS 主题。有关更多信息，请参阅 *Amazon Simple Queue Service 开发人员指南*中的[将 Amazon SQS 队列订阅到 Amazon SNS 主题（控制台）](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-configure-subscribe-queue-sns-topic.html)。

您已为此示例使用案例创建了初始资源。要继续，请参阅 [为 Amazon SNS 消息归档设置 Amazon Data Firehose 传输流](firehose-example-create-delivery-stream.md)。

# 为 Amazon SNS 消息归档设置 Amazon Data Firehose 传输流
<a name="firehose-example-create-delivery-stream"></a>

本主题介绍如何为[消息归档和分析示例使用案例](firehose-example-use-case.md)创建 Amazon Data Firehose 传输流。

**创建 Amazon Data Firehose 传输流**

1. 打开 [Amazon Data Firehose 服务控制台](https://console.aws.amazon.com/kinesis/home)。

1. 选择 **Firehose**，然后选择**创建传输流**。

1. 在 **New delivery stream**（新传输流）页面上，对于 **Delivery stream name**（传输流名称），输入 **ticketUploadStream**，然后选择 **Next**（下一步）。

1. 在 **Process records**（处理记录）页面上，选择 **Next**（下一步）。

1. 在 **Choose a destination**（选择目标）页面上，执行以下操作：

   1. 对于 **Destination**（目标），选择 **Amazon S3**。

   1. 在 **S3 destination**（S3 目标）下，对于 **S3 bucket**（S3 存储桶），选择您[最初创建的](firehose-example-initial-resources.md) S3 存储桶。

   1. 选择**下一步**。

1. 在 **Configure settings**（配置设置）页面上，对于 **S3 缓冲区条件**，执行以下操作：
   + 对于 **Buffer size**（缓冲区大小），输入 **1**。
   + 对于 **Buffer interval**（缓冲区时间间隔），输入 **60**。

   通过将这些值用于 Amazon S3 缓冲区，您可以快速测试配置。满足的第一个缓冲条件将触发至 S3 存储桶的数据传输。

1. 在**配置设置**页面上，对于**权限**，选择创建自动分配所需权限的 AWS Identity and Access Management (IAM) 角色。然后选择**下一步**。

1. 在 **Review**（审核）页面上，选择 **Create delivery stream**（创建传输流）。

1. 从 **Amazon Data Firehose 传输流页面中，**选择您刚刚创建的传输流（）**ticketUploadStream**。在 **Details**（详细信息）选项卡上，记下流的 Amazon Resource Name (ARN) 以供日后使用。

有关创建传输流的更多信息，请参阅《Amazon Data Firehose 开发人员指南》**中的[创建 Amazon Data Firehose 传输流](https://docs.aws.amazon.com/firehose/latest/dev/basic-create.html)。有关创建 IAM 角色的更多信息，请参阅 I [A *M 用户指南*中的创建角色以向 AWS 服务委派权限](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-service.html)。

您已创建具有所需权限的 Firehose 传输流。要继续，请参阅 [为 Firehose 传输流订阅 Amazon SNS 主题](firehose-example-subscribe-delivery-stream-to-topic.md)。

# 为 Firehose 传输流订阅 Amazon SNS 主题
<a name="firehose-example-subscribe-delivery-stream-to-topic"></a>

本主题介绍如何为[消息归档和分析示例使用案例](firehose-example-use-case.md)创建以下资源：
+  AWS Identity and Access Management (IAM) 角色，允许订阅 Amazon SNS 将记录放入传送流。
+ 到 Amazon SNS 主题的 Firehose 传输流订阅。

**要为 Amazon SNS 订阅创建 IAM 角色**

1. 打开 IAM 控制台的[角色页面](https://console.aws.amazon.com/iam/home?#/roles)。

1. 选择**创建角色**。

1. 对于**Select type of trusted entity（选择受信任实体的类型）**，选择 **AWS service（服务）**。

1. 对于 **Choose a use case**（选择使用案例），选择 **SNS**。然后选择**下一步：权限**。

1. 选择**下一步：标签**。

1. 选择**下一步：审核**。

1. 在**审核**页面上，对于**角色名称**，输入 **ticketUploadStreamSubscriptionRole**。然后选择**创建角色**。

1. 创建角色后，选择其名称 (**ticketUploadStreamSubscriptionRole**)。

1. 在角色的 **Summary**（摘要）页面上，选择 **Add inline policy**（添加内联策略）。

1. 在 **Create policy**（创建策略）页面上，选择 **JSON** 选项卡，然后将以下策略粘贴到文本框中：

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Action": [
                   "firehose:DescribeDeliveryStream",
                   "firehose:ListDeliveryStreams",
                   "firehose:ListTagsForDeliveryStream",
                   "firehose:PutRecord",
                   "firehose:PutRecordBatch"
               ],
               "Resource": [
                   "arn:aws:firehose:us-east-1:123456789012:deliverystream/ticketUploadStream"
               ],
               "Effect": "Allow"
           }
       ]
   }
   ```

------

   在本政策中，将 AWS 账户 数字 (*123456789012*) 替换为自己的数字，然后相应地更改 AWS 区域 (*us-east-1*)。

1. 选择**查看策略**。

1. 在 **Create policy**（创建策略）页面上，对于 **Name**（名称），输入 **FirehoseSnsPolicy**。然后选择**创建策略**。

1. 在角色的 **Summary**（摘要）页面上，记下**角色 ARN**供稍后使用。

有关创建 IAM 角色的更多信息，请参阅 I [A *M 用户指南*中的创建角色以向 AWS 服务委派权限](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-service.html)。

**为 Firehose 传输流订阅 SNS 主题**

1. 打开 Amazon SNS 控制台中的[主题](https://console.aws.amazon.com/sns/home#/topics)页面。

1. 在 **Subscriptions**（订阅）选项卡上，选择 **Create subscription**（创建订阅）。

1. 在**详细信息**下，对于**方案**，选择 ****。

1. 在 En **d** point 中，输入您之前创建的**ticketUploadStream**传输流的亚马逊资源名称 (ARN)。例如，输入 **arn:aws:firehose:us-east-1:123456789012:deliverystream/ticketUploadStream**。

1. 对于**订阅角色 ARN**，请输入您之前创建的 **ticketUploadStreamSubscriptionRole**IAM 角色的 ARN。例如，输入 **arn:aws:iam::123456789012:role/ticketUploadStreamSubscriptionRole**。

1. 选择 **Enable raw message delivery**（启用原始消息传输）复选框。

1. 选择**创建订阅**。

您已创建 IAM 角色和 SNS 主题订阅。要继续，请参阅 [测试和查询 Amazon SNS 配置以实现有效的数据管理](firehose-example-test-and-query.md)。

# 测试和查询 Amazon SNS 配置以实现有效的数据管理
<a name="firehose-example-test-and-query"></a>

本主题介绍如何通过将消息发布到 Amazon SNS 主题来测试[消息归档和分析示例使用案例](firehose-example-use-case.md)。这些说明包括一个示例查询，您可以运行并根据自己的需求对其进行调整。

**测试配置**

1. 打开 Amazon SNS 控制台中的[主题](https://console.aws.amazon.com/sns/home#/topics)页面。

1. 选择 **ticketTopic** 主题。

1. 选择**发布消息**。

1. 在 **Publish message to topic**（发布消息到主题）页面上，为消息正文输入以下内容。在消息结尾处添加换行符。

   ```
   {"BookingDate":"2020-12-15","BookingTime":"2020-12-15 04:15:05","Destination":"Miami","FlyingFrom":"Vancouver","TicketNumber":"abcd1234"}
   ```

   保留所有其他选项作为默认值。

1. 选择**发布消息**。

   有关发布消息的更多信息，请参阅 [发布 Amazon SNS 消息](sns-publishing.md)。

1. 在 60 秒的传输流间隔后，打开 [Amazon Simple Storage Service (Amazon S3) 控制台](https://console.aws.amazon.com/s3/home)并选择您[最初创建的](firehose-example-initial-resources.md) Amazon S3 存储桶。

   存储桶中会显示已发布的消息。

**要查询数据**

1. 打开 [Amazon Athena 控制台](https://console.aws.amazon.com/athena/home)。

1. 运行查询。

   例如，假设 `default` schema 中的 `notifications` 表包含下列数据：

   ```
   {"BookingDate":"2020-12-15","BookingTime":"2020-12-15 04:15:05","Destination":"Miami","FlyingFrom":"Vancouver","TicketNumber":"abcd1234"}
   {"BookingDate":"2020-12-15","BookingTime":"2020-12-15 11:30:15","Destination":"Miami","FlyingFrom":"Omaha","TicketNumber":"efgh5678"}
   {"BookingDate":"2020-12-15","BookingTime":"2020-12-15 3:30:10","Destination":"Miami","FlyingFrom":"NewYork","TicketNumber":"ijkl9012"}
   {"BookingDate":"2020-12-15","BookingTime":"2020-12-15 12:30:05","Destination":"Delhi","FlyingFrom":"Omaha","TicketNumber":"mnop3456"}
   ```

   要查找最佳目标，请运行以下查询：

   ```
   SELECT destination
   FROM default.notifications
   GROUP BY destination
   ORDER BY count(*) desc
   LIMIT 1;
   ```

   要查询在特定日期和时间范围内售出的票证，请运行如下所示的查询：

   ```
   SELECT * 
   FROM default.notifications 
   WHERE bookingtime 
     BETWEEN TIMESTAMP '2020-12-15 10:00:00' 
     AND TIMESTAMP '2020-12-15 12:00:00';
   ```

   您可以根据自己的需求调整两个示例查询。有关使用 Athena 运行查询的更多信息，请参阅 *Amazon Athena 用户指南*中的[入门](https://docs.aws.amazon.com/athena/latest/ug/getting-started.html)。

## 清理
<a name="firehose-example-cleanup"></a>

为避免在完成测试后产生使用费用，请删除您在本教程中创建的以下资源：
+ Amazon SNS 订阅
+ 亚马逊 SNS 主题
+ Amazon Simple Queue Service（Amazon SQS）队列
+ 亚马逊 S3 存储桶
+  传输流
+ AWS Identity and Access Management (IAM) 角色和策略

# 使用模板自动存档 Amazon SNS 消息 CloudFormation
<a name="firehose-example-cfn"></a>

要自动部署 Amazon SNS [消息存档和分析示例使用案例](firehose-example-use-case.md)，您可以使用以下 YAML 模板：

```
---
AWSTemplateFormatVersion: '2010-09-09'
Description: Template for creating an SNS archiving use case
Resources:
  ticketUploadStream:
    DependsOn:
    - ticketUploadStreamRolePolicy
    Type: AWS::KinesisFirehose::DeliveryStream
    Properties:
      S3DestinationConfiguration:
        BucketARN: !Sub 'arn:${AWS::Partition}:s3:::${ticketArchiveBucket}'
        BufferingHints:
          IntervalInSeconds: 60
          SizeInMBs: 1
        CompressionFormat: UNCOMPRESSED
        RoleARN: !GetAtt ticketUploadStreamRole.Arn
  ticketArchiveBucket:
    Type: AWS::S3::Bucket
  ticketTopic:
    Type: AWS::SNS::Topic
  ticketPaymentQueue:
    Type: AWS::SQS::Queue
  ticketFraudQueue:
    Type: AWS::SQS::Queue
  ticketQueuePolicy:
    Type: AWS::SQS::QueuePolicy
    Properties:
      PolicyDocument:
        Statement:
          Effect: Allow
          Principal:
            Service: sns.amazonaws.com
          Action:
            - sqs:SendMessage
          Resource: '*'
          Condition:
            ArnEquals:
              aws:SourceArn: !Ref ticketTopic
      Queues:
        - !Ref ticketPaymentQueue
        - !Ref ticketFraudQueue
  ticketUploadStreamSubscription:
    Type: AWS::SNS::Subscription
    Properties:
      TopicArn: !Ref ticketTopic
      Endpoint: !GetAtt ticketUploadStream.Arn
      Protocol: firehose
      SubscriptionRoleArn: !GetAtt ticketUploadStreamSubscriptionRole.Arn
  ticketPaymentQueueSubscription:
    Type: AWS::SNS::Subscription
    Properties:
      TopicArn: !Ref ticketTopic
      Endpoint: !GetAtt ticketPaymentQueue.Arn
      Protocol: sqs
  ticketFraudQueueSubscription:
    Type: AWS::SNS::Subscription
    Properties:
      TopicArn: !Ref ticketTopic
      Endpoint: !GetAtt ticketFraudQueue.Arn
      Protocol: sqs
  ticketUploadStreamRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17		 	 	 '
        Statement:
        - Sid: ''
          Effect: Allow
          Principal:
            Service: firehose.amazonaws.com
          Action: sts:AssumeRole
  ticketUploadStreamRolePolicy:
    Type: AWS::IAM::Policy
    Properties:
      PolicyName: FirehoseticketUploadStreamRolePolicy
      PolicyDocument:
        Version: '2012-10-17		 	 	 '
        Statement:
        - Effect: Allow
          Action:
          - s3:AbortMultipartUpload
          - s3:GetBucketLocation
          - s3:GetObject
          - s3:ListBucket
          - s3:ListBucketMultipartUploads
          - s3:PutObject
          Resource:
          - !Sub 'arn:aws:s3:::${ticketArchiveBucket}'
          - !Sub 'arn:aws:s3:::${ticketArchiveBucket}/*'
      Roles:
      - !Ref ticketUploadStreamRole
  ticketUploadStreamSubscriptionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17		 	 	 '
        Statement:
        - Effect: Allow
          Principal:
            Service:
            - sns.amazonaws.com
          Action:
          - sts:AssumeRole
      Policies:
      - PolicyName: SNSKinesisFirehoseAccessPolicy
        PolicyDocument:
          Version: '2012-10-17		 	 	 '
          Statement:
          - Action:
            - firehose:DescribeDeliveryStream
            - firehose:ListDeliveryStreams
            - firehose:ListTagsForDeliveryStream
            - firehose:PutRecord
            - firehose:PutRecordBatch
            Effect: Allow
            Resource:
            - !GetAtt ticketUploadStream.Arn
```

# 将 Amazon SNS 通知扇出到 Lambda 函数以进行自动处理
<a name="sns-lambda-as-subscriber"></a>

亚马逊 SNS 与集成 AWS Lambda，允许您触发 Lambda 函数以响应亚马逊 SNS 通知。将消息发布到 函数订阅的 SNS 主题时，将使用已发布消息的负载调用 Lambda 函数。Lambda 函数将消息负载作为输入参数接收，可以操作消息中的信息，将消息发布到其他 SNS 主题或将消息发送到其他服务。 AWS 

此外，Amazon SNS 还支持针对发送到 Lambda 终端节点的消息通知的消息传输状态属性。有关更多信息，请参阅 [Amazon SNS 消息传输状态](sns-topic-attributes.md)。

**Topics**
+ [先决条件](lambda-prereq.md)
+ [将函数订阅到主题](lambda-console.md)

# 跨区域将 Amazon SNS 与 Lambda 函数集成的先决条件
<a name="lambda-prereq"></a>

要使用 Amazon SNS 通知调用 Lambda 函数，您需要以下信息：
+ Lambda 函数
+ 一个 Amazon SNS 主题

有关创建 Lambda 函数以与 Amazon SNS 结合使用的信息，请参阅[将 Lambda 与 Amazon SNS 结合使用](https://docs.aws.amazon.com/lambda/latest/dg/with-sns-example.html)。有关创建 Amazon SNS 主题的信息，请参阅[创建主题](https://docs.aws.amazon.com/sns/latest/dg/CreateTopic.html)。

 当您使用 Amazon SNS 将消息从选择加入区域传送到默认启用的区域时，您必须通过将委托人 `sns.amazonaws.com` 替换为 `sns.<opt-in-region>.amazonaws.com` 来更改在 AWS Lambda 函数中创建的策略。

 例如，如果您希望为美国东部（弗吉尼亚北部）的 Lambda 函数订阅亚太地区（香港）的 SNS 主题，请将 AWS Lambda 函数策略中的委托人更改为 `sns.ap-east-1.amazonaws.com`。选择加入的区域包括 2019 年 3 月 20 日之后推出的任何区域，包括亚太地区（香港）、中东（巴林）、欧盟（米兰）和非洲（开普敦）。2019 年 3 月 20 日之前推出的区域默认情况下处于启用状态。

**注意**  
AWS 不支持从默认启用的区域向 Lambda 跨区域交付到可选区域。此外，也不支持将 SNS 消息从选择加入区域到其他选择加入区域的跨区域转发。

# 将 Lambda 函数订阅到 Amazon SNS 主题
<a name="lambda-console"></a>

本主题介绍如何将 Lambda 函数订阅到 Amazon SNS 主题，从而使该函数能够由已发布的消息触发。

1. 登录 [Amazon SNS 控制台](https://console.aws.amazon.com/sns/home)。

1. 在导航面板上，选择**主题**。

1. 在**主题** 页上，选择一个主题。

1. 在**订阅**部分中，选择**创建订阅**。

1. 在**创建订阅**页上的**详细信息**部分，执行以下操作：

   1. 验证所选**主题 ARN**。

   1. 对于**协议**，请选择 AWS Lambda。

   1. 对于**终端节点**，输入函数的 ARN。

   1. 选择**创建订阅**。

将消息发布到 函数订阅的 SNS 主题时，将使用已发布消息的负载调用 Lambda 函数。有关如何使用 AWS Lambda 亚马逊 SNS 的信息（包括教程），请参阅[使用 Amazon SN AWS Lambda S](https://docs.aws.amazon.com/lambda/latest/dg/with-sns.html)。

# 将 Amazon SNS 通知扇出到 Amazon SQS 队列进行异步处理
<a name="sns-sqs-as-subscriber"></a>

[Amazon SNS](https://aws.amazon.com/sns/) 与 Amazon Simple Queue Service (Amazon SQS) 密切配合。这些服务为开发人员提供了不同的益处。Amazon SNS 允许应用程序通过“推送”机制将时间要求严格的消息发送到多个订阅者，无需定期检查或“轮询”更新。Amazon SQS 是分布式应用程序通过轮询模型交换消息的消息队列服务，它可用于解耦发送和接收组件，而无需每个组件同时可用。通过将 Amazon SNS 和 Amazon SQS 配合使用，可以将消息发送到要求立即通知事件的应用程序，也可以在 Amazon SQS 队列中存留消息以供其他应用程序稍后进行处理。

为 Amazon SQS 队列订阅 Amazon SNS 主题时，您可以向该主题发布消息，Amazon SNS 会向已订阅队列发送 Amazon SQS 消息。Amazon SQS 消息包括已向主题发布的相关主题和消息，包括有关 JSON 文档中消息的元数据。Amazon SQS 消息与以下 JSON 文档相似。

```
{
   "Type" : "Notification",
   "MessageId" : "63a3f6b6-d533-4a47-aef9-fcf5cf758c76",
   "TopicArn" : "arn:aws:sns:us-west-2:123456789012:MyTopic",
   "Subject" : "Testing publish to subscribed queues",
   "Message" : "Hello world!",
   "Timestamp" : "2012-03-29T05:12:16.901Z",
   "SignatureVersion" : "1",
   "Signature" : "EXAMPLEnTrFPa3...",
   "SigningCertURL" : "https://sns.us-west-2.amazonaws.com/SimpleNotificationService-f3ecfb7224c7233fe7bb5f59f96de52f.pem",
   "UnsubscribeURL" : "https://sns.us-west-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-west-2:123456789012:MyTopic:c7fe3a54-ab0e-4ec2-88e0-db410a0f2bee"
}
```

# 为 Amazon SQS 队列订阅 Amazon SNS 主题
<a name="subscribe-sqs-queue-to-sns-topic"></a>

要启用 Amazon SNS 主题以将消息发送到 Amazon SQS 队列，请选择以下操作之一：
+ 使用 [Amazon SQS 控制台](https://console.aws.amazon.com/sqs/)，这简化了过程。有关更多信息，请参阅 *Amazon Simple Queue Service 开发人员指南*中的[将 Amazon SQS 队列订阅到 Amazon SNS 主题](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-configure-subscribe-queue-sns-topic.html)。
+ 使用以下步骤：

  1. [获取您要发送消息的目标队列的 Amazon 资源名称（ARN）以及要为队列订阅的主题。](#SendMessageToSQS.arn)

  1. [向 Amazon SNS 主题授予 `sqs:SendMessage` 权限，以便该主题向队列发送消息。](#SendMessageToSQS.sqs.permissions)

  1. [为队列订阅 Amazon SNS 主题。](#SendMessageToSQS.subscribe)

  1. [向 IAM 用户或 AWS 账户 授予适当权限，使之能够发布到 Amazon SNS 主题和阅读来自 Amazon SQS 队列的消息。](#SendMessageToSQS.iam.permissions)

  1. [通过向主题发布消息，并读取来自队列的消息，对其进行测试。](#SendMessageToSQS.test)

要了解如何设置主题以向位于不同的 AWS账户中的队列发送消息，请参阅[将 Amazon SNS 消息发送到不同账户中的 Amazon SQS 队列](sns-send-message-to-sqs-cross-account.md)。

要查看用于创建向两个队列发送消息的主题的 CloudFormation 模板，请参阅[通过以下方式自动发送亚马逊 SNS 到亚马逊 SQS 的消息 AWS CloudFormation](SendMessageToSQS.cloudformation.md)。

## 步骤 1：获取队列的 ARN 和主题
<a name="SendMessageToSQS.arn"></a>

为队列订阅主题时，需要队列 ARN 的副本。同样，为主题授予向队列发送消息的权限时，需要主题 ARN 的副本。

要获取队列 ARN，您可以使用亚马逊 SQS 控制台或 [GetQueueAttributes](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/Query_QueryGetQueueAttributes.html)API 操作。

**从 Amazon SQS 控制台获取队列 ARN**

1. 登录 AWS 管理控制台 并打开 Amazon SQS 控制台，网址为。[https://console.aws.amazon.com/sqs/](https://console.aws.amazon.com/sqs/)

1. 选定您要获取 ARN 的队列框。

1. 从**详细信息**部分中，复制 ARN 值，然后使用该值订阅 Amazon SNS 主题。

要获取主题 ARN，您可以使用 Amazon SNS 控制台、`[sns-get-topic-attributes](https://docs.aws.amazon.com/cli/latest/reference/sns/get-topic-attributes.html)` 命令或 `[GetQueueAttributes](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/Query_QueryGetQueueAttributes.html)` API 操作。

**从 Amazon SNS 控制台获取主题 ARN**

1. 登录 [Amazon SNS 控制台](https://console.aws.amazon.com/sns/home)。

1. 在导航面板上，选择要获取其 ARN 的主题。

1. 从**详细信息**部分中，复制 **ARN** 值，这样就可使用该值为 Amazon SNS 主题授予向队列发送消息的权限。

## 步骤 2. 为向 Amazon SQS 队列发送消息的 Amazon SNS 主题授予权限
<a name="SendMessageToSQS.sqs.permissions"></a>

针对能够向队列发送消息的 Amazon SNS 主题，您必须对队列设置策略，以允许 Amazon SNS 主题执行 `sqs:SendMessage` 操作。

获取主题和队列之后，方可为队列订阅主题。如果您尚未创建主题或队列，请您立刻创建。有关更多信息，请参阅[创建主题](sns-create-topic.md)，并参阅《Amazon Simple Queue Service 开发人员指南》**中的[创建队列](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/step-create-queue.html)。

要对队列设置策略，您可以使用 Amazon SQS 控制台或 [SetQueueAttributes](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/Query_QuerySetQueueAttributes.html)API 操作。开始前，请确保针对您想要允许向队列发送消息的主题，您已拥有其 ARN。如果要为队列订阅多个主题，策略必须对于每个主题包含一个 `Statement` 元素。

**使用 Amazon SQS 控制台对队列设置 SendMessage 策略**

1. 登录 AWS 管理控制台 并打开 Amazon SQS 控制台，网址为。[https://console.aws.amazon.com/sqs/](https://console.aws.amazon.com/sqs/)

1. 选择要设置其策略的队列的框，然后依次选择 **Access policy**（访问策略）选项卡、**编辑**。

1. 在 **Access policy**（访问策略）部分中，定义谁可以访问您的队列。
   + 添加允许主题操作的一项条件。
   + 将 `Principal` 设置为 Amazon SNS 服务，如下例所示。
   + 使用 [https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourcearn](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourcearn) 或 [https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourceaccount](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourceaccount) 全局条件键来防止[混淆代理](https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html)场景。要使用这些条件键，请将值设置为主题的 ARN。如果您的队列订阅了多个主题，则可以改用 `aws:SourceAccount`。

   例如，以下策略允许 MyTopic 向发送消息 MyQueue。

   ```
   {
     "Statement": [
       {
         "Effect": "Allow",
         "Principal": {
           "Service": "sns.amazonaws.com"
         },
         "Action": "sqs:SendMessage",
         "Resource": "arn:aws:sqs:us-east-2:123456789012:MyQueue",
         "Condition": {
           "ArnEquals": {
             "aws:SourceArn": "arn:aws:sns:us-east-2:123456789012:MyTopic"
           }
         }
       }
     ]
   }
   ```

## 步骤 3. 为队列订阅 Amazon SNS 主题
<a name="SendMessageToSQS.subscribe"></a>

必须为队列订阅 Amazon SNS 主题后，方可通过主题向队列发送消息。您可以按队列 ARN 指定队列。要订阅主题，您可以使用 Amazon SNS 控制台、`[sns-subscribe](https://docs.aws.amazon.com/cli/latest/reference/sns/subscribe.html)` CLI 命令或 `[Subscribe](https://docs.aws.amazon.com/sns/latest/api/API_Subscribe.html)` API 操作。开始前，必须确保您拥有要订阅队列的 ARN。

1. 登录 [Amazon SNS 控制台](https://console.aws.amazon.com/sns/home)。

1. 在导航面板上，选择**主题**。

1. 在**主题** 页上，选择一个主题。

1. 在该***MyTopic***页面的**订阅**页面中，选择**创建订阅**。

1. 在**创建订阅**页上的**详细信息**部分，执行以下操作：

   1. 验证**主题 ARN**。

   1. 对于 **Protocol**（协议），选择 **Amazon SQS**。

   1. 对于 **Endpoint**（终端节点），输入 Amazon SQS 队列的 ARN。

   1. 选择**创建订阅**。

   确认订阅后，您新建订阅的“**Subscription ID**”将显示其订阅 ID。如果订阅由队列所有者创建，则订阅将自动确认，且订阅立刻可用。

   一般情况下，您可以在您自己的账户中为您的队列订阅您自己的主题。但是，您还可以通过另一账户为队列订阅主题。如果创建订阅的用户并非队列所有者（例如，如果账户 A 的用户为账户 B 中的队列订阅账户 A 中的主题），则必须对订阅进行确认。有关通过不同账户订阅队列和确认订阅的更多信息，请参阅 [将 Amazon SNS 消息发送到不同账户中的 Amazon SQS 队列](sns-send-message-to-sqs-cross-account.md)。

## 步骤 4：向用户授予对适当主题和队列操作的权限
<a name="SendMessageToSQS.iam.permissions"></a>

您应使用 AWS Identity and Access Management (IAM) 仅允许相应的用户向亚马逊 SNS 主题和来自亚马逊 SQS 队列的 read/delete 消息发布消息。有关针对 IAM 用户控制主题和队列操作的更多信息，请参阅 Amazon Simple Queue Service 开发人员指南中的 [将基于身份的策略用于 Amazon SNS](sns-using-identity-based-policies.md) 和 [Amazon SQS 中的 Identity and Access Management](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/UsingIAM.html)。

可以采取两种方式控制对主题或队列的访问：
+ [添加策略至 IAM 用户或群组](#SendMessageToSQS.iam.permissions.user)。为用户授予主题或队列权限的最简单方式就是创建群组，并为该群组添加适当策略，然后向此群组添加用户。相比较而言，向群组添加或删除用户，比追踪您为单独用户而设定的各项策略要简单得多。
+ [添加策略至主题或队列](#SendMessageToSQS.iam.permissions.resource)。如果您想将某个主题或队列的权限授予其他 AWS 账户，那么唯一的方法就是添加一个以 AWS 账户 您想要授予权限的委托人为其委托人的策略。

绝大多数情况下，您应使用第一种方法（通过向群组添加或删除适当用户的方式，向群组添加策略，管理用户权限）。如果您需要向另一账户的用户授予权限，那么应使用第二种方法。

### 添加策略至 IAM 用户或群组
<a name="SendMessageToSQS.iam.permissions.user"></a>

如果您向 IAM 用户或群组添加了以下策略，则需要向该用户或群组中的成员授予对该主题执行`sns:Publish`操作的权限 MyTopic。

```
{
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "sns:Publish",
      "Resource": "arn:aws:sns:us-east-2:123456789012:MyTopic"
    }
  ]
}
```

如果您向 IAM 用户或群组添加了以下策略，则需要向该用户或群组中的成员授予对队列 MyQueue 1 `sqs:ReceiveMessage` 和 MyQueue 2 执行和`sqs:DeleteMessage`操作的权限。

```
{
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "sqs:ReceiveMessage",
        "sqs:DeleteMessage"
      ],
      "Resource": [
        "arn:aws:sqs:us-east-2:123456789012:MyQueue1",
        "arn:aws:sqs:us-east-2:123456789012:MyQueue2"
      ]
    }
  ]
}
```

### 添加策略至主题或队列
<a name="SendMessageToSQS.iam.permissions.resource"></a>

以下策略示例显示如何为主题和队列授予另一账户授权。

**注意**  
当您授予其他人 AWS 账户 访问您账户中某项资源的权限时，也就是向对该资源拥有管理员级访问权限（通配符访问权限）的 IAM 用户授予权限。此操作将自动拒绝其他账户中的所有其他 IAM 用户访问您的资源。如果您要向该 AWS 账户 中的特定 IAM 用户授予访问您的资源的权限，那么拥有管理员级访问权限的账户或 IAM 用户必须将此项资源的访问权限委派给这些 IAM 用户。有关跨账户委派的更多信息，请参阅*使用 IAM 指南*中的[启用跨账户访问](https://docs.aws.amazon.com/IAM/latest/UserGuide/Delegation.html)。

如果您向账户 123456789012 MyTopic 中的主题添加了以下策略，则需要向账户 111122223333 授予对该主题执行操作的权限。`sns:Publish`

```
{
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "111122223333"
      },
      "Action": "sns:Publish",
      "Resource": "arn:aws:sns:us-east-2:123456789012:MyTopic"
    }
  ]
}
```

如果您向账户 123456789012 MyQueue 中的队列添加了以下策略，则需要授予账户 111122223333 对该队列执行和操作的权限。`sqs:ReceiveMessage` `sqs:DeleteMessage`

```
{
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "111122223333"
      },
      "Action": [
        "sqs:DeleteMessage",
        "sqs:ReceiveMessage"
      ],
      "Resource": [
        "arn:aws:sqs:us-east-2:123456789012:MyQueue"
      ]
    }
  ]
}
```

## 步骤 5：测试主题的队列订阅
<a name="SendMessageToSQS.test"></a>

通过发布主题，查看主题向队列发送的消息，可以测试主题的队列订阅情况。

**利用 Amazon SNS 控制台发布主题**

1. 使用有权发布主题的 AWS 账户 或 IAM 用户的证书，登录 AWS 管理控制台 并打开 Amazon SNS 控制台，网址为。[https://console.aws.amazon.com/sns/](https://console.aws.amazon.com/sns/home)

1. 在导航面板上，选择主题，然后选择**发布到主题**。

1. 在**主题**框中，输入主题（例如 **Testing publish to queue**），在**消息**框中，输入一些文字（例如 **Hello world\$1**），然后选择**发布消息**。界面将显示如下消息：Your message has been successfully published。

**利用 Amazon SQS 控制台查看来自主题的消息**

1. 使用有权查看队列中消息的 AWS 账户 或 IAM 用户的证书，登录 AWS 管理控制台 并打开 Amazon SQS 控制台，网址为。[https://console.aws.amazon.com/sqs/](https://console.aws.amazon.com/sqs/)

1. 选择已订阅该主题的 **queue**（队列）。

1. 选择 **Send and receive messages**（发送和接收消息），然后选择 **Poll for messages**（轮询消息）。界面将显示“**Notification**”类型消息。

1. 在**正文**列中，选择**更多详细信息**。“**Message Details**”框包括 JSON 文档，此文档包含您发布主题的主题和消息。消息与以下 JSON 文档相似。

   ```
   {
     "Type" : "Notification",
     "MessageId" : "63a3f6b6-d533-4a47-aef9-fcf5cf758c76",
     "TopicArn" : "arn:aws:sns:us-west-2:123456789012:MyTopic",
     "Subject" : "Testing publish to subscribed queues",
     "Message" : "Hello world!",
     "Timestamp" : "2012-03-29T05:12:16.901Z",
     "SignatureVersion" : "1",
     "Signature" : "EXAMPLEnTrFPa3...",
     "SigningCertURL" : "https://sns.us-west-2.amazonaws.com/SimpleNotificationService-f3ecfb7224c7233fe7bb5f59f96de52f.pem",
     "UnsubscribeURL" : "https://sns.us-west-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-west-2:123456789012:MyTopic:c7fe3a54-ab0e-4ec2-88e0-db410a0f2bee"
   }
   ```

1. 选择**关闭**。您已经成功发布到一个主题，该主题向队列发送通知消息。

# 通过以下方式自动发送亚马逊 SNS 到亚马逊 SQS 的消息 AWS CloudFormation
<a name="SendMessageToSQS.cloudformation"></a>

CloudFormation 允许您使用模板文件将 AWS 资源集合作为一个单元一起创建和配置。通过本部分提供的模板示例，您可以轻松部署向队列发布的主题。模板通过以下操作协助您处理设置步骤，即创建两个队列、创建订阅队列的主题、添加策略至队列，以便主题能够向队列发送消息，以及创建 IAM 用户和群组，控制对这些资源的访问。

有关使用 CloudFormation 模板部署 AWS 资源的更多信息，请参阅《*CloudFormation 用户指南》*中的 “[入门](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/GettingStarted.Walkthrough.html)”。

## 使用 CloudFormation 模板在中设置主题和队列 AWS 账户
<a name="SendMessageToSQS.cloudformation.iam"></a>

该模板示例创建一个 Amazon SNS 主题，该主题能够向具备相应权限的两个 Amazon SQS 队列发送信息，以便一个 IAM 组的成员能够向该主题发布消息，而另一个组则从该队列读取消息。模板还用于创建可添加至各个群组的 IAM 用户。

您可以将模板内容复制到文件中，您也可以从 “模板[” 页面下载AWS CloudFormation 模板](https://aws.amazon.com/cloudformation/aws-cloudformation-templates/)。在模板页面上，选择**按 AWS 服务浏览示例模板**，然后选择**亚马逊简单队列服务**。

我的设置SNSTopic 为发布到两个已订阅的终端节点，即两个 Amazon SQS 队列MyQueue（1 MyQueue 和 2）。 MyPublishTopicGroup 是一个 IAM 群组，其成员有权SNSTopic 使用 “发布 API” 操作或 [sns-p [ub](https://docs.aws.amazon.com/sns/latest/api/API_Publish.html) lish 命令向 “我的” 发布内容](https://docs.aws.amazon.com/cli/latest/reference/sns/publish.html)。该模板创建 IAM 用户 MyPublishUser ， MyQueueUser 并为他们提供登录配置文件和访问密钥。通过该模板创建堆栈的用户将指定登录界面密码作为输入参数。该模板使用 MyPublishUserKey 和为两个 IAM 用户创建访问密钥 MyQueueUserKey。 AddUserToMyPublishTopicGroup 添加 MyPublishUser 到， MyPublishTopicGroup 这样用户就可以拥有分配给该组的权限。

我RDMessageQueueGroup 是一个 IAM 群组，其成员有权使用和 [DeleteMessage](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/Query_QueryDeleteMessage.html)API 操作从两个 Amazon SQS 队列中读取[ReceiveMessage](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/Query_QueryReceiveMessage.html)和删除消息。 AddUserToMyQueueGroup 添加 MyQueueUser 到 “我的”，RDMessageQueueGroup 这样用户就可以拥有分配给该组的权限。 MyQueuePolicy 为 My 分配SNSTopic 向这两个队列发布通知的权限。

以下清单显示了 CloudFormation 模板的内容。

```
{
  "AWSTemplateFormatVersion" : "2010-09-09",
  
  "Description" : "AWS CloudFormation Sample Template SNSToSQS: This Template creates an SNS topic that can send messages to 
  two SQS queues with appropriate permissions for one IAM user to publish to the topic and another to read messages from the queues. 
  MySNSTopic is set up to publish to two subscribed endpoints, which are two SQS queues (MyQueue1 and MyQueue2). MyPublishUser is an IAM user 
  that can publish to MySNSTopic using the Publish API. MyTopicPolicy assigns that permission to MyPublishUser. MyQueueUser is an IAM user 
  that can read messages from the two SQS queues. MyQueuePolicy assigns those permissions to MyQueueUser. It also assigns permission for 
  MySNSTopic to publish its notifications to the two queues. The template creates access keys for the two IAM users with MyPublishUserKey 
  and MyQueueUserKey. ***Warning*** you will be billed for the AWS resources used if you create a stack from this template.",

  "Parameters": {
    "MyPublishUserPassword": {
      "NoEcho": "true",
      "Type": "String",
      "Description": "Password for the IAM user MyPublishUser",
      "MinLength": "1",
      "MaxLength": "41",
      "AllowedPattern": "[a-zA-Z0-9]*",
      "ConstraintDescription": "must contain only alphanumeric characters."
    },
    "MyQueueUserPassword": {
      "NoEcho": "true",
      "Type": "String",
      "Description": "Password for the IAM user MyQueueUser",
      "MinLength": "1",
      "MaxLength": "41",
      "AllowedPattern": "[a-zA-Z0-9]*",
      "ConstraintDescription": "must contain only alphanumeric characters."
    }
  },


  "Resources": {
    "MySNSTopic": {
      "Type": "AWS::SNS::Topic",
      "Properties": {
        "Subscription": [{
            "Endpoint": {
              "Fn::GetAtt": ["MyQueue1", "Arn"]
            },
            "Protocol": "sqs"
          },
          {
            "Endpoint": {
              "Fn::GetAtt": ["MyQueue2", "Arn"]
            },
            "Protocol": "sqs"
          }
        ]
      }
    },
    "MyQueue1": {
      "Type": "AWS::SQS::Queue"
    },
    "MyQueue2": {
      "Type": "AWS::SQS::Queue"
    },
    "MyPublishUser": {
      "Type": "AWS::IAM::User",
      "Properties": {
        "LoginProfile": {
          "Password": {
            "Ref": "MyPublishUserPassword"
          }
        }
      }
    },
    "MyPublishUserKey": {
      "Type": "AWS::IAM::AccessKey",
      "Properties": {
        "UserName": {
          "Ref": "MyPublishUser"
        }
      }
    },
    "MyPublishTopicGroup": {
      "Type": "AWS::IAM::Group",
      "Properties": {
        "Policies": [{
          "PolicyName": "MyTopicGroupPolicy",
          "PolicyDocument": {
            "Statement": [{
              "Effect": "Allow",
              "Action": [
                "sns:Publish"
              ],
              "Resource": {
                "Ref": "MySNSTopic"
              }
            }]
          }
        }]
      }
    },
    "AddUserToMyPublishTopicGroup": {
      "Type": "AWS::IAM::UserToGroupAddition",
      "Properties": {
        "GroupName": {
          "Ref": "MyPublishTopicGroup"
        },
        "Users": [{
          "Ref": "MyPublishUser"
        }]
      }
    },
    "MyQueueUser": {
      "Type": "AWS::IAM::User",
      "Properties": {
        "LoginProfile": {
          "Password": {
            "Ref": "MyQueueUserPassword"
          }
        }
      }
    },
    "MyQueueUserKey": {
      "Type": "AWS::IAM::AccessKey",
      "Properties": {
        "UserName": {
          "Ref": "MyQueueUser"
        }
      }
    },
    "MyRDMessageQueueGroup": {
      "Type": "AWS::IAM::Group",
      "Properties": {
        "Policies": [{
          "PolicyName": "MyQueueGroupPolicy",
          "PolicyDocument": {
            "Statement": [{
              "Effect": "Allow",
              "Action": [
                "sqs:DeleteMessage",
                "sqs:ReceiveMessage"
              ],
              "Resource": [{
                  "Fn::GetAtt": ["MyQueue1", "Arn"]
                },
                {
                  "Fn::GetAtt": ["MyQueue2", "Arn"]
                }
              ]
            }]
          }
        }]
      }
    },
    "AddUserToMyQueueGroup": {
      "Type": "AWS::IAM::UserToGroupAddition",
      "Properties": {
        "GroupName": {
          "Ref": "MyRDMessageQueueGroup"
        },
        "Users": [{
          "Ref": "MyQueueUser"
        }]
      }
    },
    "MyQueuePolicy": {
      "Type": "AWS::SQS::QueuePolicy",
      "Properties": {
        "PolicyDocument": {
          "Statement": [{
            "Effect": "Allow",
            "Principal": {
              "Service": "sns.amazonaws.com"
            },
            "Action": ["sqs:SendMessage"],
            "Resource": "*",
            "Condition": {
              "ArnEquals": {
                "aws:SourceArn": {
                  "Ref": "MySNSTopic"
                }
              }
            }
          }]
        },
        "Queues": [{
          "Ref": "MyQueue1"
        }, {
          "Ref": "MyQueue2"
        }]
      }
    }
  },
  "Outputs": {
    "MySNSTopicTopicARN": {
      "Value": {
        "Ref": "MySNSTopic"
      }
    },
    "MyQueue1Info": {
      "Value": {
        "Fn::Join": [
          " ",
          [
            "ARN:",
            {
              "Fn::GetAtt": ["MyQueue1", "Arn"]
            },
            "URL:",
            {
              "Ref": "MyQueue1"
            }
          ]
        ]
      }
    },
    "MyQueue2Info": {
      "Value": {
        "Fn::Join": [
          " ",
          [
            "ARN:",
            {
              "Fn::GetAtt": ["MyQueue2", "Arn"]
            },
            "URL:",
            {
              "Ref": "MyQueue2"
            }
          ]
        ]
      }
    },
    "MyPublishUserInfo": {
      "Value": {
        "Fn::Join": [
          " ",
          [
            "ARN:",
            {
              "Fn::GetAtt": ["MyPublishUser", "Arn"]
            },
            "Access Key:",
            {
              "Ref": "MyPublishUserKey"
            },
            "Secret Key:",
            {
              "Fn::GetAtt": ["MyPublishUserKey", "SecretAccessKey"]
            }
          ]
        ]
      }
    },
    "MyQueueUserInfo": {
      "Value": {
        "Fn::Join": [
          " ",
          [
            "ARN:",
            {
              "Fn::GetAtt": ["MyQueueUser", "Arn"]
            },
            "Access Key:",
            {
              "Ref": "MyQueueUserKey"
            },
            "Secret Key:",
            {
              "Fn::GetAtt": ["MyQueueUserKey", "SecretAccessKey"]
            }
          ]
        ]
      }
    }
  }
}
```

# 将 Amazon SNS 通知扇出到 HTTPS 端点
<a name="sns-http-https-endpoint-as-subscriber"></a>

您可以使用 Amazon SNS 向一个或多个 HTTP 或 HTTPS 端点发送通知消息。为终端节点订阅主题时，您可以向主题发布通知，Amazon SNS 将发送 HTTP POST 请求，向已订阅终端节点传递通知内容。订阅终端节点时，您可以选择 Amazon SNS 是否使用 HTTP 或 HTTPS 向终端节点发送 POST 请求。如果您使用 HTTPS，则可以利用 Amazon SNS 对以下功能的支持：
+ **服务器名称指示 (SNI)** - 这使 Amazon SNS 可以支持需要 SNI 的 HTTPS 终端节点，如需要多个证书来承载多个域的服务器。有关 SNI 的更多信息，请参阅[服务器名称指示](http://en.wikipedia.org/wiki/Server_Name_Indication)。
+ **基本和摘要式访问身份验证** - 这使您可以在 HTTPS URL 中为 HTTP POST 请求指定用户名和密码，如 `https://user:password@domain.com` 或 `https://user@domain.com`。在使用 HTTPS 建立的 SSL 连接上，会对该用户名和密码进行加密。只有域名以明文形式发送。有关基本和摘要式访问身份验证的更多信息，请参阅 [RFC-2617](http://www.rfc-editor.org/info/rfc2617)。
**重要**  
Amazon SNS 目前不支持私有 HTTP(S) 端点。  
对于您 URLs 已授予 API 访问权限的委托人，只能从 Amazon `GetSubscriptionAttributes` SNS API 操作中检索 HTTPS。
**注意**  
 客户端服务必须能够支持 `HTTP/1.1 401 Unauthorized` 标头响应

此项请求包含已向主题发布的相关主题和消息，包括 JSON 文档中通知的元数据。此项请求与以下 HTTP POST 请求相似。有关 HTTP 标头和请求正文 JSON 格式的详细信息，请参阅 [HTTP/HTTPS 标题](http-header.md) 和 [HTTP/HTTPS 通知 JSON 格式](http-notification-json.md)。

**注意**  
Amazon SNS 将所有 5XX 错误和 429（发送的请求过多）错误视为可重试错误。这些错误会按照传输策略进行重试。其他所有错误都被视为永久失败，不会进行重试。

```
POST / HTTP/1.1
    x-amz-sns-message-type: Notification
    x-amz-sns-message-id: da41e39f-ea4d-435a-b922-c6aae3915ebe
    x-amz-sns-topic-arn: arn:aws:sns:us-west-2:123456789012:MyTopic
    x-amz-sns-subscription-arn: arn:aws:sns:us-west-2:123456789012:MyTopic:2bcfbf39-05c3-41de-beaa-fcfcc21c8f55
    Content-Length: 761
    Content-Type: text/plain; charset=UTF-8
    Host: ec2-50-17-44-49.compute-1.amazonaws.com
    Connection: Keep-Alive
    User-Agent: Amazon Simple Notification Service Agent
    
{
  "Type" : "Notification",
  "MessageId" : "da41e39f-ea4d-435a-b922-c6aae3915ebe",
  "TopicArn" : "arn:aws:sns:us-west-2:123456789012:MyTopic",
  "Subject" : "test",
  "Message" : "test message",
  "Timestamp" : "2012-04-25T21:49:25.719Z",
  "SignatureVersion" : "1",
  "Signature" : "EXAMPLElDMXvB8r9R83tGoNn0ecwd5UjllzsvSvbItzfaMpN2nk5HVSw7XnOn/49IkxDKz8YrlH2qJXj2iZB0Zo2O71c4qQk1fMUDi3LGpij7RCW7AW9vYYsSqIKRnFS94ilu7NFhUzLiieYr4BKHpdTmdD6c0esKEYBpabxDSc=",
  "SigningCertURL" : "https://sns.us-west-2.amazonaws.com/SimpleNotificationService-f3ecfb7224c7233fe7bb5f59f96de52f.pem",
   "UnsubscribeURL" : "https://sns.us-west-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-west-2:123456789012:MyTopic:2bcfbf39-05c3-41de-beaa-fcfcc21c8f55"
}
```

# 为 HTTPS 端点订阅 Amazon SNS 主题
<a name="sns-subscribe-https-s-endpoints-to-topic"></a>

本主题介绍如何为 HTTP/S 终端节点订阅 Amazon SNS 主题。

**Topics**
+ [步骤 1：确保您的终端节点已准备好处理 Amazon SNS 消息](SendMessageToHttp.prepare.md)
+ [步骤 2：为 HTTP/HTTPS 终端节点订阅 Amazon SNS 主题](SendMessageToHttp.subscribe.md)
+ [第 3 步：确认您的 Amazon SNS 订阅](SendMessageToHttp.confirm.md)
+ [步骤 4：可选 - 设置 Amazon SNS 订阅的传送策略](SendMessageToHttp.retry.md)
+ [步骤 5：可选 - 授予用户发布 Amazon SNS 主题的权限](SendMessageToHttp.iam.permissions.md)
+ [步骤 6：向终端节点发送 Amazon SNS 消息 HTTP/HTTPS](SendMessageToHttp.publish.md)

# 步骤 1：确保您的终端节点已准备好处理 Amazon SNS 消息
<a name="SendMessageToHttp.prepare"></a>

确保供 Amazon SNS 使用发送订阅确认和通知消息的 HTTP 或 HTTPS 终端节点能够处理 HTTP POST 请求之后，方可订阅相关主题的 HTTP 或 HTTPS 终端节点。一般情况下，这要求创建和部署 Web 应用程序（例如，若您的终端主机正在通过 Apache 和 Tomcat 运行 Linux，则为 Java servlet），用于处理来自 Amazon SNS 的 HTTP 请求。当您订阅 HTTP 终端节点时，Amazon SNS 会向其发送一条订阅确认请求。当您创建订阅时，终端节点必须已经准备好接收和处理此请求，因为 Amazon SNS 会同时发送此请求。在您确认订阅前，Amazon SNS 不会向终端节点发送消息。订阅确认后，在已订阅主题上执行发布操作时，Amazon SNS 会向终端节点发送通知。

**设置您的终端节点，处理订阅确认和通知消息**

1. 您的代码将读取 Amazon SNS 向您的终端节点发送的 HTTP POST 请求的 HTTP 标头。您的代码将查找标头字段 `x-amz-sns-message-type`，此标头字段将显示 Amazon SNS 向您发送的消息类型。查看标头后，您可以确定消息类型，而无需分析 HTTP 请求正文。您需要处理如下两种类型消息：`SubscriptionConfirmation` 和 `Notification`。仅当从主题中删除订阅时，方使用 `UnsubscribeConfirmation` 消息。

   有关 HTTP 标头的详细信息，请参阅 [HTTP/HTTPS 标题](http-header.md)。以下 HTTP POST 请求为订阅确认消息的一个示例。

   ```
   POST / HTTP/1.1
       x-amz-sns-message-type: SubscriptionConfirmation
       x-amz-sns-message-id: 165545c9-2a5c-472c-8df2-7ff2be2b3b1b
       x-amz-sns-topic-arn: arn:aws:sns:us-west-2:123456789012:MyTopic
       Content-Length: 1336
       Content-Type: text/plain; charset=UTF-8
       Host: example.com
       Connection: Keep-Alive
       User-Agent: Amazon Simple Notification Service Agent
       
   {
     "Type" : "SubscriptionConfirmation",
     "MessageId" : "165545c9-2a5c-472c-8df2-7ff2be2b3b1b",
     "Token" : "2336412f37f...",
     "TopicArn" : "arn:aws:sns:us-west-2:123456789012:MyTopic",
     "Message" : "You have chosen to subscribe to the topic arn:aws:sns:us-west-2:123456789012:MyTopic.\nTo confirm the subscription, visit the SubscribeURL included in this message.",
     "SubscribeURL" : "https://sns.us-west-2.amazonaws.com/?Action=ConfirmSubscription&TopicArn=arn:aws:sns:us-west-2:123456789012:MyTopic&Token=2336412f37...",
     "Timestamp" : "2012-04-26T20:45:04.751Z",
     "SignatureVersion" : "1",
     "Signature" : "EXAMPLEpH+...",
     "SigningCertURL" : "https://sns.us-west-2.amazonaws.com/SimpleNotificationService-f3ecfb7224c7233fe7bb5f59f96de52f.pem"
   }
   ```

1. 您的代码应解析 HTTP POST 请求正文中的 JSON 文档和内容类型， text/plain 以读取构成 Amazon SNS 消息的名称/值对。使用 JSON 分析器将控制字符的转义字符转换回 ASCII 字符值（例如，将 \$1n 转换成换行符）。您可以使用现有 JSON 分析器（例如 [Jackson JSON 处理器](https://github.com/FasterXML/jackson)）或者由您自己写入。要将主题和消息字段中的文本作为有效 JSON 发送，Amazon SNS 必须将部分控制字符转换成可包含在 JSON 文档中的转义字符。向您的终端节点发送的 POST 请求正文中包括 JSON 文档，当您接收到该文档时，若您想要获取发布到主题上的原始主题和消息的精确字符，则必须将转义字符转换回其原始字符值。由于签名采用了原始形式的消息和主题作为待签字符串的一部分，因此如果您想要验证通知签名，则上述操作非常重要。

1. 您的代码应对 Amazon SNS 发送的通知、订阅确认或取消订阅确认消息进行验证。使用 Amazon SNS 消息所含信息，终端节点可以重新创建签名，以便您可以通过将自己的签名与 Amazon SNS 随消息发送的签名进行匹配，来验证消息的内容。有关验证消息签名的更多信息，请参阅 [验证 Amazon SNS 消息签名](sns-verify-signature-of-message.md)。

1. 根据标头字段 `x-amz-sns-message-type` 指定的类型，您的代码将读取 HTTP 请求正文所含的 JSON 文档，并处理该消息。这里是处理两大主要消息类型的指导原则：  
**SubscriptionConfirmation**  
读取 `SubscribeURL` 值，访问此 URL。要确认订阅并通过此终端节点接收通知，必须访问 `SubscribeURL` URL（例如，向此 URL 发送 HTTP GET 请求）。参阅上一步中 HTTP 请求示例，查看 `SubscribeURL` 相关情况。有关 `SubscriptionConfirmation` 消息格式的更多信息，请参阅 [HTTP/HTTPS 订阅确认 JSON 格式](http-subscription-confirmation-json.md)。访问 URL 时，您将获取与以下 XML 文档相似的响应。文档会在 `ConfirmSubscriptionResult` 元素内返回终端节点的订阅 ARN。  

   ```
   <ConfirmSubscriptionResponse xmlns="http://sns.amazonaws.com/doc/2010-03-31/">
      <ConfirmSubscriptionResult>
         <SubscriptionArn>arn:aws:sns:us-west-2:123456789012:MyTopic:2bcfbf39-05c3-41de-beaa-fcfcc21c8f55</SubscriptionArn>
      </ConfirmSubscriptionResult>
      <ResponseMetadata>
         <RequestId>075ecce8-8dac-11e1-bf80-f781d96e9307</RequestId>
      </ResponseMetadata>
   </ConfirmSubscriptionResponse>
   ```
除了访问之外`SubscribeURL`，您还可以使用在`SubscriptionConfirmation`消息中`Token`设置相应值的[ConfirmSubscription](https://docs.aws.amazon.com/sns/latest/api/API_ConfirmSubscription.html)操作来确认订阅。如果您仅允许主题所有者和订阅所有者拥有取消订阅终端节点的权限，那么您可以通过 AWS 签名调用 `ConfirmSubscription` 操作。  
**通知**  
读取 `Subject` 和 `Message` 值，获取已向主题发布的通知信息。  
有关 `Notification` 消息格式的详细信息，请参阅 [HTTP/HTTPS 标题](http-header.md)。以下 HTTP POST 请求为向终端节点 example.com.发送的通知消息的示例。  

   ```
   POST / HTTP/1.1
       x-amz-sns-message-type: Notification
       x-amz-sns-message-id: 22b80b92-fdea-4c2c-8f9d-bdfb0c7bf324
       x-amz-sns-topic-arn: arn:aws:sns:us-west-2:123456789012:MyTopic
       x-amz-sns-subscription-arn: arn:aws:sns:us-west-2:123456789012:MyTopic:c9135db0-26c4-47ec-8998-413945fb5a96
       Content-Length: 773
       Content-Type: text/plain; charset=UTF-8
       Host: example.com
       Connection: Keep-Alive
       User-Agent: Amazon Simple Notification Service Agent
       
   {
     "Type" : "Notification",
     "MessageId" : "22b80b92-fdea-4c2c-8f9d-bdfb0c7bf324",
     "TopicArn" : "arn:aws:sns:us-west-2:123456789012:MyTopic",
     "Subject" : "My First Message",
     "Message" : "Hello world!",
     "Timestamp" : "2012-05-02T00:54:06.655Z",
     "SignatureVersion" : "1",
     "Signature" : "EXAMPLEw6JRN...",
     "SigningCertURL" : "https://sns.us-west-2.amazonaws.com/SimpleNotificationService-f3ecfb7224c7233fe7bb5f59f96de52f.pem",
     "UnsubscribeURL" : "https://sns.us-west-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-west-2:123456789012:MyTopic:c9135db0-26c4-47ec-8998-413945fb5a96"
   }
   ```

1. 确保您的终端节点已通过适当的状态代码对来自 Amazon SNS 的 HTTP POST 消息作出响应。此项连接将在大约 15 秒内超时。在连接超时前，如果您的端点不响应，或者您的端点返回的状态代码超出 200–4*xx* 范围，那么 Amazon SNS 会认为消息发送尝试失败。

1. 确保您的代码能够处理 Amazon SNS 的消息发送重试。如果 Amazon SNS 未能接收到从终端节点发出的发送成功响应，它将会尝试再次发送消息。这适用于包括订阅确认消息在内的所有消息。默认情况下，如果消息初次发送失败，那么 Amazon SNS 会通过失败尝试期间设定为 20 秒的延时进行多达 3 次的尝试。
**注意**  
消息请求大约 15 秒后超时。这表示，如果因超时引起消息发送失败，那么 Amazon SNS 将在前一次发送尝试后 35 秒左右重新发送。您可以为终端节点设置不同的发送策略。

   Amazon SNS 使用 `x-amz-sns-message-id` 标头字段来唯一标识发布到 Amazon SNS 主题的每条消息。通过将已处理 IDs 的消息与传入的消息进行比较，可以确定该消息是否为重试尝试。

1. 如果您要订阅 HTTPS 终端节点，请确保终端节点具备由可信赖证书颁发机构 (CA) 颁发的服务器证书。 将仅向具有 所信任 CA 签署的服务器证书的 HTTPS 终端节点发送消息。Amazon SNS 将仅向具有 Amazon SNS 所信任 CA 签署的服务器证书的 HTTPS 终端节点发送消息。

1. 对您已创建的代码进行部署，以便接收 Amazon SNS 消息。当您订阅终端节点时，该终端节点必须准备好至少接收订阅确认消息。

# 步骤 2：为 HTTP/HTTPS 终端节点订阅 Amazon SNS 主题
<a name="SendMessageToHttp.subscribe"></a>

要通过主题向 HTTP 或 HTTPS 终端节点发送消息，必须为终端节点订阅 Amazon SNS 主题。您可以通过终端节点的 URL 指定终端节点。要订阅主题，您可以使用 Amazon SNS 控制台、[sns-subscribe](https://docs.aws.amazon.com/cli/latest/reference/sns/subscribe.html) 命令或 [Subscribe](https://docs.aws.amazon.com/sns/latest/api/API_Subscribe.html) API 操作。开始操作前，应确保拥有想要订阅终端节点的 URL，并且该终端节点按照步骤 1 所述已准备好接收确认和通知消息。

**利用 Amazon SNS 控制台为 HTTP 或 HTTPS 终端节点订阅主题**

1. 登录 [Amazon SNS 控制台](https://console.aws.amazon.com/sns/home)。

1. 在导航面板中，选择**订阅**。

1. 选择 **Create subscription**（创建订阅）。

1. 在 **Protocol** 下拉列表中，选择 **HTTP** 或 **HTTPS**。

1. 在**终端节点**框中，粘贴您希望主题向其发送消息的终端节点的 URL，然后选择**创建订阅**。

1. 将显示确认消息。选择**关闭**。

   将显示您的新订**阅的订阅 ID** PendingConfirmation。当您确认订阅时，**Subscription ID (订阅 ID)** 将显示订阅 ID。

# 第 3 步：确认您的 Amazon SNS 订阅
<a name="SendMessageToHttp.confirm"></a>

要确认您的 Amazon SNS 订阅，请按照以下步骤操作，确保您的端点能够成功接收消息。此过程包括设置端点以处理传入的确认消息、检索确认 URL 以及确认订阅。您可以自动或手动确认订阅，具体取决于您的设置。

1. 订阅到 Amazon SNS 主题后，Amazon SNS 会向您的端点发送一条订阅确认消息。此消息包含 `SubscribeURL`，您必须用它来确认订阅。

1. 您的端点必须设置为监听来自 Amazon SNS 的传入消息。当确认消息到达时，从消息中提取 **`SubscribeURL`**。

1. 获得 `SubscribeURL` 后，您可以通过下列两种方式之一确认订阅：
   + **自动确认**：您的端点可以通过向 `SubscribeURL` 发送 **HTTP GET 请求**来自动确认订阅。

     此方法不需要手动干预。
   + **手动确认**：如果未设置自动确认，请**复制**确认消息中的 **`SubscribeURL`**，然后将其**粘贴**到浏览器的地址栏中。

     这将手动确认订阅。

1. 您还可以使用 Amazon SNS 控制台验证**订阅状态**。

   1. 登录 [Amazon SNS 控制台](https://console.aws.amazon.com/sns/home)。

   1. 在导航窗格中，选择**订阅**。

   1. 在列表中找到您的**订阅**。
      + 如果已确认，`SubscriptionArn` 将显示。
      + 如果仍未确认，它将显示为 `PendingConfirmation`。

# 步骤 4：可选 - 设置 Amazon SNS 订阅的传送策略
<a name="SendMessageToHttp.retry"></a>

默认情况下，如果消息初次发送失败，那么 Amazon SNS 会通过失败尝试期间设定为 20 秒的延时进行多达 3 次的尝试。按照[步骤 1](SendMessageToHttp.prepare.md) 所述，您的终端节点应包括能够处理已重试消息的代码。通过设置主题或订阅的发送策略，您可以控制 Amazon SNS 即将重试失败消息的频率和间隔。您还可以在中指定 HTTP/S 通知的内容类型`DeliveryPolicy`。有关更多信息，请参阅 [创建配 HTTP/S 送策略](sns-message-delivery-retries.md#creating-delivery-policy)。

# 步骤 5：可选 - 授予用户发布 Amazon SNS 主题的权限
<a name="SendMessageToHttp.iam.permissions"></a>

默认情况下，只有主题所有者才拥有发布主题的权限。要允许其他用户或应用程序向该主题发布内容，您应使用 AWS Identity and Access Management (IAM) 授予该主题的发布权限。有关授予 IAM 用户 Amazon SNS 操作权限的更多信息，请参阅 [将基于身份的策略用于 Amazon SNS](sns-using-identity-based-policies.md)。

可以采取两种方式控制对主题的访问：
+ 添加策略至 IAM 用户或群组。向用户授予主题权限的最简单方式就是创建群组，向该群组添加适当策略，再向此群组添加用户。相比较而言，向群组添加或删除用户，比追踪您为单独用户而设定的各项策略要简单得多。
+ 添加策略至主题。如果您想向另一 AWS 账户授予主题权限，那么唯一的方法是添加策略，并且该策略必须具备您想向其授予权限的主要 AWS 账户 。

绝大多数情况下，您应使用第一种方法（通过向群组添加或删除适当用户的方式，向群组添加策略，管理用户权限）。如果您需要向另一账户的用户授予权限，请使用第二种方法。

如果您向 IAM 用户或群组添加了以下策略，则需要向该用户或群组中的成员授予对该主题执行`sns:Publish`操作的权限 MyTopic。

```
{
  "Statement":[{
    "Sid":"AllowPublishToMyTopic",
    "Effect":"Allow",
    "Action":"sns:Publish",
    "Resource":"arn:aws:sns:us-east-2:123456789012:MyTopic"
  }]
}
```

以下策略示例显示如何向主题授予另一账户权限。

**注意**  
当您授予其他人 AWS 账户 访问您账户中某项资源的权限时，也就是向对该资源拥有管理员级访问权限（通配符访问权限）的 IAM 用户授予权限。此操作将自动拒绝其他账户中的所有其他 IAM 用户访问您的资源。如果您想向该中的特定 IAM 用户授予 AWS 账户 访问您的资源的权限，则该账户或具有管理员级别访问权限的 IAM 用户必须将资源权限委托给这些 IAM 用户。有关跨账户委派的更多信息，请参阅*使用 IAM 指南*中的[启用跨账户访问](https://docs.aws.amazon.com/IAM/latest/UserGuide/Delegation.html)。

如果您向账户 123456789012 MyTopic 中的某个主题添加了以下策略，则需要向账户 111122223333 授予对该主题执行操作的权限。`sns:Publish`

```
{
  "Statement":[{
    "Sid":"Allow-publish-to-topic",
    "Effect":"Allow",
      "Principal":{
        "AWS":"111122223333"
      },
    "Action":"sns:Publish",
    "Resource":"arn:aws:sns:us-east-2:123456789012:MyTopic"
  }]
}
```

# 步骤 6：向终端节点发送 Amazon SNS 消息 HTTP/HTTPS
<a name="SendMessageToHttp.publish"></a>

您可以通过发布到主题来向主题订阅发送消息。要订阅主题，您可以使用 Amazon SNS 控制台、`[sns-publish](https://docs.aws.amazon.com/cli/latest/reference/sns/publish.html)` CLI 命令或 `[Publish](https://docs.aws.amazon.com/sns/latest/api/API_Publish.html)` API。

如果您遵循 [步骤 1](SendMessageToHttp.prepare.md)，则在您的终端节点上部署的代码将处理通知。

**利用 Amazon SNS 控制台发布主题**

1. 使用有权发布主题的 AWS 账户 或 IAM 用户的证书，登录 AWS 管理控制台 并打开 Amazon SNS 控制台，网址为。[https://console.aws.amazon.com/sns/](https://console.aws.amazon.com/sns/home)

1. 在导航面板上，选择**主题**，然后选择一个主题。

1. 选择**发布消息**按钮。

1. 在**主题**框中，输入主题（例如，**Testing publish to my endpoint**）。

1. 在**消息**框中，输入一些文本（例如 **Hello world\$1**），然后选择 **发布消息**。

    界面将显示如下消息：Your message has been successfully published。

# 验证 Amazon SNS 消息签名
<a name="sns-verify-signature-of-message"></a>

Amazon SNS 使用消息签名来确认发送到您的 HTTP 端点的消息的真实性。为确保消息完整性并防止欺骗，您**必须**在处理任何 Amazon SNS 消息之前验证签名。

**什么时候应该验证 Amazon SNS 签名？**

在以下情况下，您应该验证 Amazon SNS 消息签名：
+ Amazon SNS 将通知消息发送到您的 HTTP(S) 端点时。
+ 当 Amazon SNS 在 [https://docs.aws.amazon.com/sns/latest/api/API_Subscribe.html](https://docs.aws.amazon.com/sns/latest/api/API_Subscribe.html) 或 [https://docs.aws.amazon.com/sns/latest/api/API_Unsubscribe.html](https://docs.aws.amazon.com/sns/latest/api/API_Unsubscribe.html) API 调用后向您的端点发送确认消息时。

**Amazon SNS 支持两种消息签名版本：**
+ SignatureVersion1-使用消息的SHA1哈希值。
+ SignatureVersion2-使用消息的SHA256哈希值。这提供了更强的安全性，推荐使用该选项。

**要正确验证 SNS 消息签名，请遵循以下最佳实践：**
+ 请务必使用 HTTPS 检索签名证书，以防止未经授权的拦截攻击。
+ 检查证书是否由 Amazon SNS 签发。
+ 确认证书的信任链有效。
+ 证书应来自 SNS 签名的 URL。
+ 未经验证，请勿信任消息中提供的任何证书。
+ 拒绝任何带有意外 `TopicArn` 的消息，以防止欺骗。
+  AWS SDKs 适用于 Amazon SNS 的提供了内置的验证逻辑，从而降低了错误实施的风险。

# 在 Amazon SNS 主题上配置消息签名版本
<a name="sns-verify-signature-of-message-configure-message-signature"></a>

通过在 Amazon SNS 主题中配置消息签名版本，您可以增强消息验证流程的安全性和兼容性。

在 `SignatureVersion` **1** (SHA1) 和 `SignatureVersion` **2** (SHA256) 之间进行选择，以控制用于签名消息的哈希算法。默认情况下，Amazon SNS 主题使用 `SignatureVersion`**1**。您可以使用 [https://docs.aws.amazon.com/sns/latest/api/API_SetTopicAttributes.html](https://docs.aws.amazon.com/sns/latest/api/API_SetTopicAttributes.html) API 操作配置此设置。

参照以下示例使用 AWS CLI设置主题属性 `SignatureVersion`：

```
aws sns set-topic-attributes \
    --topic-arn arn:aws:sns:us-east-2:123456789012:MyTopic \
    --attribute-name SignatureVersion \
    --attribute-value 2
```

# 在使用基于 HTTP 查询的请求时验证 Amazon SNS 消息的签名
<a name="sns-verify-signature-of-message-verify-message-signature"></a>

在使用基于 HTTP 查询的请求时验证 Amazon SNS 消息的签名，可确保消息的真实性和完整性。此过程确认消息源自 Amazon SNS，并且在传输过程中未被篡改。通过解析消息、构造正确的签名字符串以及根据可信的公有密钥验证签名，可以保护您的系统免受欺骗和未经授权的消息更改。

1. 从 Amazon SNS 发送的 HTTP POST 请求正文的 JSON 文档中提取**键值对**。这些字段是构造**待签字符串**所必需的。
   + `Message`
   + `Subject`（如果存在）
   + `MessageId`
   + `Timestamp`
   + `TopicArn`
   + `Type`

   例如：

   ```
   MESSAGE_FILE="message.json"
   FIELDS=("Message" "MessageId" "Subject" "Timestamp" "TopicArn" "Type")
   ```
**注意**  
如果任何字段包含转义字符（例如 `\n`），请将其转换为其**原始形式**以确保完全匹配。

1. 在 Amazon SNS 消息中找到 `SigningCertURL` 字段。该证书包含验证消息签名所需的公有密钥。例如：

   ```
   SIGNING_CERT_URL=$(jq -r '.SigningCertURL' "$MESSAGE_FILE")
   ```

1. 确保来自`SigningCertURL`可信 AWS 域（例如，https://sns.us-east-1.amazonaws.com）。出于安全考虑，拒绝任何 URLs **外部 AWS 域名**。

1. 从提供的 URL 下载 **X.509 证书**。例如：

   ```
   curl -s "$SIGNING_CERT_URL" -o signing_cert.pem
   ```

1. 从下载的 X.509 证书上提取**公有密钥**。您可以使用公有密钥解密消息的签名并验证其完整性。例如：

   ```
   openssl x509 -pubkey -noout -in signing_cert.pem > public_key.pem
   ```

1. 不同的消息类型需要在待签名字符串中使用不同的键值对。确定**消息类型**（Amazon SNS 消息中的 `Type` 字段）以确定要包含哪些**键值对**：
   + **通知消息**：包括 `Message`、`MessageId`、`Subject`（如果存在）`Timestamp`、`TopicArn`、和 `Type`。
   + **SubscriptionConfirmation**或**UnsubscribeConfirmation 消息**-包括`Message`、`MessageId``SubscribeURL`、`Timestamp`、`Token`、`TopicArn`、和`Type`。

1. Amazon SNS 要求待签名字符串遵循严格的固定字段顺序以进行验证。**必须仅包含明确必填的字段**，不能添加额外的字段。可选字段（例如 `Subject`）只有在消息中存在时才必须包含且必须出现在必填字段顺序所定义的确切位置。例如：

   ```
   KeyNameOne\nValueOne\nKeyNameTwo\nValueTwo
   ```
**重要**  
不要在消息结尾处添加换行符。

1. 按字节排序顺序（按键名称的字母顺序）排列**键值对**。

1. 参照以下格式示例构造**待签名字符串**：

   ```
   STRING_TO_SIGN=""
   for FIELD in "${FIELDS[@]}"; do
       VALUE=$(jq -r --arg field "$FIELD" '.[$field]' "$MESSAGE_FILE")
       STRING_TO_SIGN+="$FIELD\n$VALUE"
       # Append a newline after each field except the last one
       if [[ "$FIELD" != "Type" ]]; then
           STRING_TO_SIGN+="\n"
       fi
   done
   ```

   **通知消息示例：**

   ```
   Message
   My Test Message
   MessageId
   4d4dc071-ddbf-465d-bba8-08f81c89da64
   Subject
   My subject
   Timestamp
   2019-01-31T04:37:04.321Z
   TopicArn
   arn:aws:sns:us-east-2:123456789012:s4-MySNSTopic-1G1WEFCOXTC0P
   Type
   Notification
   ```

   **SubscriptionConfirmation 示例：**

   ```
   Message
   Please confirm your subscription
   MessageId
   3d891288-136d-417f-bc05-901c108273ee
   SubscribeURL
   https://sns.us-east-2.amazonaws.com/...
   Timestamp
   2024-01-01T00:00:00.000Z
   Token
   abc123...
   TopicArn
   arn:aws:sns:us-east-2:123456789012:MyTopic
   Type
   SubscriptionConfirmation
   ```

1. 消息中的 `Signature` 字段是经过 Base64 编码的。您需要对其进行**解码**，将其**原始二进制形式**与**派生的哈希值**进行比较。例如：

   ```
   SIGNATURE=$(jq -r '.Signature' "$MESSAGE_FILE")
   echo "$SIGNATURE" | base64 -d > signature.bin
   ```

1. 使用 `SignatureVersion` 字段选择哈希算法：
   + 对于 `SignatureVersion` **1**，使用 **SHA1**（例如，`-sha1`）。
   + 对于 `SignatureVersion` **2**，使用 **SHA256**（例如，`-sha256`）。

1. 要确认 Amazon SNS 消息的真实性，请生成构造字符串的**哈希值**，并使用**公有密钥**验证签名。

   ```
   openssl dgst -sha256 -verify public_key.pem -signature signature.bin <<< "$STRING_TO_SIGN"
   ```

   如果签名有效，则输出为 `Verified OK`。否则，输出为 `Verification Failure`。

## 带有错误处理的示例脚本
<a name="sns-verify-signature-of-message-example"></a>

以下示例脚本可自动执行验证流程：

```
#!/bin/bash

# Path to the local message file
MESSAGE_FILE="message.json"

# Extract the SigningCertURL and Signature from the message
SIGNING_CERT_URL=$(jq -r '.SigningCertURL' "$MESSAGE_FILE")
SIGNATURE=$(jq -r '.Signature' "$MESSAGE_FILE")

# Fetch the X.509 certificate
curl -s "$SIGNING_CERT_URL" -o signing_cert.pem

# Extract the public key from the certificate
openssl x509 -pubkey -noout -in signing_cert.pem > public_key.pem

# Define the fields to include in the string to sign
FIELDS=("Message" "MessageId" "Subject" "Timestamp" "TopicArn" "Type")

# Initialize the string to sign
STRING_TO_SIGN=""

# Iterate over the fields to construct the string to sign
for FIELD in "${FIELDS[@]}"; do
    VALUE=$(jq -r --arg field "$FIELD" '.[$field]' "$MESSAGE_FILE")
    STRING_TO_SIGN+="$FIELD\n$VALUE"
    # Append a newline after each field except the last one
    if [[ "$FIELD" != "Type" ]]; then
        STRING_TO_SIGN+="\n"
    fi
done

# Verify the signature
echo -e "$STRING_TO_SIGN" | openssl dgst -sha256 -verify public_key.pem -signature <(echo "$SIGNATURE" | base64 -d)
```

# 解析 Amazon SNS 消息格式
<a name="sns-message-and-json-formats"></a>

当 Amazon SNS 向 HTTP/HTTPS 终端节点发送消息时，它们同时包含 HTTP 标头和 JSON 消息正文。这些消息遵循特定的结构格式，其中包括消息类型、主题 ARN、时间戳以及数字签名等元数据。通过正确解析 Amazon SNS 消息，您可以判断消息是订阅确认、通知还是取消订阅确认，并提取相关数据，同时通过签名验证来确认消息的真实性。

# HTTP/HTTPS 标题
<a name="http-header"></a>

当 Amazon SNS 向 HTTP/HTTPS 终端节点发送订阅确认、通知或取消订阅确认消息时，它会发送一条包含许多 Amazon SNS 特定标头值的 POST 消息。可以使用标头值执行以下任务，例如识别消息类型而无需解析 JSON 消息主体来读取 `Type` 值。原定设置情况下，Amazon SNS 会将所有通知发送到 HTTP/S 端点，`Content-Type` 设置为 `text/plain; charset=UTF-8`。要选择 text/plain （默认）以`Content-Type`外的选项，请参阅`headerContentType`中的[创建配 HTTP/S 送策略](sns-message-delivery-retries.md#creating-delivery-policy)。

**`x-amz-sns-message-type`**  
消息类型。可能的值为 `SubscriptionConfirmation`、`Notification` 和 `UnsubscribeConfirmation`。

**`x-amz-sns-message-id`**  
通用唯一标识符（UUID），它对于每条发布的消息是唯一的。对于 Amazon SNS 在重试期间重新发送的通知，使用原始消息的消息 ID。

**`x-amz-sns-topic-arn`**  
此消息所发布到的主题的 Amazon 资源名称（ARN）。

**`x-amz-sns-subscription-arn`**  
用于订阅终端节点的 ARN。

下面的 HTTP POST 标头是一条发送至 HTTP 端点的 `Notification` 消息的标头示例。

```
POST / HTTP/1.1
x-amz-sns-message-type: Notification
x-amz-sns-message-id: 165545c9-2a5c-472c-8df2-7ff2be2b3b1b
x-amz-sns-topic-arn: arn:aws:sns:us-west-2:123456789012:MyTopic
x-amz-sns-subscription-arn: arn:aws:sns:us-west-2:123456789012:MyTopic:2bcfbf39-05c3-41de-beaa-fcfcc21c8f55
Content-Length: 1336
Content-Type: text/plain; charset=UTF-8
Host: myhost.example.com
Connection: Keep-Alive
User-Agent: Amazon Simple Notification Service Agent
```

# HTTP/HTTPS 订阅确认 JSON 格式
<a name="http-subscription-confirmation-json"></a>

在您订阅 HTTP/HTTPS 终端节点后，Amazon SNS 会向该 HTTP/HTTPS 终端节点发送订阅确认消息。此条消息包含您必须访问的 `SubscribeURL` 值，以确认订阅（或者，您可以将 `Token` 值与 [https://docs.aws.amazon.com/sns/latest/api/API_ConfirmSubscription.html](https://docs.aws.amazon.com/sns/latest/api/API_ConfirmSubscription.html) 结合使用）。

**注意**  
直到订阅被确认后，Amazon SNS 才会向终端节点发送通知

订阅确认消息是一条 POST 消息，消息正文包含一个带以下名称/值对的 JSON 格式文档。

**`Type`**  
消息类型。为订阅确认，消息类型为：`SubscriptionConfirmation`。

**`MessageId`**  
通用唯一标识符（UUID），它对于每条发布的消息是唯一的。对于 Amazon SNS 在重试期间重新发送的消息，原始消息的消息 ID 被使用。

**`Token`**  
您可以使用 [https://docs.aws.amazon.com/sns/latest/api/API_ConfirmSubscription.html](https://docs.aws.amazon.com/sns/latest/api/API_ConfirmSubscription.html) 操作确认订阅的一个值。或者，您只需访问`SubscribeURL`。

**`TopicArn`**  
终端节点已经订阅该主题的 Amazon Resource Name。

**`Message`**  
一个描述消息的字符串。为订阅确认，字符串看上去像这样：  

```
You have chosen to subscribe to the topic arn:aws:sns:us-east-2:123456789012:MyTopic.\nTo confirm the subscription, visit the SubscribeURL included in this message.
```

**`SubscribeURL`**  
为了确认订阅而必须访问的 URL。或者，您可以改为将 `Token` 与 [https://docs.aws.amazon.com/sns/latest/api/API_ConfirmSubscription.html](https://docs.aws.amazon.com/sns/latest/api/API_ConfirmSubscription.html) 操作结合使用以确认订阅。

**`Timestamp`**  
订阅确认发出的时间 (GMT)。

**`SignatureVersion`**  
所用 Amazon SNS 签名的版本。  
+ 如果 `SignatureVersion` 为 **1**，则 `Signature` 是 `Message`、`MessageId`、`Type`、`Timestamp` 和 `TopicArn` 值的 Base64 编码 `SHA1withRSA` 签名。
+ 如果 `SignatureVersion` 为 **2**，则 `Signature` 是 `Message`、`MessageId`、`Type`、`Timestamp` 和 `TopicArn` 值的 Base64 编码 `SHA256withRSA` 签名。

**`Signature`**  
`Message`、`MessageId`、`Type`、`Timestamp` 和 `TopicArn` 值的 Base64 编码 `SHA1withRSA` 或 `SHA256withRSA` 签名。

**`SigningCertURL`**  
用于签署消息的证书的 URL。

以下 HTTP POST 消息是发送至 HTTP 端点的一条 `SubscriptionConfirmation` 消息的示例。

```
POST / HTTP/1.1
x-amz-sns-message-type: SubscriptionConfirmation
x-amz-sns-message-id: 165545c9-2a5c-472c-8df2-7ff2be2b3b1b
x-amz-sns-topic-arn: arn:aws:sns:us-west-2:123456789012:MyTopic
Content-Length: 1336
Content-Type: text/plain; charset=UTF-8
Host: myhost.example.com
Connection: Keep-Alive
User-Agent: Amazon Simple Notification Service Agent

{
  "Type" : "SubscriptionConfirmation",
  "MessageId" : "165545c9-2a5c-472c-8df2-7ff2be2b3b1b",
  "Token" : "2336412f37...",
  "TopicArn" : "arn:aws:sns:us-west-2:123456789012:MyTopic",
  "Message" : "You have chosen to subscribe to the topic arn:aws:sns:us-west-2:123456789012:MyTopic.\nTo confirm the subscription, visit the SubscribeURL included in this message.",
  "SubscribeURL" : "https://sns.us-west-2.amazonaws.com/?Action=ConfirmSubscription&TopicArn=arn:aws:sns:us-west-2:123456789012:MyTopic&Token=2336412f37...",
  "Timestamp" : "2012-04-26T20:45:04.751Z",
  "SignatureVersion" : "1",
  "Signature" : "EXAMPLEpH+DcEwjAPg8O9mY8dReBSwksfg2S7WKQcikcNKWLQjwu6A4VbeS0QHVCkhRS7fUQvi2egU3N858fiTDN6bkkOxYDVrY0Ad8L10Hs3zH81mtnPk5uvvolIC1CXGu43obcgFxeL3khZl8IKvO61GWB6jI9b5+gLPoBc1Q=",
  "SigningCertURL" : "https://sns.us-west-2.amazonaws.com/SimpleNotificationService-f3ecfb7224c7233fe7bb5f59f96de52f.pem"
}
```

# HTTP/HTTPS 通知 JSON 格式
<a name="http-notification-json"></a>

当 Amazon SNS 向已订阅的 HTTP 或 HTTPS 终端节点发送一条通知时，发送到终端节点的 POST 消息具有包含一个带下列名称/值对的 JSON 格式文档的消息正文。

**`Type`**  
消息类型。用于通知，这种类型属于`Notification`。

**`MessageId`**  
通用唯一标识符（UUID），它对于每条发布的消息是唯一的。对于 Amazon SNS 在重试期间重新发送的通知，使用原始消息的消息 ID。

**`TopicArn`**  
此消息所发布到的主题的 Amazon 资源名称（ARN）。

**`Subject`**  
在将通知发布至主题时指定的 `Subject` 参数。  
此参数为可选参数。如果未指定 `Subject`，则此 JSON 格式文档中不会显示该名称/值对。

**`Message`**  
当通知发布至主题时指定的 `Message` 值。

**`Timestamp`**  
通知发布的时间 (GMT)。

**`SignatureVersion`**  
所用 Amazon SNS 签名的版本。  
+ 如果 `SignatureVersion` 为 **1**，则 `Signature` 是 `Message`、`MessageId`、`Subject`（如果存在）、`Type`、`Timestamp` 和 `TopicArn` 值的 Base64 编码 `SHA1withRSA` 签名。
+ 如果 `SignatureVersion` 为 **2**，则 `Signature` 是 `Message`、`MessageId`、`Subject`（如果存在）、`Type`、`Timestamp` 和 `TopicArn` 值的 Base64 编码 `SHA256withRSA` 签名。

**`Signature`**  
`Message`、`MessageId`、`Subject`（如果存在）、`Type`、`Timestamp` 和 `TopicArn` 值的 Base64 编码 `SHA1withRSA` 或 `SHA256withRSA` 签名。

**`SigningCertURL`**  
用于签署消息的证书的 URL。

**`UnsubscribeURL`**  
可以用作从主题取消订阅终端节点的 URL。如果您访问此 URL，那么 Amazon SNS 将取消订阅终端节点并不发送通知至此终端节点。

以下 HTTP POST 消息是发送至 HTTP 端点的一条 `Notification` 消息的示例。

```
POST / HTTP/1.1
x-amz-sns-message-type: Notification
x-amz-sns-message-id: 22b80b92-fdea-4c2c-8f9d-bdfb0c7bf324
x-amz-sns-topic-arn: arn:aws:sns:us-west-2:123456789012:MyTopic
x-amz-sns-subscription-arn: arn:aws:sns:us-west-2:123456789012:MyTopic:c9135db0-26c4-47ec-8998-413945fb5a96
Content-Length: 773
Content-Type: text/plain; charset=UTF-8
Host: myhost.example.com
Connection: Keep-Alive
User-Agent: Amazon Simple Notification Service Agent

{
  "Type" : "Notification",
  "MessageId" : "22b80b92-fdea-4c2c-8f9d-bdfb0c7bf324",
  "TopicArn" : "arn:aws:sns:us-west-2:123456789012:MyTopic",
  "Subject" : "My First Message",
  "Message" : "Hello world!",
  "Timestamp" : "2012-05-02T00:54:06.655Z",
  "SignatureVersion" : "1",
  "Signature" : "EXAMPLEw6JRN...",
  "SigningCertURL" : "https://sns.us-west-2.amazonaws.com/SimpleNotificationService-f3ecfb7224c7233fe7bb5f59f96de52f.pem",
  "UnsubscribeURL" : "https://sns.us-west-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-west-2:123456789012:MyTopic:c9135db0-26c4-47ec-8998-413945fb5a96"
  }
```

# HTTP/HTTPS 取消订阅确认 JSON 格式
<a name="http-unsubscribe-confirmation-json"></a>

在 HTTP/HTTPS 终端节点取消订阅主题后，Amazon SNS 会向该终端节点发送取消订阅确认消息。

取消订阅确认消息是一条 POST 消息，消息正文包含一个带以下名称/值对的 JSON 格式文档。

**`Type`**  
消息类型。为取消订阅确认，消息类型为`UnsubscribeConfirmation`。

**`MessageId`**  
通用唯一标识符（UUID），它对于每条发布的消息是唯一的。对于 Amazon SNS 在重试期间重新发送的消息，原始消息的消息 ID 被使用。

**`Token`**  
您可以使用 [https://docs.aws.amazon.com/sns/latest/api/API_ConfirmSubscription.html](https://docs.aws.amazon.com/sns/latest/api/API_ConfirmSubscription.html) 操作重新确认订阅的一个值。或者，您只需访问`SubscribeURL`。

**`TopicArn`**  
此终端节点已经从主题取消订阅的 Amazon Resource Name (ARN)。

**`Message`**  
一个描述消息的字符串。为了取消订阅确认，字符串应看起来像这样：  

```
You have chosen to deactivate subscription arn:aws:sns:us-east-2:123456789012:MyTopic:2bcfbf39-05c3-41de-beaa-fcfcc21c8f55.\nTo cancel this operation and restore the subscription, visit the SubscribeURL included in this message.
```

**`SubscribeURL`**  
为了重新确认订阅，您必须访问的 URL。或者，您可以改为将 `Token` 与 [https://docs.aws.amazon.com/sns/latest/api/API_ConfirmSubscription.html](https://docs.aws.amazon.com/sns/latest/api/API_ConfirmSubscription.html) 操作结合使用以重新确认订阅。

**`Timestamp`**  
取消订阅确认发送的时间(GMT)。

**`SignatureVersion`**  
所用 Amazon SNS 签名的版本。  
+ 如果 `SignatureVersion` 为 **1**，则 `Signature` 是 `Message`、`MessageId`、`Type`、`Timestamp` 和 `TopicArn` 值的 Base64 编码 `SHA1withRSA` 签名。
+ 如果 `SignatureVersion` 为 **2**，则 `Signature` 是 `Message`、`MessageId`、`Type`、`Timestamp` 和 `TopicArn` 值的 Base64 编码 `SHA256withRSA` 签名。

**`Signature`**  
`Message`、`MessageId`、`Type`、`Timestamp` 和 `TopicArn` 值的 Base64 编码 `SHA1withRSA` 或 `SHA256withRSA` 签名。

**`SigningCertURL`**  
用于签署消息的证书的 URL。

以下 HTTP POST 消息是发送至 HTTP 端点的一条 `UnsubscribeConfirmation` 消息的示例。

```
POST / HTTP/1.1
x-amz-sns-message-type: UnsubscribeConfirmation
x-amz-sns-message-id: 47138184-6831-46b8-8f7c-afc488602d7d
x-amz-sns-topic-arn: arn:aws:sns:us-west-2:123456789012:MyTopic
x-amz-sns-subscription-arn: arn:aws:sns:us-west-2:123456789012:MyTopic:2bcfbf39-05c3-41de-beaa-fcfcc21c8f55
Content-Length: 1399
Content-Type: text/plain; charset=UTF-8
Host: myhost.example.com
Connection: Keep-Alive
User-Agent: Amazon Simple Notification Service Agent

{
  "Type" : "UnsubscribeConfirmation",
  "MessageId" : "47138184-6831-46b8-8f7c-afc488602d7d",
  "Token" : "2336412f37...",
  "TopicArn" : "arn:aws:sns:us-west-2:123456789012:MyTopic",
  "Message" : "You have chosen to deactivate subscription arn:aws:sns:us-west-2:123456789012:MyTopic:2bcfbf39-05c3-41de-beaa-fcfcc21c8f55.\nTo cancel this operation and restore the subscription, visit the SubscribeURL included in this message.",
  "SubscribeURL" : "https://sns.us-west-2.amazonaws.com/?Action=ConfirmSubscription&TopicArn=arn:aws:sns:us-west-2:123456789012:MyTopic&Token=2336412f37fb6...",
  "Timestamp" : "2012-04-26T20:06:41.581Z",
  "SignatureVersion" : "1",
  "Signature" : "EXAMPLEHXgJm...",
  "SigningCertURL" : "https://sns.us-west-2.amazonaws.com/SimpleNotificationService-f3ecfb7224c7233fe7bb5f59f96de52f.pem"
}
```

# SetSubscriptionAttributes 交付策略 JSON 格式
<a name="set-sub-attributes-delivery-policy-json"></a>

如果您向 `SetSubscriptionAttributes` 操作发送一个请求并将 `AttributeName` 参数设置为 `DeliveryPolicy` 值，那么 `AttributeValue` 参数的值必须是一个有效的 JSON 对象。例如，以下例子将传输策略设置为 5 次重试。

```
http://sns.us-east-2.amazonaws.com/
?Action=SetSubscriptionAttributes
&SubscriptionArn=arn%3Aaws%3Asns%3Aus-east-2%3A123456789012%3AMy-Topic%3A80289ba6-0fd4-4079-afb4-ce8c8260f0ca
&AttributeName=DeliveryPolicy
&AttributeValue={"healthyRetryPolicy":{"numRetries":5}}
...
```

为 `AttributeValue` 参数的值使用下列 JSON 格式。

```
{
    "healthyRetryPolicy" : {
        "minDelayTarget" :  int,
        "maxDelayTarget" : int,
        "numRetries" : int,
        "numMaxDelayRetries" : int,
        "backoffFunction" : "linear|arithmetic|geometric|exponential"
    },
    "throttlePolicy" : {
        "maxReceivesPerSecond" : int
    },
    "requestPolicy" : {
        "headerContentType" : "text/plain | application/json | application/xml"
    }
}
```

有关该`SetSubscriptionAttribute`操作的更多信息，请[SetSubscriptionAttributes](https://docs.aws.amazon.com/sns/latest/api/API_SetSubscriptionAttributes.html)访问《*亚马逊简单通知服务 API 参考*》。有关支持的 HTTP content-type 标头的更多信息，请参阅[创建配 HTTP/S 送策略](sns-message-delivery-retries.md#creating-delivery-policy)。

# SetTopicAttributes 交付策略 JSON 格式
<a name="set-topic-attributes-delivery-policy-json"></a>

如果您向 `SetTopicAttributes` 操作发送一个请求并将 `AttributeName` 参数设置为 `DeliveryPolicy` 值，那么 `AttributeValue` 参数的值必须是一个有效的 JSON 对象。例如，以下例子将传输策略设置为 5 次重试。

```
http://sns.us-east-2.amazonaws.com/
?Action=SetTopicAttributes
&TopicArn=arn%3Aaws%3Asns%3Aus-east-2%3A123456789012%3AMy-Topic
&AttributeName=DeliveryPolicy
&AttributeValue={"http":{"defaultHealthyRetryPolicy":{"numRetries":5}}}
...
```

为 `AttributeValue` 参数的值使用下列 JSON 格式。

```
{
    "http" : {
        "defaultHealthyRetryPolicy" : {
            "minDelayTarget":  int,
            "maxDelayTarget": int,
            "numRetries": int,
            "numMaxDelayRetries": int,
            "backoffFunction": "linear|arithmetic|geometric|exponential"
        },
        "disableSubscriptionOverrides" : Boolean,
        "defaultThrottlePolicy" : {
            "maxReceivesPerSecond" : int
        },
        "defaultRequestPolicy" : {
            "headerContentType" : "text/plain | application/json | application/xml"
        }
    }
}
```

有关该`SetTopicAttribute`操作的更多信息，请[SetTopicAttributes](https://docs.aws.amazon.com/sns/latest/api/API_SetTopicAttributes.html)访问《*亚马逊简单通知服务 API 参考*》。有关支持的 HTTP content-type 标头的更多信息，请参阅[创建配 HTTP/S 送策略](sns-message-delivery-retries.md#creating-delivery-policy)。

# Fanout Amazon SNS 事件 AWS 到事件分叉管道
<a name="sns-fork-pipeline-as-subscriber"></a>


|  | 
| --- |
| 对于事件归档和分析，Amazon SNS 现在建议使用其与 Amazon Data Firehose 的本机集成。您可以将 Firehose 传输流订阅 SNS 主题，这样您就可以向存档和分析终端节点发送通知，例如亚马逊简单存储服务 (Amazon S3) 存储桶、亚马逊 Redshift 表、亚马逊 OpenSearch 服务（服务）等。OpenSearch 将 Amazon SNS 与 Firehose 传输流配合使用是一种完全托管且无需代码的解决方案，您无需使用任何功能。 AWS Lambda 有关更多信息，请参阅 [扇出到 Firehose 传输流](sns-firehose-as-subscriber.md)。 | 

您可以使用 Amazon SNS 构建事件驱动的应用程序，这些应用程序使用订阅者服务自动执行工作以响应发布者服务所触发的事件。此架构模式可提高服务的可重用性、可互操作性和可扩展性。但是，将事件处理分解为可满足常见事件处理要求的管道（例如，事件存储、备份、搜索、分析和重放）可能会非常耗费人力。

为了加快事件驱动型应用程序的开发，您可以订阅 Amazon SNS 主题的事件处理管道（由事件 AWS 分叉管道提供支持）。 AWS Event Fork Pipelines 是一套基于[AWS 无服务器应用程序模型](https://aws.amazon.com/serverless/sam/) (SA AWS M) 的开源[嵌套](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-template-nested-applications.html)应用程序，您可以直接从 Ev [AWS ent Fork Pipelines 套件](https://serverlessrepo.aws.amazon.com/applications?query=aws-event-fork-pipelines)（选择**显示创建自定义 IAM 角色或资源策略的应用程序**）将其部署到您的 AWS 账户中。

有关 E AWS vent Fork Pipelines 用例，请参阅[部署和测试 Amazon SNS Event Fork Pipelines 示例应用程序](sns-deploy-test-fork-pipelines-sample-application.md)。

**Topics**
+ [AWS 事件分叉管道的工作原理](#how-sns-fork-works)
+ [部署 AWS 事件分叉管道](#deploying-sns-fork-pipelines)
+ [部署和测试 Amazon SNS Event Fork Pipelines 示例应用程序](sns-deploy-test-fork-pipelines-sample-application.md)
+ [将 AWS 事件分叉管道订阅到 Amazon SNS 主题](sns-subscribe-event-fork-pipelines.md)

## AWS 事件分叉管道的工作原理
<a name="how-sns-fork-works"></a>

AWS Event Fork Pipelines 是一种无服务器设计模式。但是，它也是一套基于 S AWS AM 的嵌套无服务器应用程序（您可以将其直接从 AWS Serverless Application Repository (S AWS AR) 部署到您的， AWS 账户 以丰富您的事件驱动平台）。您可以根据架构的需要单独部署这些嵌套的应用程序。

**Topics**
+ [事件存储与备份管线](#sns-fork-event-storage-and-backup-pipeline)
+ [事件搜索与分析管线](#sns-fork-event-search-and-analytics-pipeline)
+ [事件重播管线](#sns-fork-event-replay-pipeline)

下图显示了一个由三个嵌套应用程序补充的 AWS Event Fork Pipelines 应用程序。根据您的架构要求，您可以在 AWS SAR 上独立部署 AWS Event Fork Pipelines 套件中的任何管道。

![\[AWS 事件分叉管道架构，展示了如何通过三个不同的管道筛选和处理来自 Amazon SNS 主题的事件：事件存储和备份、事件搜索和分析以及事件重播。这些管线被描绘成垂直堆叠的框，每个管线都独立并行处理来自同一 Amazon SNS 主题的事件。\]](http://docs.aws.amazon.com/zh_cn/sns/latest/dg/images/sns-fork-pipeline-as-subscriber-how-it-works.png)


为每个管线订阅了相同的 Amazon SNS 主题，并允许管线在事件发布到主题时并行处理这些事件。每个管线都是独立的，并且可以设置其自己的[订阅筛选策略](sns-subscription-filter-policies.md)。这允许管线仅处理它感兴趣的部分事件（而不是发布到主题的所有事件）。

**注意**  
由于您将三个 AWS 事件分叉管道放置在常规事件处理管道旁边（可能已经订阅了您的 Amazon SNS 主题），因此您无需更改当前消息发布者的任何部分即可在现有 AWS 工作负载中利用事件分叉管道。

### 事件存储与备份管线
<a name="sns-fork-event-storage-and-backup-pipeline"></a>

下图显示了[事件存储与备份管线](https://serverlessrepo.aws.amazon.com/applications/arn:aws:serverlessrepo:us-east-1:077246666028:applications~fork-event-storage-backup-pipeline)。您可以为此管线订阅 Amazon SNS 主题来自动备份流经系统的事件。

该管道由一个用于缓冲由 Amazon SNS 主题传送的事件的 Amazon SQS 队列、一个自动轮询队列中这些事件并将其推送到流中的 AWS Lambda 函数以及一个持久备份流加载的事件的 Amazon S3 存储桶组成。

![\[Fork-Event-Storage-Backup-Pipeline，旨在处理和备份 Amazon SNS 主题中的事件。流程从 Amazon SNS 主题开始，事件通过该流程扇出到 Amazon SQS 队列。然后，这些经过筛选的事件由 Lambda 函数处理，该函数会将它们转发到 Data Firehose。在将事件加载到 Amazon S3 备份存储桶之前，Firehose 流负责缓冲、转换和压缩这些事件。最后，可以使用 Amazon Athena 来查询存储的数据。该图使用一系列图标和箭头来说明从一项服务到另一项服务的流程，清楚地标记了管线的每个组件。\]](http://docs.aws.amazon.com/zh_cn/sns/latest/dg/images/sns-fork-event-storage-and-backup-pipeline.png)


要微调 Firehose 流的行为，可将其配置为在将事件加载到存储桶之前对事件进行缓冲、转换和压缩。在加载事件时，可以使用 Amazon Athena 通过标准 SQL 查询来查询存储桶。您也可以将管道配置为重用现有 Amazon S3 存储桶或创建一个新的存储桶。

### 事件搜索与分析管线
<a name="sns-fork-event-search-and-analytics-pipeline"></a>

下图显示了[事件搜索与分析管线](https://serverlessrepo.aws.amazon.com/applications/arn:aws:serverlessrepo:us-east-1:077246666028:applications~fork-event-search-analytics-pipeline)。您可以为此管线订阅 Amazon SNS 主题以便在搜索域中为流经系统的事件编制索引，然后对这些事件进行分析。

该管道由一个用于缓冲由 Amazon SNS 主题传送的事件的 Amazon SQS 队列、一个轮询队列中的事件并将其推 OpenSearch 送到流中的 AWS Lambda 函数、一个为 Firehose 流加载的事件编制索引的 Amazon S3 域以及一个存储无法在搜索域中编制索引的死信事件的 Amazon S3 存储桶组成。

![\[AWS 架构中的事件搜索和分析管道。它从左边开始，Amazon SNS 主题接收所有事件。然后，这些事件通过表示“扇出筛选出的事件”的虚线汇入到 Amazon SQS 队列中。该队列中的事件由 Lambda 函数处理，该函数随后将事件转到 Data Firehose 流。Data Firehose 将事件定向到两个目的地：一条路由通向 Amazon Elasticsearch Service 进行索引，另一条路由将无法处理的事件或“死信”事件发送到 Amazon S3 死信存储桶。在最右边，Elasticsearch Service 的输出馈送到 Kibana 控制面板中进行分析和可视化。整个流程是水平布局的，每个组件都通过显示数据流方向的线条相连。\]](http://docs.aws.amazon.com/zh_cn/sns/latest/dg/images/sns-fork-event-search-and-analytics-pipeline.png)


要在事件缓冲、转换和压缩方面微调 Firehose 流，您可以配置此管线。

您还可以配置管道是应重复使用您的现有 OpenSearch 域 AWS 账户 还是为您创建一个新域。在搜索域中为事件编制索引时，您可以使用 Kibana 对事件运行分析并实时更新可视化控制面板。

### 事件重播管线
<a name="sns-fork-event-replay-pipeline"></a>

下图显示了[事件重播管线](https://serverlessrepo.aws.amazon.com/applications/arn:aws:serverlessrepo:us-east-1:077246666028:applications~fork-event-replay-pipeline)。要记录系统在过去 14 天内处理过的事件（例如，当您的平台需要从故障中恢复时），您可以为此管道订阅 Amazon SNS 主题，然后重新处理事件。

该管道由一个 Amazon SQS 队列和一个 AWS Lambda 函数组成，该队列用于缓冲由 Amazon SNS 主题传送的事件，以及一个用于轮询队列中的事件并将其重新驱动到您的常规事件处理管道的函数，该管道也已订阅您的主题。

![\[流程图格式的事件重播管线。从左到右，它以 Amazon SNS 主题开头，该主题将经过筛选的事件分发给两个并行进程。上方的流程代表您的常规事件处理管线，其中包括处理事件的 Amazon SQS 队列。标记为 “fork-event-replay-pipeline” 的下层流程包括一个 Amazon SQS 重播队列，事件在由 Lambda 重播函数处理之前会暂时存储在该队列中。此 Lambda 函数能够根据重播功能的启用还是禁用，将事件重新导入您的常规事件处理管线中或将其保留以供重播。该图还表明，操作员可以控制启用或禁用事件重播功能。\]](http://docs.aws.amazon.com/zh_cn/sns/latest/dg/images/sns-fork-event-replay-pipeline.png)


**注意**  
默认情况下，重播功能已禁用，而不会重新导入您的事件。如果您需要重新处理事件，则必须启用 Amazon SQS 重播队列作为 AWS Lambda 重播函数的事件源。

## 部署 AWS 事件分叉管道
<a name="deploying-sns-fork-pipelines"></a>

[AWS Event Fork Pipelines 套件](https://serverlessrepo.aws.amazon.com/applications?query=aws-event-fork-pipelines)**（选择 “显示创建自定义 IAM 角色或资源策略**的应用程序”）在中作为一组公共应用程序提供 AWS Serverless Application Repository，您可以从中使用[AWS Lambda 控制台](https://console.aws.amazon.com/lambda/)手动部署和测试它们。有关使用 AWS Lambda 控制台部署管道的信息，请参阅[将 AWS 事件分叉管道订阅到 Amazon SNS 主题](sns-subscribe-event-fork-pipelines.md)。

在生产场景中，我们建议在整个应用程序的 AWS SAM 模板中嵌入 AWS 事件分支管道。嵌套应用程序功能允许您通过将资源添加到 AWS SAM 模板、引用嵌套应用程序的 S AWS AR `ApplicationId` 和`[AWS::Serverless::Application](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-template.html#serverless-sam-template-application)`来实现此`SemanticVersion`目的。

例如，您可以将以下 YAML 代码段添加到 SA AWS M 模板的`Resources`部分，从而将事件存储和备份管道用作嵌套应用程序。

```
Backup:   
    Type: AWS::Serverless::Application
  Properties:
    Location:
      ApplicationId: arn:aws:serverlessrepo:us-east-2:123456789012:applications/fork-event-storage-backup-pipeline
      SemanticVersion: 1.0.0
    Parameters: 
      #The ARN of the Amazon SNS topic whose messages should be backed up to the Amazon S3 bucket.
      TopicArn: !Ref MySNSTopic
```

指定参数值时，您可以使用 AWS CloudFormation 内部函数来引用模板中的其他资源。例如，在上面的 YAML 片段中，`TopicArn`参数引用了模板中其他地方定义的`[AWS::SNS::Topic](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sns-topic.html)` AWS SAM 资源`MySNSTopic`。有关更多信息，请参阅 *AWS CloudFormation 用户指南*中的[内置函数参考](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference.html)。

**注意**  
您的 AWS SAR 应用程序的 AWS Lambda 控制台页面包括**复制为 SAM 资源**按钮，该按钮可将嵌套 SA AWS R 应用程序所需的 YAML 复制到剪贴板。

# 部署和测试 Amazon SNS Event Fork Pipelines 示例应用程序
<a name="sns-deploy-test-fork-pipelines-sample-application"></a>

为了加快事件驱动型应用程序的开发，您可以订阅 Amazon SNS 主题的事件处理管道（由事件 AWS 分叉管道提供支持）。 AWS Event Fork Pipelines 是一套基于[AWS 无服务器应用程序模型](https://aws.amazon.com/serverless/sam/) (SA AWS M) 的开源[嵌套](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-template-nested-applications.html)应用程序，您可以直接从 Ev [AWS ent Fork Pipelines 套件](https://serverlessrepo.aws.amazon.com/applications?query=aws-event-fork-pipelines)（选择**显示创建自定义 IAM 角色或资源策略的应用程序**）将其部署到您的 AWS 账户中。有关更多信息，请参阅 [AWS 事件分叉管道的工作原理](sns-fork-pipeline-as-subscriber.md#how-sns-fork-works)。

本页介绍如何使用部署和测试 E AWS vent Fork Pipelines 示例应用程序。 AWS 管理控制台 

**重要**  
为避免在部署完 AWS 事件分支管道示例应用程序后产生不必要的费用，请删除其 CloudFormation 堆栈。有关更多信息，请参阅 *AWS CloudFormation 用户指南*中的[在 CloudFormation 控制台上删除堆栈](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-console-delete-stack.html)。

# AWS 事件分叉管道用例示例
<a name="example-sns-fork-use-case"></a>

以下场景描述了一个使用 Event Fork Pipelines AWS 的事件驱动型无服务器电子商务应用程序。您可以在中使用此[示例电子商务应用程序](https://serverlessrepo.aws.amazon.com/applications/arn:aws:serverlessrepo:us-east-1:077246666028:applications~fork-example-ecommerce-checkout-api)， AWS Serverless Application Repository 然后 AWS 账户 使用控制台将其部署到您的 AWS Lambda 控制台中，您可以在其中对其进行测试并检查其源代码 GitHub。

![\[集成 AWS 服务的无服务器电子商务应用程序的架构。它描绘了从电子商务用户通过 API Gateway 下订单到包括订单存储、搜索分析和重播在内的不同处理管道的流程，展示了如何通过 Amazon SNS、Lambda、Amazon SQS、DynamoDB 和 Kibana 管理和分析事件。\]](http://docs.aws.amazon.com/zh_cn/sns/latest/dg/images/sns-fork-example-use-case.png)


该电子商务应用程序通过 RESTful API Gateway托管并由该 AWS Lambda 功能支持的API接受买家的订单`CheckoutApiBackendFunction`。此函数将收到的所有订单发布到名为 `CheckoutEventsTopic` 的 Amazon SNS 主题，该主题转而将订单分散到四个不同的管道。

第一个管道是由电子商务应用程序的拥有者设计和实现的常规结算处理管道。该管道具有用于缓冲所有已收到订单的 Amazon SQS 队列`CheckoutQueue`、一个名为`CheckoutFunction`的 AWS Lambda 函数，用于轮询队列以处理这些订单，还有一个用于安全保存所有已下订单的 DynamoDB 表`CheckoutTable`。

## 应用 AWS 事件分叉管道
<a name="applying-sns-fork-pipelines"></a>

电子商务应用程序的组件处理核心业务逻辑。但是，电子商务应用程序拥有者还需满足：
+ **合规性** - 安全的、压缩的静态加密备份，清理敏感信息
+ **弹性** - 在执行过程中断的情况下重播最近的订单
+ **可搜索性** - 对已下订单运行分析并生成指标

应用程序所有者无需实现此事件处理逻辑，而是可以订阅 `CheckoutEventsTopic` Amazon SNS 主题的 AWS Event Fork Pipelines
+ [事件存储与备份管线](sns-fork-pipeline-as-subscriber.md#sns-fork-event-storage-and-backup-pipeline)配置为转换数据以删除信用卡详细信息，缓冲数据 60 秒，使用 GZIP 压缩数据，并使用 Amazon S3 的原定设置客户自主管理型密钥来加密数据。此密钥由 () 管理 AWS 并由 AWS Key Management Service (AWS KMS) 提供支持。

  有关更多信息，请参阅《Amazon Data Firehose 开发人员指南》**中的[为您的目的地选择 Amazon S3](https://docs.aws.amazon.com/firehose/latest/dev/create-destination.html#create-destination-s3)、[Amazon Data Firehose 数据转换](https://docs.aws.amazon.com/firehose/latest/dev/data-transformation.html)和[配置设置](https://docs.aws.amazon.com/firehose/latest/dev/create-configure.html)。
+ 为[事件搜索与分析管线](sns-fork-pipeline-as-subscriber.md#sns-fork-event-search-and-analytics-pipeline)配置了一个 30 秒的索引重试持续时间、一个用于存储无法在搜索域中编制索引的订单的存储桶和一个用来限制已编制索引的订单集的筛选策略。

  有关更多信息，请参阅 *Amazon Data Firehose 开发者*指南中的[为您的目的地选择 OpenSearch 服务](https://docs.aws.amazon.com/firehose/latest/dev/create-destination.html#create-destination-elasticsearch)。
+ [事件重播管线](sns-fork-pipeline-as-subscriber.md#sns-fork-event-replay-pipeline) 为配置了常规订单处理管道（由电子商务应用程序拥有者设计和实施）的 Amazon SQS 队列部分。

  有关更多信息，请参阅 *Amazon Simple Queue Service 开发人员指南*中的[队列名称和 URL](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-general-identifiers.html#queue-name-url)。

在事件搜索与分析管道的配置中设置以下 JSON 筛选策略。它仅匹配总金额为 100 美元或更多的传入订单。有关更多信息，请参阅 [Amazon SNS 消息筛选](sns-message-filtering.md)。

```
{				
   "amount": [{ "numeric": [ ">=", 100 ] }]
}
```

使用 E AWS vent Fork Pipelines 模式，电子商务应用程序所有者可以避免开发开销，这种开销通常是在为事件处理编写非微分逻辑之后出现的。取而代之的是，她可以将 AWS 事件分叉管道直接从部署 AWS Serverless Application Repository 到她身上 AWS 账户。

# 第 1 步：部署 Amazon SNS 示例应用程序
<a name="deploy-sample-application"></a>

1. 登录 [AWS Lambda 控制台](https://console.aws.amazon.com/lambda/)。

1. 在导航面板上，选择 **Functions (函数)**，然后选择 **Create function (创建函数)**。

1. 在 **Create function (创建函数)** 页面上，执行以下操作：

   1. 依次选择 **Browse serverless app repository（浏览无服务器应用程序存储库）**、**Public applications（公共应用程序）**、**Show apps that create custom roles or resource policies（显示创建 IAM 角色或资源策略的应用程序）**。

   1. 搜索 `fork-example-ecommerce-checkout-api`，然后选择该应用程序。

1. 在 **fork-example-ecommerce-checkout-api** 页面上，执行以下操作：

   1. 在 **Application settings (应用程序设置)** 部分中，输入 **Application name (应用程序名称)**（例如，`fork-example-ecommerce-my-app`）。
**注意**  
要稍后轻松找到您的资源，请保留前缀 `fork-example-ecommerce`。
对于每个部署，应用程序名称必须唯一。如果您重复使用应用程序名称，则部署将仅更新先前部署的 CloudFormation 堆栈（而不是创建新的堆栈）。

   1. （可选）输入以下**LogLevel**设置之一以执行应用程序的 Lambda 函数：
      + `DEBUG`
      + `ERROR`
      + `INFO`（默认值）
      + `WARNING`

1. 选择 **I acknowledge that this app creates custom IAM roles, resource policies and deploys nested applications (我确认此应用程序创建自定义 IAM 角色和资源策略并部署嵌套应用程序)**，然后在页面底部选择 **Deploy (部署)**。

在 **fork-example-ecommerce-的部署状态*my-app***页面上，Lambda 会显示 “**您的应用程序正在部署中**” 状态。

在**资源**部分中， CloudFormation 开始创建堆栈并显示每个资源的 **CREATE\$1IN\$1PROGRESS** 状态。该过程完成后， CloudFormation 将显示 “**创建\$1完成**” 状态。

**注意**  
部署所有资源可能需要 20-30 分钟。

部署完成后，Lambda 将显示 **Your application has been deployed（您的应用程序已部署完成）**状态。

# 步骤 2：执行与 SNS 关联的示例应用程序
<a name="execute-sample-application"></a>

1. 在 AWS Lambda 控制台的导航面板上，选择**应用程序**。

1. 在 **Applications (应用程序)** 页面上的搜索字段中，搜索 `serverlessrepo-fork-example-ecommerce-my-app`，然后选择该应用程序。

1. 在 **Resources (资源)** 部分中，执行以下操作：

   1. 例如，要查找类型为的资源 **ApiGatewayRestApi**，请按**类型**对资源进行排序`ServerlessRestApi`，然后展开该资源。

   1. 将显示两个嵌套资源，分别是 “**ApiGateway部署**” 和 “**ApiGateway阶段**”。

   1. 复制链接 **Prod API endpoint (Prod API 终端节点)** 并为其附加 `/checkout`，例如：

      ```
      https://abcdefghij.execute-api.us-east-2.amazonaws.com/Prod/checkout
      ```

1. 将以下 JSON 复制到名为 `test_event.json` 的文件中。

   ```
   {
      "id": 15311,
      "date": "2019-03-25T23:41:11-08:00",
      "status": "confirmed",
      "customer": {
         "id": 65144,		
   	 "quantity": 2,
         "price": 25.00,
         "subtotal": 50.00
      }]
   }
   ```

1. 要将 HTTPS 请求发送到您的 API 端点，请通过执行 `curl` 命令来将示例事件负载作为输入传递，例如：

   ```
   curl -d "$(cat test_event.json)" https://abcdefghij.execute-api.us-east-2.amazonaws.com/Prod/checkout
   ```

   API 将返回以下空响应，并指示已成功执行：

   ```
   { }
   ```

# 第 3 步：验证 Amazon SNS 应用程序和管道性能
<a name="verify-sample-application-pipelines"></a>

## 步骤 1：验证示例签出管道的执行
<a name="verify-execution-checkout-pipeline"></a>

1. 登录 [Amazon DynamoDB 控制台](https://console.aws.amazon.com/dynamodb/)。

1. 在导航面板上，选择**表**。

1. 搜索 `serverlessrepo-fork-example` 并选择 `CheckoutTable`。

1. 在表详细信息页面上，选择**项目**，然后选择已创建的项目。

   将显示存储的属性。

## 步骤 2：验证事件存储与备份管道的执行
<a name="verify-execution-event-storage-backup-pipeline"></a>

1. 登录 [Amazon S3 控制台](https://console.aws.amazon.com/s3/)。

1. 在导航面板上，选择 **Buckets (存储桶)**。

1. 搜索 `serverlessrepo-fork-example`，然后选择 `CheckoutBucket`。

1. 导航目录层次结构，直到找到扩展名为 `.gz` 的文件。

1. 要下载该文件，请依次选择 **Actions (操作)** 和 **Open (打开)**。

1. 为管道配置了一个 Lambda 函数，此函数将清理信用卡信息以实现合规性。

   要验证存储的 JSON 负载不包含任何信用卡信息，请解压缩该文件。

## 步骤 3：验证事件搜索与分析管道的执行
<a name="verify-execution-event-search-analytics-pipeline"></a>

1. 登录到[OpenSearch 服务控制台](https://console.aws.amazon.com/aos/)。

1. 在导航面板上的 **My domains (我的域)** 下，选择前缀为 `serverl-analyt` 的域。

1. 为管道配置了一个 Amazon SNS 订阅筛选策略，该策略设置一个数值匹配条件。

   ****要验证该事件是否因为指的是价值高于100美元的订单而被索引，请在**服务器分析*abcdefgh1ijk*页面上选择指数，checkout\$1even** ts。****

## 步骤 4：验证事件重播管道的执行
<a name="verify-execution-event-replay-pipeline"></a>

1. 登录 [Amazon SQS 控制台](https://console.aws.amazon.com/sqs/)。

1. 在队列列表中，搜索 `serverlessrepo-fork-example` 并选择 `ReplayQueue`。

1. 选择**发送和接收消息**。

1. 在 **fork-example-ecommerce-*my-app*... ReplayP-ReplayQueue-中发送和接收消息*123ABCD4E5F6***对话框中，选择**轮询留**言。

1. 要验证事件是否已入队，请选择队列中显示的消息旁边的 **More Details (更多详细信息)**。

# 步骤 4：模拟问题并重播事件以进行恢复
<a name="simulate-issue-replay-events-for-recovery"></a>

## 步骤 1：启用模拟的问题并发送第二个 API 请求
<a name="enable-simulated-issue-send-second-api-request"></a>

1. 登录 [AWS Lambda 控制台](https://console.aws.amazon.com/lambda/)。

1. 在导航面板上，选择 **Functions (函数)**。

1. 搜索 `serverlessrepo-fork-example` 并选择 `CheckoutFunction`。

1. 在 **fork-example-ecommerce-*my-app*-CheckoutFunction-*ABCDEF*...** **页面的**环境变量**部分中，将 **BUG\$1** ENABLED 变量设置**为 true**，然后选择保存。**

1. 将以下 JSON 复制到名为 `test_event_2.json` 的文件中。

   ```
   {
   	   "id": 9917,
   	   "date": "2019-03-26T21:11:10-08:00",
   	   "status": "confirmed",
   	   "customer": {
   	      "id": 56999,
   "quantity": 1,
   	      "price": 75.00,
   	      "subtotal": 75.00
   	   }]
   	}
   ```

1. 要将 HTTPS 请求发送到您的 API 端点，请通过执行 `curl` 命令来将示例事件负载作为输入传递，例如：

   ```
   curl -d "$(cat test_event_2.json)" https://abcdefghij.execute-api.us-east-2.amazonaws.com/Prod/checkout
   ```

   API 将返回以下空响应，并指示已成功执行：

   ```
   { }
   ```

## 步骤 2：验证模拟数据损坏
<a name="verify-simulated-data-corruption"></a>

1. 登录 [Amazon DynamoDB 控制台](https://console.aws.amazon.com/dynamodb/)。

1. 在导航面板上，选择**表**。

1. 搜索 `serverlessrepo-fork-example` 并选择 `CheckoutTable`。

1. 在表详细信息页面上，选择**项目**，然后选择已创建的项目。

   将显示存储的属性，其中一些标记为 **CORRUPTED\$1 (已损坏\$1)**

## 步骤 3：禁用模拟的问题
<a name="disable-simulated-issue"></a>

1. 登录 [AWS Lambda 控制台](https://console.aws.amazon.com/lambda/)。

1. 在导航面板上，选择 **Functions (函数)**。

1. 搜索 `serverlessrepo-fork-example` 并选择 `CheckoutFunction`。

1. 在 **fork-example-ecommerce-*my-app*-CheckoutFunction-*ABCDEF*...** **页面的**环境变量**部分中，将 **BUG\$1** ENABLED 变量设置**为 false**，然后选择保存。**

## 步骤 4：启用重播以从问题中恢复
<a name="enable-replay-recover-from-simulated-issue"></a>

1. 在 AWS Lambda 控制台的导航面板上，选择**功能**。

1. 搜索 `serverlessrepo-fork-example` 并选择 `ReplayFunction`。

1. 展开 **Designer** 部分，选择 **SQS** 磁贴，然后在 **SQS** 部分中，选择 **Enabled (启用)**。
**注意**  
启用 Amazon SQS 事件源触发器大约需要 1 分钟。

1. 选择**保存**。

1. 要查看已恢复的属性，请返回到 Amazon DynamoDB 控制台。

1. 要禁用重播，请返回 AWS Lambda 控制台并禁用 Amazon SQS 事件源触发器。`ReplayFunction`

# 将 AWS 事件分叉管道订阅到 Amazon SNS 主题
<a name="sns-subscribe-event-fork-pipelines"></a>

为了加快事件驱动型应用程序的开发，您可以订阅 Amazon SNS 主题的事件处理管道（由事件 AWS 分叉管道提供支持）。 AWS Event Fork Pipelines 是一套基于[AWS 无服务器应用程序模型](https://aws.amazon.com/serverless/sam/) (SA AWS M) 的开源[嵌套](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-template-nested-applications.html)应用程序，您可以直接从 Ev [AWS ent Fork Pipelines 套件](https://serverlessrepo.aws.amazon.com/applications?query=aws-event-fork-pipelines)（选择**显示创建自定义 IAM 角色或资源策略的应用程序**）将其部署到您的 AWS 账户中。有关更多信息，请参阅 [AWS 事件分叉管道的工作原理](sns-fork-pipeline-as-subscriber.md#how-sns-fork-works)。

本节介绍如何使用部署管道，然后 AWS 管理控制台 将 AWS 事件分叉管道订阅 Amazon SNS 主题。在开始之前，请[创建 Amazon SNS 主题](sns-create-topic.md)。

要删除构成管道的资源，请在 AWS Lambda 控制台的**应用程序**页面上找到管道，展开 **SAM 模板部分**，选择**CloudFormation堆栈**，然后选择**其他操作**，**删除堆栈**。

# 订阅事件存储与备份管道并将其部署到 Amazon SNS
<a name="deploy-event-storage-backup-pipeline"></a>


|  | 
| --- |
| 对于事件归档和分析，Amazon SNS 现在建议使用其与 Amazon Data Firehose 的本机集成。您可以将 Firehose 传输流订阅 SNS 主题，这样您就可以向存档和分析终端节点发送通知，例如亚马逊简单存储服务 (Amazon S3) 存储桶、亚马逊 Redshift 表、亚马逊 OpenSearch 服务（服务）等。OpenSearch 将 Amazon SNS 与 Firehose 传输流配合使用是一种完全托管且无需代码的解决方案，您无需使用任何功能。 AWS Lambda 有关更多信息，请参阅 [扇出到 Firehose 传输流](sns-firehose-as-subscriber.md)。 | 

本教程说明如何部署[事件存储与备份管道](sns-fork-pipeline-as-subscriber.md#sns-fork-event-storage-and-backup-pipeline)并为该管道订阅 Amazon SNS 主题。此过程会自动将与管道关联的 AWS SAM 模板转换为 CloudFormation 堆栈，然后将该堆栈部署到您的 AWS 账户。此过程还会创建和配置构成事件存储与备份管道的资源集，包括以下内容：
+ Amazon SQS 队列
+ Lambda 函数
+ Firehose 传输流
+ Amazon S3 备份存储桶

有关将流配置为以 Amazon S3 存储桶作为目标的更多信息，请参阅 *Amazon Data Firehose API Reference* 中的 `[S3DestinationConfiguration](https://docs.aws.amazon.com/firehose/latest/APIReference/API_S3DestinationConfiguration.html)`。

有关转换事件以及配置事件缓冲、事件压缩和事件加密的详细信息，请参阅 *Amazon Data Firehose 开发人员指南*中的[创建传输流](https://docs.aws.amazon.com/firehose/latest/dev/basic-create.html)。

有关筛选事件的更多信息，请参阅本指南中的 [Amazon SNS 订阅筛选策略](sns-subscription-filter-policies.md)。

1. 登录 [AWS Lambda 控制台](https://console.aws.amazon.com/lambda/)。

1. 在导航面板上，选择 **Functions (函数)**，然后选择 **Create function (创建函数)**。

1. 在 **Create function (创建函数)** 页面上，执行以下操作：

   1. 依次选择 **Browse serverless app repository（浏览无服务器应用程序存储库）**、**Public applications（公共应用程序）**、**Show apps that create custom roles or resource policies（显示创建 IAM 角色或资源策略的应用程序）**。

   1. 搜索 `fork-event-storage-backup-pipeline`，然后选择该应用程序。

1. 在 **fork-event-storage-backup-pipelin** e 页面上，执行以下操作：

   1. 在 **Application settings (应用程序设置)** 部分中，输入 **Application name (应用程序名称)**（例如，`my-app-backup`）。
**注意**  
对于每个部署，应用程序名称必须唯一。如果您重复使用应用程序名称，则部署将仅更新先前部署的 CloudFormation 堆栈（而不是创建新的堆栈）。

   1. （可选）对于 **BucketArn**，请输入加载传入事件的 Amazon S3 存储桶的 ARN。如果您未输入值，则会在您的 AWS 账户中创建一个新的 Amazon S3 存储桶。

   1. （可选）对于 **DataTransformationFunctionArn**，输入用于转换传入事件的 Lambda 函数的 ARN。如果您不输入值，则将禁用数据转换。

   1. （可选）输入以下**LogLevel**设置之一以执行应用程序的 Lambda 函数：
      + `DEBUG`
      + `ERROR`
      + `INFO`（默认值）
      + `WARNING`

   1. 对于 **TopicArn**，输入要订阅此分叉管道实例的 Amazon SNS 主题的 ARN。

   1. （可选）对于**StreamBufferingIntervalInSeconds**和 **StreamBufferingSizeInMBs**，输入用于配置传入事件缓冲的值。如果您不输入任何值，则使用 300 秒和 5 MB。

   1. （可选）输入以下**StreamCompressionFormat**设置之一以压缩传入的事件：
      + `GZIP`
      + `SNAPPY`
      + `UNCOMPRESSED`（默认值）
      + `ZIP`

   1. （可选）对于 **StreamPrefix**，输入字符串前缀以命名存储在 Amazon S3 备份存储桶中的文件。如果您不输入值，则不使用任何前缀。

   1. （可选）对于 **SubscriptionFilterPolicy**，输入 JSON 格式的 Amazon SNS 订阅筛选策略，用于筛选传入的事件。筛选策略决定在 OpenSearch 服务索引中对哪些事件进行索引。如果您不输入值，则不使用筛选（为所有事件编制索引）。

   1. （可选）对于 **SubscriptionFilterPolicyScope**，输入字符串`MessageBody`或`MessageAttributes`以启用基于负载或基于属性的邮件筛选。

   1. 选择 **I acknowledge that this app creates custom IAM roles, resource policies and deploys nested applications (我确认此应用程序创建自定义 IAM 角色和资源策略并部署嵌套应用程序)**，然后选择 **Deploy (部署)**。

在 “**部署状态 *my-app***” 页面上，Lambda 会显示 “**您的应用程序正在部署中**” 状态。

在**资源**部分中， CloudFormation 开始创建堆栈并显示每个资源的 **CREATE\$1IN\$1PROGRESS** 状态。该过程完成后， CloudFormation 将显示 “**创建\$1完成**” 状态。

部署完成后，Lambda 将显示 **Your application has been deployed（您的应用程序已部署完成）**状态。

发布到您的 Amazon SNS 主题的消息将存储在由事件存储与备份管道自动预置的 Amazon S3 备份存储桶中。

# 订阅事件搜索与分析管道并将其部署到 Amazon SNS
<a name="deploy-event-search-analytics-pipeline"></a>


|  | 
| --- |
| 对于事件归档和分析，Amazon SNS 现在建议使用其与 Amazon Data Firehose 的本机集成。您可以将 Firehose 传输流订阅 SNS 主题，这样您就可以向存档和分析终端节点发送通知，例如亚马逊简单存储服务 (Amazon S3) 存储桶、亚马逊 Redshift 表、亚马逊 OpenSearch 服务（服务）等。OpenSearch 将 Amazon SNS 与 Firehose 传输流配合使用是一种完全托管且无需代码的解决方案，您无需使用任何功能。 AWS Lambda 有关更多信息，请参阅 [扇出到 Firehose 传输流](sns-firehose-as-subscriber.md)。 | 

本教程说明如何部署[事件搜索与分析管道](sns-fork-pipeline-as-subscriber.md#sns-fork-event-search-and-analytics-pipeline)并为该管道订阅 Amazon SNS 主题。此过程会自动将与管道关联的 AWS SAM 模板转换为 CloudFormation 堆栈，然后将该堆栈部署到您的 AWS 账户。此过程还会创建和配置构成事件搜索与分析管道的资源集，包括以下内容：
+ Amazon SQS 队列
+ Lambda 函数
+ Firehose 传输流
+ 亚马逊 OpenSearch 服务域名
+ Amazon S3 死信存储桶

有关将流配置为以索引作为目标的更多信息，请参阅《Amazon Data Firehose API Reference》**中的 `[ElasticsearchDestinationConfiguration](https://docs.aws.amazon.com/firehose/latest/APIReference/API_ElasticsearchDestinationConfiguration.html)`。

有关转换事件以及配置事件缓冲、事件压缩和事件加密的详细信息，请参阅 *Amazon Data Firehose 开发人员指南*中的[创建传输流](https://docs.aws.amazon.com/firehose/latest/dev/basic-create.html)。

有关筛选事件的更多信息，请参阅本指南中的 [Amazon SNS 订阅筛选策略](sns-subscription-filter-policies.md)。

1. 登录 [AWS Lambda 控制台](https://console.aws.amazon.com/lambda/)。

1. 在导航面板上，选择 **Functions (函数)**，然后选择 **Create function (创建函数)**。

1. 在 **Create function (创建函数)** 页面上，执行以下操作：

   1. 依次选择 **Browse serverless app repository（浏览无服务器应用程序存储库）**、**Public applications（公共应用程序）**、**Show apps that create custom roles or resource policies（显示创建 IAM 角色或资源策略的应用程序）**。

   1. 搜索 `fork-event-search-analytics-pipeline`，然后选择该应用程序。

1. 在 **fork-event-search-analytics-pipelin** e 页面上，执行以下操作：

   1. 在 **Application settings (应用程序设置)** 部分中，输入 **Application name (应用程序名称)**（例如，`my-app-search`）。
**注意**  
对于每个部署，应用程序名称必须唯一。如果您重复使用应用程序名称，则部署将仅更新先前部署的 CloudFormation 堆栈（而不是创建新的堆栈）。

   1. （可选）对于 **DataTransformationFunctionArn**，输入用于转换传入事件的 Lambda 函数的 ARN。如果您不输入值，则将禁用数据转换。

   1. （可选）输入以下**LogLevel**设置之一以执行应用程序的 Lambda 函数：
      + `DEBUG`
      + `ERROR`
      + `INFO`（默认值）
      + `WARNING`

   1. （可选）对于 **SearchDomainArn**，输入 OpenSearch 服务域的 ARN，该域是一个配置所需计算和存储功能的集群。如果您不输入值，则使用默认配置创建新域。

   1. 对于 **TopicArn**，输入要订阅此分叉管道实例的 Amazon SNS 主题的 ARN。

   1. 对于 **SearchIndexName**，输入用于事件搜索和分析的 OpenSearch 服务索引的名称。
**注意**  
以下配额适用于索引名称：  
不能包含大写字母
不能包含以下字符：`\ / * ? " < > | ` , #`
不能以下列字符开头：`- + _`
不能为以下内容：`. ..`
长度不能超过 80 个字符
长度不能超过 255 个字节
不能包含冒号（来自 OpenSearch 服务 7.0）

   1. （可选）为 OpenSearch 服务索引的轮换周期输入以下**SearchIndexRotationPeriod**设置之一：
      + `NoRotation`（默认值）
      + `OneDay`
      + `OneHour`
      + `OneMonth`
      + `OneWeek`

      索引轮换将时间戳附加到索引名称，从而促进旧数据的到期。

   1. 对于 **SearchTypeName**，输入用于在索引中组织事件的 OpenSearch 服务类型的名称。
**注意**  
OpenSearch 服务类型名称可以包含任何字符（空字节除外），但不能以开头`_`。
对于 S OpenSearch ervice 6.x，每个索引只能有一个类型。如果您为具有其他类型的现有索引指定新类型，Firehose 会返回运行时错误。

   1. （可选）对于**StreamBufferingIntervalInSeconds**和 **StreamBufferingSizeInMBs**，输入用于配置传入事件缓冲的值。如果您不输入任何值，则使用 300 秒和 5 MB。

   1. （可选）输入以下**StreamCompressionFormat**设置之一以压缩传入的事件：
      + `GZIP`
      + `SNAPPY`
      + `UNCOMPRESSED`（默认值）
      + `ZIP`

   1. （可选）对于 **StreamPrefix**，输入字符串前缀以命名存储在 Amazon S3 死信存储桶中的文件。如果您不输入值，则不使用任何前缀。

   1. （可选）对于 **StreamRetryDurationInSecons**，输入 Firehose 无法索引服务索引中的 OpenSearch 事件时的重试持续时间。如果您不输入值，则使用 300 秒。

   1. （可选）对于 **SubscriptionFilterPolicy**，输入 JSON 格式的 Amazon SNS 订阅筛选策略，用于筛选传入的事件。筛选策略决定在 OpenSearch 服务索引中对哪些事件进行索引。如果您不输入值，则不使用筛选（为所有事件编制索引）。

   1. 选择 **I acknowledge that this app creates custom IAM roles, resource policies and deploys nested applications (我确认此应用程序创建自定义 IAM 角色和资源策略并部署嵌套应用程序)**，然后选择 **Deploy (部署)**。

在 “**部署状态 *my-app-search***” 页面上，Lambda 会显示 “**您的应用程序正在部署中**” 状态。

在**资源**部分中， CloudFormation 开始创建堆栈并显示每个资源的 **CREATE\$1IN\$1PROGRESS** 状态。该过程完成后， CloudFormation 将显示 “**创建\$1完成**” 状态。

部署完成后，Lambda 将显示 **Your application has been deployed（您的应用程序已部署完成）**状态。

发布到您的 Amazon SNS 主题的消息将在事件搜索和分析管 OpenSearch 道自动配置的服务索引中编制索引。如果该管道无法为事件编制索引，它会将其存储在 S3 死信存储桶中。

# 使用 Amazon SNS 集成，部署事件重播管道
<a name="deploy-event-replay-pipeline"></a>

本教程说明如何部署[事件重播管道](sns-fork-pipeline-as-subscriber.md#sns-fork-event-replay-pipeline)并为该管道订阅 Amazon SNS 主题。此过程会自动将与管道关联的 AWS SAM 模板转换为 CloudFormation 堆栈，然后将该堆栈部署到您的 AWS 账户。此过程还会创建和配置构成事件重播管道的资源集，包括一个 Amazon SQS 队列和一个 Lambda 函数。

有关筛选事件的更多信息，请参阅本指南中的 [Amazon SNS 订阅筛选策略](sns-subscription-filter-policies.md)。

1. 登录 [AWS Lambda 控制台](https://console.aws.amazon.com/lambda/)。

1. 在导航面板上，选择 **Functions (函数)**，然后选择 **Create function (创建函数)**。

1. 在 **Create function (创建函数)** 页面上，执行以下操作：

   1. 依次选择 **Browse serverless app repository（浏览无服务器应用程序存储库）**、**Public applications（公共应用程序）**、**Show apps that create custom roles or resource policies（显示创建 IAM 角色或资源策略的应用程序）**。

   1. 搜索 `fork-event-replay-pipeline`，然后选择该应用程序。

1. 在 **fork-event-replay-pipeline** 页面中，执行以下操作：

   1. 在 **Application settings (应用程序设置)** 部分中，输入 **Application name (应用程序名称)**（例如，`my-app-replay`）。
**注意**  
对于每个部署，应用程序名称必须唯一。如果您重复使用应用程序名称，则部署将仅更新先前部署的 CloudFormation 堆栈（而不是创建新的堆栈）。

   1. （可选）输入以下**LogLevel**设置之一以执行应用程序的 Lambda 函数：
      + `DEBUG`
      + `ERROR`
      + `INFO`（默认值）
      + `WARNING`

   1. （可选 **ReplayQueueRetentionPeriodInSeconds**）输入 Amazon SQS 重播队列保留消息的时间长度（以秒为单位）。如果您不输入值，则使用 1209600 秒（14 天）。

   1. 对于 **TopicArn**，输入要订阅此分叉管道实例的 Amazon SNS 主题的 ARN。

   1. 对于 **DestinationQueueName**，输入 Lambda 重播函数向其转发消息的 Amazon SQS 队列的名称。

   1. （可选）对于 **SubscriptionFilterPolicy**，输入 JSON 格式的 Amazon SNS 订阅筛选策略，用于筛选传入的事件。筛选策略决定缓冲哪些事件以进行重播。如果您不输入值，则不使用筛选（缓冲所有事件以进行重播）。

   1. 选择 **I acknowledge that this app creates custom IAM roles, resource policies and deploys nested applications (我确认此应用程序创建自定义 IAM 角色和资源策略并部署嵌套应用程序)**，然后选择 **Deploy (部署)**。

在 “**部署状态 *my-app-replay***” 页面上，Lambda 会显示 “**您的应用程序正在部署中**” 状态。

在**资源**部分中， CloudFormation 开始创建堆栈并显示每个资源的 **CREATE\$1IN\$1PROGRESS** 状态。该过程完成后， CloudFormation 将显示 “**创建\$1完成**” 状态。

部署完成后，Lambda 将显示 **Your application has been deployed (您的应用程序已部署完成)**状态。

将在由事件重播管道自动预置的 Amazon SQS 索引中缓冲发布到您的 Amazon SNS 主题的消息以进行重播。

**注意**  
默认情况下，禁用重播。要启用重播，请导航到 Lambda 控制台上的函数页面，展开 **Designer** 部分，选择 **SQS** 磁贴，然后在 **SQS** 部分中，选择 **Enabled（启用）**。

# 将 Amazon S EventBridge cheduler 与亚马逊 SNS 配合使用
<a name="using-eventbridge-scheduler"></a>

[Amazon Sched EventBridge uler](https://docs.aws.amazon.com/scheduler/latest/UserGuide/what-is-scheduler.html) 是一种无服务器计划程序，允许您通过一个中央托管服务创建、运行和管理任务。使用 EventBridge Scheduler，您可以使用 Cron 和费率表达式为重复模式创建计划，也可以配置一次性调用。您可以设置灵活的交付时间窗口、定义重试限制，并为失败的 API 调用设置最大保留时间。

本页介绍如何使用 EventBridge 计划程序按计划发布来自 Amazon SNS 主题的消息。



## 设置执行角色
<a name="using-eventbridge-scheduler-execution-role"></a>

 创建新计划时， EventBridge 调度程序必须有权代表您调用其目标 API 操作。您可以使用*执行角色*向 EventBridge 调度器授予这些权限。您附加到计划执行角色的权限策略定义了所需权限。这些权限取决于您希望 EventBridge 调度程序调用的目标 API。

 当您使用 EventBridge 调度器控制台创建计划时，如以下过程所示， EventBridge 调度器会根据您选择的目标自动设置执行角色。如果要使用 EventBridge 调度器 SDKs、或中的一个来创建计划 AWS CLI CloudFormation，则必须有一个现有的执行角色来授予 EventBridge 调度器调用目标所需的权限。有关为计划手动设置执行角色的更多信息，请参阅《日程*EventBridge 安排器用户*[指南》中的设置执行角色](https://docs.aws.amazon.com/scheduler/latest/UserGuide/setting-up.html#setting-up-execution-role)。

## 创建计划
<a name="using-eventbridge-scheduler-create"></a>

**使用控制台创建计划**

1. 在[https://console.aws.amazon.com/scheduler/家](https://console.aws.amazon.com/scheduler/home/)中打开 Amazon EventBridge 日程安排器控制台。

1.  在**计划**页面，选择**创建计划**。

1.  在**指定计划详细信息**页面，在**计划名称和描述**部分中，执行以下操作：

   1. 对于**计划名称**，输入计划的名称。例如 **MyTestSchedule**。

   1. （可选）对于**描述**，输入对计划的描述。例如 **My first schedule**。

   1. 对于**计划组**，从下拉列表中选择一个计划组。如果您没有计划组，选择**默认**。要创建计划组，选择**创建自己的计划**。

      您可以使用计划组将标签添加到计划组。

1. 

   1. 选择计划选项。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/sns/latest/dg/using-eventbridge-scheduler.html)

1. （可选）如果您在上一步中选择**定期计划**，在**时间范围**部分，请执行以下操作：

   1. 对于**时区**，请选择时区。

   1. 对于**开始日期和时间**，请输入 `YYYY/MM/DD` 格式的有效日期，然后指定 24 小时 `hh:mm` 格式的时间戳。

   1. 对于**结束日期和时间**，请输入 `YYYY/MM/DD` 格式的有效日期，然后指定 24 小时 `hh:mm` 格式的时间戳。

1. 选择**下一步**。

1. 在**选择目标**页面上，选择 EventBridge 调度器调用 AWS 的 API 操作：

   1. 选择 **Amazon SNS 发布**。

   1. 在**发布**部分中，选择 SNS 主题或选择**创建新的 SNS 主题**。

   1. （可选）输入 JSON 负载。如果您未输入有效负载，则 EventBridge 调度器会使用空事件来调用该函数。

1. 选择**下一步**。

1. 在**设置**页面上，执行以下操作：

   1. 要打开计划，在**计划状态**下，切换**启用计划**。

   1. 要为计划配置重试策略，在**重试策略和死信队列（DLQ）**下，请执行以下操作：
      + 切换**重试**。
      + 对于**事件的最大**持续时间，请输入 EventBridge 调度器必须保留未处理事件的最大**小时**数和**最小**值。
      + 最长时间为 24 小时。
      + 在 “**最大重试**次数” 中，输入目标返回错误时 EventBridge 调度器重试计划的最大次数。

         最大值为 185 次重试。

      使用重试策略，如果调 EventBridge 度未能调用其目标，则调度程序会重新运行该计划。如果已配置，则必须为计划设置最长保留时间和最大重试次数。

   1. 选择 EventBridge 日程安排器存储未传送事件的位置。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/sns/latest/dg/using-eventbridge-scheduler.html)

   1. 要使用客户托管密钥加密目标输入，在**加密**下，选择**自定义加密设置（高级）**。

      如果选择此选项，请输入现有的 KMS 密钥 ARN 或选择**创建一个  AWS KMS key** 以导航到  AWS KMS  控制台。有关 EventBridge 计划程序如何加密静态数据的更多信息，请参阅 A *mazon EventBridge 计划程序用户*[指南中的静态加密](https://docs.aws.amazon.com/scheduler/latest/UserGuide/encryption-rest.html)。

   1. 要让 EventBridge Scheduler 为您创建新的执行角色，请选择**为此计划创建新角色**。然后，在**角色名称**中输入名称。如果您选择此选项，S EventBridge cheduler 会将模板化目标所需的权限附加到该角色。

1. 选择**下一步**。

1.  在**查看并创建计划**页面上，查看计划的详细信息。在每个部分中，选择**编辑**返回到该步骤并编辑其详细信息。

1. 选择**创建计划**。

   您可以在**计划**页面上查看新的和现有的计划列表。在**状态**列下，验证新计划是否**已启用**。

## 相关资源
<a name="using-eventbridge-scheduler-related-resources"></a>

 有关 EventBridge 调度程序的更多信息，请参阅以下内容：
+ [EventBridge 日程安排器用户指南](https://docs.aws.amazon.com/scheduler/latest/UserGuide/what-is-scheduler.html)
+ [EventBridge 调度器 API 参考](https://docs.aws.amazon.com/scheduler/latest/APIReference/Welcome.html)
+ [EventBridge 调度程序定价](https://aws.amazon.com/eventbridge/pricing/#Scheduler)