通知传递策略¶
https://blueprints.launchpad.net/zaqar/+spec/notification-delivery-policy
有时,由于网络/互联网连接问题或目标服务/应用程序的负载,从 Zaqar 发送到订阅者的通知可能会失败,因此如果我们可以支持重试,并且用户可以在订阅的选项中定义重试策略,那将是很好的。
此功能仅适用于 HTTP/HTTPS 订阅方式,不包括电子邮件通知。
问题描述¶
现在 Zaqar 没有通知传递策略,这意味着如果端点存在无法接收通知的问题,则不会进行重试。对于用户或应用程序来说,在没有通知的情况下会丢失重要消息。
AWS SNS 服务已经支持该策略,这对 Zaqar 来说是一个很好的参考[1]。
提议的变更¶
为了明确我们想要做什么,有一些问题需要回答
何时生效通知传递策略?
Zaqar 仅在一次失败的传递尝试后尝试重试。以下情况被视为一次失败的传递尝试
HTTP 状态码在 500-599 范围内。
HTTP 状态码不在 200-599 范围内。
请求超时。
任何连接错误,例如连接超时、端点无法访问等。
通知传递策略如何工作?
您可以使用传递策略来控制重试的总次数,以及每次重试之间的时间延迟。
总共有四个离散阶段,用户可以使用它们来设置重试策略
立即重试阶段:也称为无延迟阶段,此阶段在初始传递尝试后立即发生。用户为“无延迟重试”设置的值决定了在初始传递尝试后的立即重试次数。此阶段的重试之间没有延迟。
预回退阶段:预回退阶段紧随立即重试阶段之后。使用此阶段创建在回退函数应用到重试之前发生的一组重试。使用“最小延迟重试”设置指定预回退阶段中的重试次数。用户可以使用“最小延迟”设置来控制此阶段重试之间的时间延迟。
回退阶段:此阶段称为回退阶段,因为用户可以使用重试回退函数来控制此阶段重试之间的延迟。设置“最小延迟”和“最大延迟”,然后选择重试回退函数来定义延迟如何从最小延迟增加到最大延迟。
后回退阶段:后回退阶段紧随回退阶段之后。使用“最大延迟重试”设置指定后回退阶段中的重试次数。您可以使用“最大延迟”设置来控制此阶段重试之间的时间延迟。
用户可以在创建队列和订阅时创建和应用重试策略。因此,当 Zaqar 将通知发送到这些订阅者时,它将使用这些策略在初始传递尝试失败后进行重试。
..note
By default, if there are retry policies on both queue and subscription,
Zaqar will use the subscription's policy. If user don't want the override
he can set the ignore_subscription_override=True in _retry_policy metadata
of the queue.
这将给 Zaqar 带来哪些变化?
首先,用户可以在队列创建请求的主体中的元数据中创建重试策略。
其次,用户也可以在订阅创建请求的主体中的选项中创建重试策略。如果重试策略同时设置在队列和订阅中,Zaqar 将默认使用订阅策略而不是队列策略,但如果队列的元数据中 ignore_subscription_override 为 True,则 Zaqar 仍将使用队列中的重试策略。
第三,更改通知逻辑,当向端点发送通知时存在失败时,则使用绑定到此订阅的策略进行重试,如果订阅没有重试策略,则 Zaqar 将使用队列元数据中的策略。
由于队列中的“metadata”和订阅中的“options”都是字典,因此重试策略的数据模型应如下所示
{
'_retry_policy': {
'retries_with_no_delay': <Integer value, optional>,
'minimum_delay_retries': <Integer value, optional>,
'minimum_delay': <Interger value, optional>,
'maximum_delay': <Interger value, optional>,
'maximum_delay_retries': <Integer value, optional>,
'retry_backoff_function': <String value, optional>,
'ignore_subscription_override': <Bool value, optional>
}
}
'minimum_delay' and 'maximum_delay' mean delay time in seconds.
'retry_backoff_function' mean name of retry backoff function.
There will be a enum in Zaqar that contain all valid values. At first step,
Zaqar only supports one function: 'linear'.
If value of retry_policy is empty dict, that Zaqar will use default
value to those keys:
* retries_with_no_delay=3
* minimum_delay_retries=3
* minimum_delay=5
* maximum_delay=30
* maximum_delay_retries=3
* retry_backoff_function=linear
* ignore_subscription_override=False
Those default values will be configurable in Queens.
..note
Retry policy is only applied for webhook(http/https) subscriber.
Zaqar will support linear retry backoff function only in Pike release,
it will increase the delay time linearly within 10 times from minimum delay
to maximum delay. We will support more retry backoff functions in future.
For avoiding the users receive notification message repeatedly
if connection is reconnected during retry process, once Zaqar sends the
notification successfully when doing retry, it will stop the whole retry
process.
示例¶
为了更好地了解其工作原理,这里有一个示例案例。假设用户在队列 A 中使用重试策略的默认值,并创建一个带有 HTTP 订阅者的订阅:http://192.168.1.100:8080。当 Zaqar 将通知发送到此订阅者时,它收到一个 HTTP 代码为 500 的响应,然后重试策略将开始工作
- 阶段 1:立即重试。Zaqar 将在没有延迟的情况下调用订阅者 3
次。如果没有成功,则进入阶段 2。如果其中一次重试成功,则重试过程将结束。
- 阶段 2:预回退。根据 minimum_delay_retries 和 minimum_delay。
Zaqar 将进行总共 3 次重试,每次重试之间有 5 秒的延迟。如果没有成功,则进入阶段 3。如果其中一次重试成功,则重试过程将结束。
- 阶段 3:回退。使用线性函数,Zaqar 将增加重试之间的延迟
以回退阶段期间的恒定速率。因此,由于恒定速率为 5,Zaqar 将使用延迟时间调用订阅者 12 次:[5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60]。如果没有成功,则进入阶段 4。如果其中一次重试成功,则重试过程将结束。
- 阶段 4:后回退。根据 maximum_delay 和
maximum_delay_retries,Zaqar 将进行总共 3 次重试,每次重试之间有 60 秒的延迟。在此阶段之后,无论调用是否成功,重试过程都将结束。
缺点¶
N/A
备选方案¶
N/A
实现¶
负责人¶
- 主要负责人
wanghao (sxmatch1986@gmail.com)
里程碑¶
P-3
工作项¶
添加在创建队列和订阅时对重试策略的验证。
更改通知流程以应用策略。
此功能的 UTs。
依赖项¶
[1]: http://docs.aws.amazon.com/sns/latest/dg/DeliveryPolicies.html