Amazon SNS 消息传输重试
Amazon SNS 为每个传输协议定义了一个传输策略。传输策略定义了在发生服务器端错误时(当承载已订阅终端节点的系统变得不可用时),Amazon SNS 如何重试消息传输。当传输策略用尽时,Amazon SNS 将停止重试传输并丢弃邮件——除非已将死信队列附加到订阅。有关更多信息,请参阅 Amazon SNS 死信队列。
传输协议和策略
注意
-
除 HTTP/S 外,您无法更改 Amazon SNS 定义的传输策略。只有 HTTP/S 支持自定义策略。请参阅创建 HTTP/S 传输策略。
-
Amazon SNS 将抖动应用于传输重试。有关更多信息,请参阅发布在 Amazon 架构博客上的指数回退和抖动
博客文章。 -
HTTP/S 端点的策略重试总时间不能超过 3600 秒。这是一项硬性限制,无法增加。
| 端点类型 | 传输协议 | 立即重试(无延迟)阶段 | 前退避阶段 | 退避阶段 | 后退避阶段 | 总尝试次数 |
|---|---|---|---|---|---|---|
| Amazon 托管的终端节点 | ¹ | 3 次,无延迟 | 2 次,相隔 1 秒 | 10 次,带指数退避(1 秒到 20 秒) | 100000 次,相隔 20 秒 | 100015 次,超过 23 天 |
| Amazon Lambda | ||||||
| Amazon SQS | ||||||
| 客户托管的终端节点 | SMTP | 0 次,无延迟 | 2 次,相隔 10 秒 | 10 次,带指数退避(10 秒到 600 秒(10 分钟)) | 38 次,相隔 600 秒(10 分钟) | 50 次尝试,超过 6 小时 |
| 短信 | ||||||
| 移动推送 |
¹ 对于 Firehose 协议的节流错误,Amazon SNS 使用与客户托管端点相同的传输策略。
传输策略阶段
下图显示了传输策略的各个阶段。
每个传输策略包含四个阶段。
-
立即重试阶段(无延迟)– 此阶段在首次传输尝试结束后立即发生。在该阶段中重试之间没有延迟。
-
前退避阶段 – 此阶段紧随即刻重试阶段。Amazon SNS 使用此阶段进行一系列重试,然后再应用退避函数。此阶段指定重试次数以及它们之间的延迟时间量。
-
退避阶段 – 此阶段通过使用重试-退避函数控制各个重试之间的延迟。此阶段设置了最短延迟时间、最长延迟时间和重试-退避函数,该函数定义了延迟时间从最小值增加到最大值的速度。退避函数可以是算术、指数、几何或线性的。
-
后退避阶段 – 此阶段在退避阶段之后发生。此阶段指定重试次数以及它们之间的延迟时间量。它是最后一个阶段。
创建 HTTP/S 传输策略
您可以使用包含四个阶段(无延迟、前退避、退避和后退避)的传输策略来定义 Amazon SNS 向 HTTP/S 端点重试消息传输的方式。此策略可让您覆盖原定的重试设置,并根据您的 HTTP 服务器容量进行自定义。
您可以在主题或订阅级别将 HTTP/S 传输策略设置为 JSON 对象。
-
主题级策略 - 适用于链接到该主题的所有 HTTP/S 订阅。使用
CreateTopic或SetTopicAttributesAPI 操作设置此策略。 -
订阅级策略 - 仅适用于特定的订阅。使用
Subscribe或SetSubscriptionAttributesAPI 操作设置此策略。
或者,您也可以在 Amazon CloudFormation 模板中使用 AWS::SNS::Subscription 资源。
您应根据 HTTP/S 服务器的容量来自定义您的传输策略:
-
所有订阅使用单台服务器 - 如果主题中的所有 HTTP/S 订阅都使用同一台服务器,请将传输策略设置为主题属性,以确保所有订阅之间的一致性。
-
不同订阅使用不同服务器 - 如果订阅针对不同的服务器,则为每个订阅创建独立的传输策略并根据特定服务器的容量进行定制。
您还可以在请求策略中设置 Content-Type 标头,以指定通知的媒体类型。默认情况下,Amazon SNS 会将所有通知发送到 HTTP/S 端点,内容类型设置为 text/plain; charset=UTF-8。但是,您可以使用请求策略中的 headerContentType 字段来覆盖此原定设置值。
以下 JSON 对象定义了一个包含四阶段重试的传输策略:
-
无延迟阶段 – 立即重试 3 次。
-
前退避阶段 - 以 1 秒的间隔重试 2 次。
-
退避阶段 - 以指数延迟方式重试 10 次,延迟时间从 1 秒到 60 秒不等。
-
后退避阶段 - 以固定 60 秒间隔重试 35 次。
在丢弃消息之前,Amazon SNS 总共尝试传输消息 50 次。为了保留在所有重试后仍无法传输的消息,可将您的订阅配置为将无法传输的消息移动到死信队列(DLQ)。有关更多信息,请参阅 Amazon SNS 死信队列。
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 |
各个重试之间退避的模型。 |
四个选项之一:
默认:线性 |
maxReceivesPerSecond
|
每个订阅每秒的消息传输最大平均数量。 | 1 或更多 默认:无节流(对传输速率无限制) |
headerContentType
|
发送到 HTTP/S 端点的通知的内容类型。 |
如果未定义请求策略,则内容类型原定设置为 当为订阅禁用原始消息传送时(原定设置),或者在主题级别定义传送策略时,支持的标头内容类型为 为订阅启用原始消息传送时,支持以下内容类型:
|
Amazon SNS 使用以下公式计算退避阶段的重试次数:
numRetries - numNoDelayRetries - numMinDelayRetries - numMaxDelayRetries
您可以使用三个参数来控制退避阶段的重试频率。
-
minDelayTarget– 设置退避阶段第一次重试的延迟时间。 -
maxDelayTarget– 设置退避阶段最后一次重试的延迟时间。 -
backoffFunction– 决定 Amazon SNS 用于计算第一次和最后一次重试之间所有重试延迟的算法。您可以从四个重试退避函数中进行选择。
下图说明了在退避阶段,不同的重试退避函数如何影响各次重试之间的延迟。本示例中使用的传输策略包括以下设置:总共 10 次重试,最小延迟为 5 秒,最大延迟为 260 秒。
-
纵轴显示每次重试的延迟(以秒为单位)。
-
横轴表示重试序列,从第 1 次重试到第 10 次重试。