

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

# Amazon SNS 消息传输重试
<a name="sns-message-delivery-retries"></a>

Amazon SNS 为每个传输协议定义了一个*传输策略*。传输策略定义了在发生服务器端错误时（当承载已订阅终端节点的系统变得不可用时），Amazon SNS 如何重试消息传输。当传输策略用尽时，Amazon SNS 将停止重试传输并丢弃邮件——除非已将死信队列附加到订阅。有关更多信息，请参阅 [Amazon SNS 死信队列](sns-dead-letter-queues.md)。

## 传输协议和策略
<a name="delivery-policies-for-protocols"></a>

**注意**  
HTTP/S, you can't change Amazon SNS-defined delivery policies. Only HTTP/S支持自定义策略除外。请参阅[创建配 HTTP/S 送策略](#creating-delivery-policy)。
Amazon SNS 将抖动应用于传输重试。有关更多信息，请参阅发布在 *AWS 架构博客*上的[指数回退和抖动](https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/)博客文章。
** HTTP/S 终端节点的总策略重试时间不能超过 3,600 秒。这是一项硬性限制，无法增加**。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/sns/latest/dg/sns-message-delivery-retries.html)

¹ 对于 Firehose 协议的节流错误，Amazon SNS 使用与客户托管端点相同的传输策略。

## 传输策略阶段
<a name="delivery-policy-stages"></a>

下图显示了传输策略的各个阶段。

