支持更多退避函数

https://blueprints.launchpad.net/zaqar/+spec/support-more-backoff-functions

有时,由于网络/互联网连接问题或目标服务/应用程序的负载,从 Zaqar 发送到订阅者的通知可能会失败。这意味着如果端点存在无法接收通知的问题,则不会进行重试。对于用户或应用程序来说,在没有通知的情况下会丢失重要消息。为了解决这个问题,Zaqar 在 pike 版本中支持了通知传递策略 [1]。

问题描述

现在 Zaqar 在 Pike 版本中仅支持线性重试退避函数,它从最小延迟到最大延迟线性增加延迟时间。现在我们将支持 Zaqar 中的更多重试退避函数。

幸运的是,AWS SNS 服务已经支持该策略,这对于 Zaqar 来说是一个很好的参考 [2]。

提议的变更

为了明确我们想要做什么,有一些问题需要回答

  1. Zaqar 将支持多少种重试退避函数?

您可以从以下四种重试退避函数中选择:

  • 线性。

  • 算术。

  • 几何。

  • 指数。

  1. 这四种重试退避函数之间有什么区别?

正如我们在 [2] 的“退避阶段”章节中看到的图片,该截图显示了每个重试退避函数如何影响退避期间消息的延迟。纵轴表示与 10 次重试中的每次重试相关的秒数延迟。横轴表示重试次数。最小延迟为 5 秒,最大延迟为 260 秒。

  1. 这四种重试退避函数的公式

通常,我们假设最小延迟为 MIN,最大延迟为 MAX,总重试次数为 NUM。从以上三个元素,我们可以得出这四种重试退避函数的公式。

  • 线性。

    LINEAR_INTERVAL = ( MAX - MIN ) / NUM time1 = MIN time2 = MIN + LINEAR_INTERVAL*1 time3 = MIN + LINEAR_INTERVAL*2 timen = MIN + LINEAR_INTERVAL*(n-1) timeN = MAX

    线性重试退避函数已经在 Pike 版本中实现,我们仅在此处列出供参考和比较。

  • 几何

    我们假设几何级数的公比为 K:time1 = MIN time2 = K * MIN time3 = K^2 * MIN timen = K^(n-1) * MIN timeN = K^(NUM-1) * MIN = MAX

    所以

    K^(NUM-1) = MAX/MIN lg[ K^(NUM-1) ] = lg( MAX/MIN ) (NUM-1) * lg(K) = lg( MAX/MIN ) lg(K) = lg( MAX/MIN ) / (NUM-1) K = 10^[ lg( MAX/MIN ) / (NUM-1) ]

    最终

    timen = {10^[ lg( MAX/MIN ) / (NUM-1) ]}^(n-1) * MIN

  • 指数。

    我们假设指数级数的幂指数为 k,系数为 p

    指数级数的通用函数是:y = p * k^x

    time1 = MIN = p*k^1 timeN = MAX = p*k^NUM MAX/MIN = k^(NUM-1) lg(MAX/MIN) = (NUM-1)*lg(k) lg(k) = lg(MAX/MIN)/ (NUM-1) k = 10^[lg(MAX/MIN)/ (NUM-1)] p = MIN/{10^[lg(MAX/MIN)/ (NUM-1)]}

    最终

    timen = p*k^n timen = MIN/{10^[lg(MAX/MIN)/ (NUM-1)]} * {10^[lg(MAX/MIN)/ (NUM-1)]} ^n

  • 算术。

    我们假设算术级数的公差为 d

    time1 = MIN time2 = time1 + d*1 time3 = time2 + d*2 time4 = time3 + d*3

    timen = timen-1 + d*(n-1)

    timeN = timeN-1 + d*(NUM-1) = MAX

    所以:timeN - time1 = NUM*(NUM-1)/2*d

    d = 2*(MAX-MIN)/[NUM*(NUM-1)]

    timen - time1 = n*(n-1)/2 * { 2*(MAX-MIN)/[NUM*(NUM-1)] }

    最终

    timen = n*(n-1)/2 * { 2*(MAX-MIN)/[NUM*(NUM-1)] } + MIN

  1. 这将给 Zaqar 带来哪些变化?

  • 首先,我们将根据这些重试退避函数的公式定义三个函数。

  • 其次,更改通知的逻辑,当向端点发送通知时存在失败时,则使用绑定到此订阅的策略进行重试。在退避阶段,我们将根据用户的选择选择重试退避函数来重新发送通知。

缺点

N/A

备选方案

N/A

实现

负责人

主要负责人

gecong (ge.cong@zte.com.cn)

里程碑

Q-2

工作项

  • 根据这些重试退避函数的公式添加三个函数。

  • 更改通知过程的退避阶段以应用重试退避函数。

  • 此功能的 UTs。

依赖项

[1]:https://specs.openstack.org/openstack/zaqar-specs/specs/pike/notification-delivery-policy.html [2]:http://docs.aws.amazon.com/sns/latest/dg/DeliveryPolicies.html