为什么亚马逊多次发送SNS确认请求
Why Amazon sends confirmation request for SNS several times
从 CLI 或 AWS 控制台为 http 端点创建新的 SNS 订阅后,我收到来自 Amazon 的确认订阅请求。我的代码执行确认,然后我从 Amazon 得到回复,订阅已通过 SubscriptionArn 成功确认。同样在 AWS 控制台中,我看到订阅已确认。
但几秒钟后我又收到了来自亚马逊的确认请求。脚本尝试处理它,但 Amazon 发送错误消息 "Subscription already confirmed"
。并重复多次。
为什么亚马逊确认后还要发送确认请求?是否可以检查订阅是否已经确认而不执行confirmSubscription
?
P.S.: 我使用NodeJS SDK确认订阅。
谢谢
If Amazon SNS doesn't receive a successful response from your endpoint, it attempts to deliver the message again. This applies to all messages, including the subscription confirmation message.
从概念上讲,正在发生的事情似乎一定是这样的:SNS 的一部分(需要您确认订阅的部分)本质上询问了 SNS 的另一部分(将 HTTP 消息传送到 HTTP 的部分)端点)将消息传递到您的端点。在这种情况下,它是确认消息。
与任何其他消息一样,系统不会询问原始发件人是否应重试失败的消息——SNS 只会重试。这似乎是明智的,即使原始发件人恰好是 SNS 的不同内部部分,这仍然适用,如订阅确认的情况。
没有使用告诉 SNS 您收到消息的 HTTP 响应代码进行响应会导致 SNS 在几秒钟后重试...所以即使与此同时,您已经确认了您的订阅,SNS 的那部分已经负责向您发送消息的任务并不知道这一点——从它的角度来看,它只知道您显然没有收到一条消息,这意味着重试。
正在重试的消息每次重试时都会有相同的 x-amz-sns-message-id:
请求 header。这使您能够区分重试消息和看似与先前消息相同但实际上是具有相同负载的不同消息。
从上面链接的同一页面,在指定时间内任何介于 200 和 499 之间的响应代码都被视为成功交付。
Make sure that your endpoint responds to the HTTP POST
message from Amazon SNS with the appropriate status code. The connection will time out in 15 seconds. If your endpoint does not respond before the connection times out or if your endpoint returns a status code outside the range of 200–4xx, Amazon SNS will consider the delivery of the message as a failed attempt.
在 "success" 的概念中包含 4xx 状态代码似乎违反直觉,直到您考虑 "delivery" 的含义的概念——这意味着您的端点确实 收到 消息。 4xx 响应表明您的端点没有以某种方式 喜欢 消息,但消息确实已送达。这与 5xx 错误形成对比,从一般意义上讲,这意味着您的端点无法——至少目前——无法处理消息。
此行为还表明了另一个设计考虑:作为针对 "lost" 确认尝试的故障保护,如果您的应用程序尝试联系 SNS 端点以完成确认失败,您的应用程序应该 return 一个 5xx返回 SNS 的错误,以便 SNS 将重试并且该过程随后可能会成功。
从 CLI 或 AWS 控制台为 http 端点创建新的 SNS 订阅后,我收到来自 Amazon 的确认订阅请求。我的代码执行确认,然后我从 Amazon 得到回复,订阅已通过 SubscriptionArn 成功确认。同样在 AWS 控制台中,我看到订阅已确认。
但几秒钟后我又收到了来自亚马逊的确认请求。脚本尝试处理它,但 Amazon 发送错误消息 "Subscription already confirmed"
。并重复多次。
为什么亚马逊确认后还要发送确认请求?是否可以检查订阅是否已经确认而不执行confirmSubscription
?
P.S.: 我使用NodeJS SDK确认订阅。
谢谢
If Amazon SNS doesn't receive a successful response from your endpoint, it attempts to deliver the message again. This applies to all messages, including the subscription confirmation message.
从概念上讲,正在发生的事情似乎一定是这样的:SNS 的一部分(需要您确认订阅的部分)本质上询问了 SNS 的另一部分(将 HTTP 消息传送到 HTTP 的部分)端点)将消息传递到您的端点。在这种情况下,它是确认消息。
与任何其他消息一样,系统不会询问原始发件人是否应重试失败的消息——SNS 只会重试。这似乎是明智的,即使原始发件人恰好是 SNS 的不同内部部分,这仍然适用,如订阅确认的情况。
没有使用告诉 SNS 您收到消息的 HTTP 响应代码进行响应会导致 SNS 在几秒钟后重试...所以即使与此同时,您已经确认了您的订阅,SNS 的那部分已经负责向您发送消息的任务并不知道这一点——从它的角度来看,它只知道您显然没有收到一条消息,这意味着重试。
正在重试的消息每次重试时都会有相同的 x-amz-sns-message-id:
请求 header。这使您能够区分重试消息和看似与先前消息相同但实际上是具有相同负载的不同消息。
从上面链接的同一页面,在指定时间内任何介于 200 和 499 之间的响应代码都被视为成功交付。
Make sure that your endpoint responds to the HTTP
POST
message from Amazon SNS with the appropriate status code. The connection will time out in 15 seconds. If your endpoint does not respond before the connection times out or if your endpoint returns a status code outside the range of 200–4xx, Amazon SNS will consider the delivery of the message as a failed attempt.
在 "success" 的概念中包含 4xx 状态代码似乎违反直觉,直到您考虑 "delivery" 的含义的概念——这意味着您的端点确实 收到 消息。 4xx 响应表明您的端点没有以某种方式 喜欢 消息,但消息确实已送达。这与 5xx 错误形成对比,从一般意义上讲,这意味着您的端点无法——至少目前——无法处理消息。
此行为还表明了另一个设计考虑:作为针对 "lost" 确认尝试的故障保护,如果您的应用程序尝试联系 SNS 端点以完成确认失败,您的应用程序应该 return 一个 5xx返回 SNS 的错误,以便 SNS 将重试并且该过程随后可能会成功。