![\[一个 x y 轴图，将时间显示为 x 值，将首次传输尝试显示为 y 值。在 y 轴上，传输策略从即刻重试阶段开始，在 x 轴上依次为回退前阶段、回退阶段和回退后阶段。\]](http://docs.aws.amazon.com/zh_cn/sns/latest/dg/images/sns-delivery-policy-phases.png)


每个传输策略包含四个阶段。

1. **立即重试阶段（无延迟）**– 此阶段在首次传输尝试结束后立即发生。在该阶段中重试之间没有延迟。

1. **前退避阶段** – 此阶段紧随即刻重试阶段。Amazon SNS 使用此阶段进行一系列重试，然后再应用退避函数。此阶段指定重试次数以及它们之间的延迟时间量。

1. **退避阶段**：此阶段通过使用重试-退避函数控制各个重试之间的延迟。此阶段设置了最短延迟时间、最长延迟时间和重试-退避函数，该函数定义了延迟时间从最小值增加到最大值的速度。退避函数可以是算术、指数、几何或线性的。

1. **后退避阶段** – 此阶段在退避阶段之后发生。此阶段指定重试次数以及它们之间的延迟时间量。它是最后一个阶段。

## 创建配 HTTP/S 送策略
<a name="creating-delivery-policy"></a>

**您可以使用分为四个阶段的传输策略定义 Amazon SNS 如何重试向 HTTP/S 终端节点传送消息：*无延迟*、*预退退、退避和后退退*。**此策略可让您覆盖原定的重试设置，并根据您的 HTTP 服务器容量进行自定义。

您可以在**主题**或**订阅**级别将您的 HTTP/S 交付策略定义为 JSON 对象：
+ **主题级政策**-适用于链接到该主题的所有 HTTP/S 订阅。使用 [https://docs.aws.amazon.com/sns/latest/api/API_CreateTopic.html](https://docs.aws.amazon.com/sns/latest/api/API_CreateTopic.html) 或 [https://docs.aws.amazon.com/sns/latest/api/API_SetTopicAttributes.html](https://docs.aws.amazon.com/sns/latest/api/API_SetTopicAttributes.html) API 操作设置此策略。
+ **订阅级策略**：仅适用于特定的订阅。使用 [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_SetSubscriptionAttributes.html](https://docs.aws.amazon.com/sns/latest/api/API_SetSubscriptionAttributes.html) API 操作设置此策略。

或者，您也可以在 CloudFormation 模板中使用该[AWS::SNS::Subscription](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sns-subscription.html)资源。

您应该根据 HTTP/S 服务器的容量自定义您的传输策略：
+ **所有订阅都使用一台服务器**-如果主题中的所有 HTTP/S 订阅都使用同一台服务器，请将传送策略设置为主题属性，以确保所有订阅之间的一致性。
+ **不同订阅使用不同服务器**：如果订阅针对不同的服务器，则为每个订阅创建独立的传输策略并根据特定服务器的容量进行定制。

您还可以在请求策略中设置 `Content-Type` 标头，以指定通知的媒体类型。默认情况下，Amazon SNS 会将所有通知发送到内容类型设置为的 HTTP/S 终端节点。`text/plain; charset=UTF-8`但是，您可以使用请求策略中的 [`headerContentType`](#header-content-type) 字段来覆盖此原定设置值。

以下 JSON 对象定义了一个包含四阶段重试的传输策略：

1. **无延迟阶段** – 立即重试 3 次。

1. **前退避阶段**：以 1 秒的间隔重试 2 次。

1. **退避阶段**：以指数延迟方式重试 10 次，延迟时间从 1 秒到 60 秒不等。

1. **后退避阶段**：以固定 60 秒间隔重试 35 次。

在丢弃消息之前，Amazon SNS 总共**尝试传输消息 50 次**。为了保留在所有重试后仍无法传输的消息，可将您的订阅配置为将无法传输的消息移动到死信队列（DLQ）。有关更多信息，请参阅 [Amazon SNS 死信队列](sns-dead-letter-queues.md)。

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

**注意**  
此传输策略使用 `maxReceivesPerSecond` 属性将每个订阅的传输流量限流至平均每秒 10 条消息。虽然这种机制有助于防止您的 HTTP/S 端点被高流量所淹没，但它旨在保持平均交付率，并且没有严格的上限。偶尔可能会出现超过指定限制的传输流量峰值，尤其是您的发布速率明显高于节流值时。  
当发布（入站）流量超过传输（出站）速率时，可能导致消息积压和传输延迟增加。为避免此类问题，请确保该`maxReceivesPerSecond`值与 HTTP/S 服务器的容量和工作负载要求一致。

以下传输策略示例将 HTTP/S 通知的默认内容类型覆盖为 `application/json`。

```
{
    "healthyRetryPolicy": {
        "minDelayTarget": 1,
        "maxDelayTarget": 60,
        "numRetries": 50,
        "numNoDelayRetries": 3,
        "numMinDelayRetries": 2,
        "numMaxDelayRetries": 35,
        "backoffFunction": "exponential"
    },
    "throttlePolicy": {
        "maxReceivesPerSecond": 10
    },
    "requestPolicy": {
        "headerContentType": "application/json"
    }
}
```

传输策略包含**重试策略**、**节流策略**和**请求策略**。传输策略中共有 **9 个**属性。


| 策略  | 说明 | 限制 | 
| --- | --- | --- | 
| minDelayTarget | 重试的最短延迟时间。**单位：**秒 | 1 至最长延迟时间**原定设置值：**20 | 
| maxDelayTarget | 重试的最长延迟时间。**单位：**秒 | 最短延迟时间至 3600**原定设置值：**20 | 
| numRetries | 重试总数，包括立即重试、前退避重试、退避重试和后退避重试。 | 0 至 100**原定设置值：**3 | 
| numNoDelayRetries | 要立即完成的重试次数，各个重试之间无延迟。 | 0 或更多**原定设置值：**0 | 
| numMinDelayRetries | 前退避阶段的重试次数，各个重试之间有指定的最短延迟时间。 | 0 或更多**原定设置值：**0 | 
| numMaxDelayRetries | 后退避阶段的重试次数，各个重试之间有最长延迟时间。 | 0 或更多**原定设置值：**0 | 
| backoffFunction | 各个重试之间退避的模型。 |  四个选项之一： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/sns/latest/dg/sns-message-delivery-retries.html) **默认：**线性  | 
| maxReceivesPerSecond  | 每个订阅每秒的消息传输最大平均数量。 | 1 或更多**默认：**无节流（对传输速率无限制） | 
| headerContentType  | 发送到 HTTP/S 端点的通知的内容类型。 |  如果未定义请求策略，则内容类型原定设置为 `text/plain; charset=UTF-8`。 当为订阅禁用原始消息传送时（原定设置），或者在主题级别定义传送策略时，支持的标头内容类型为 `application/json` 和 `text/plain`。 为订阅启用原始消息传送时，支持以下内容类型： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/sns/latest/dg/sns-message-delivery-retries.html)  | 

Amazon SNS 使用以下公式计算退避阶段的重试次数：

```
numRetries - numNoDelayRetries - numMinDelayRetries - numMaxDelayRetries
```

您可以使用三个参数来控制退避阶段的重试频率。
+ **`minDelayTarget`** – 设置退避阶段第一次重试的延迟时间。
+ **`maxDelayTarget`** – 设置退避阶段最后一次重试的延迟时间。
+ **`backoffFunction`** – 决定 Amazon SNS 用于计算第一次和最后一次重试之间所有重试延迟的算法。您可以从四个重试退避函数中进行选择。

下图说明了在退避阶段，不同的重试退避函数如何影响各次重试之间的延迟。本示例中使用的传输策略包括以下设置：**总共 10 次重试**，**最小延迟为 5 秒**，**最大延迟为 260 秒**。
+ **纵轴**显示每次重试的延迟（以秒为单位）。
+ **横轴**表示重试序列，从第 1 次重试到第 10 次重试。

![\[该图显示了基于四个退避函数（指数、算术、线性和几何）在 10 次重试中的延迟变化情况。每条彩色曲线代表一种函数的延迟模式：指数：延迟增长最快，最早达到最大延迟。线性：每次重试延迟稳步增加。算术和几何：延迟增加速度适中，比线性陡峭，但比指数增长慢。所有曲线都从接近最小延迟 5 秒的位置开始，到第 10 次重试时接近最大延迟 260 秒。\]](http://docs.aws.amazon.com/zh_cn/sns/latest/dg/images/backoff-graph.png)
