详解指数退避算法

18 篇文章 0 订阅

详解指数退避算法 exponential backoff algorithm

Exponential backoff🌟🌟🌟

指数退避(Exponential backoff)在网络请求中的应用🌟🌟🌟🌟🌟

概念

指数退避算法是通过反馈,成倍的降低某个进程的速率,以逐渐找到合适速率的算法。它是一种闭环控制系统,用来降低受控进程对不良事件的回应速度。在无线电网络和计算机网络中应用广泛。

建模函数为:

t = b c t=b^c t=bc, 由此可见随着请求失败的次数的增加,两次请求之间的间隔也在指数式增加,其中

t: 两个 action 之间的延迟时间

b: 基数, 通常我们使用二进制指数退避算法时,它就是 2

c: 发生不良事件的次数,比如请求失败的次数

注:

  • 通常如果不良事件发生频率降低,t 会逐渐的恢复,但为了避免震荡恢复速度肯定要比速率降低速度慢
  • t 并不是准确的延迟时间,很多情况下它是延迟时间的上限

应用

处理 rate limit 限流

发生限流后可以使用指数退避策略重新发起请求:

通常:遇到限流报错时,传统的重试策略是每隔一段时间重试一次。但由于是固定的时间重试一次,重试时又会有大量的请求在同一时刻涌入,会不断地造成限流。但使用 exponential backoff 之后能完美避免这种情况:

c 次碰撞后(比如请求失败),会选择 0 和 2 c − 1 2^c-1 2c1 之间的随机值作为时隙的数量。

  • 对于第 1 次碰撞来说,每个发送者将会等待 0 或 1 个时隙进行发送。
  • 而在第 2 次碰撞后,发送者将会等待 0 到 3( 由 2 2 − 1 2^2-1 221 计算得到)个时隙进行发送。
  • 而在第 3 次碰撞后,发送者将会等待 0 到 7( 由 2 3 − 1 2^3-1 231 计算得到)个时隙进行发送。
  • 以此类推……

随着重传次数的增加,延迟的程度也会指数增长。

重试策略

像建立网络连接、请求公共服务

import (
	"time"

	"github.com/cenkalti/backoff/v4"
)
type BackoffOption func() backoff.BackOff

// 指定最长重试时间
func MaxSecondsLimit(seconds int) BackoffOption {
	return func() backoff.BackOff {
		back := backoff.NewExponentialBackOff()
		back.MaxElapsedTime = time.Duration(seconds) * time.Second
    // 设置间隔是 1s default: 60s
		back.InitialInterval = 1 * time.Second
		return back
	}
}
// 重试方法
func ExponentialBackoffRetry(f backoff.Operation, options ...BackoffOption) error {
  // 设置最长等待 60s,default: 15 min
	var cfg backoff.BackOff = MaxSecondsLimit(60)()
	for _, opt := range options {
		if opt != nil {
			cfg = opt()
		}
	}
	return backoff.Retry(f, cfg)
}

func NoRetry() BackoffOption {
	return func() backoff.BackOff {
		back := &backoff.StopBackOff{}
		return back
	}
}

// 使用方式一:使用指数退避重试
err := ExponentialBackoffRetry(func() error{
  resp, err := request('xx')
  return err
})
// 使用方式二:不使用重试
err := ExponentialBackoffRetry(func() error{
  resp, err := request('xx')
  return err
}NoRetry())

python 版本

import backoff
class MyException(Exception):
	def __init__(self, message, status):
		super().__init__(message, status)
		self.message = message
idx = 0
# 最长重试时间是 20s
@backoff.on_exception(
        backoff.expo, MyException, max_time=20)
def test_backoff(**params):
  print("=====>", idx)
  idx += 1
  raise MyException("test")

其他

像 celery(分布式异步消息任务队列) 中 celery/utils/time.py 使用指数退避算法避免多个任务同时执行

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Pure Pursuit算法是一种常用的路径跟踪算法,用于在自动驾驶车辆中实现目标点的跟踪。该算法基于车辆的动力学模型和控制原理来实现对目标点的追踪。 Pure Pursuit算法的基本思路是:根据车辆的位置和姿态信息,计算出距离车辆当前位置最近的目标点,然后根据车辆的动力学模型和控制原理,计算出车辆应该采取的转向角度和速度,以使车辆能够向目标点靠近,并最终到达目标点。 Pure Pursuit算法的具体实现步骤如下: 1.确定车辆的位置和姿态信息,包括车辆当前的坐标、朝向角和速度等参数。 2.确定目标点的位置信息,一般情况下目标点是提前根据路径规划算法计算出来的,或者是根据路标或者GPS等信息确定的。 3.计算出距离车辆当前位置最近的目标点,这可以通过计算车辆当前位置与路径上所有点之间的距离,然后选择距离最近的点来实现。 4.根据车辆的动力学模型和控制原理,计算出车辆应该采取的转向角度和速度。在Pure Pursuit算法中,转向角度是根据车辆当前位置和目标点之间的夹角来计算的,速度则可以根据车辆当前位置与目标点之间的距离来调整。 5.将计算出的转向角度和速度输入到车辆的控制系统中,实现对车辆的控制。 需要注意的是,Pure Pursuit算法在实际应用中还需要考虑一些限制条件,如车辆的最大加速度、最大速度、最小转弯半径等,以保证车辆的安全和稳定性。此外,由于车辆在实际行驶过程中会受到诸多干扰,如路面的摩擦力、风阻等因素,因此需要不断地对算法进行优化和改进,以提高算法的稳定性和鲁棒性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值