FreeRTOS 退避算法
backoffAlgorithm 核心算法详解
目录
算法概述
什么是退避算法(Backoff Algorithm)?
退避算法是一种用于处理失败重试的策略,通过逐渐增加重试之间的等待时间,避免在系统繁忙或网络拥塞时造成"雷群效应"(Thundering Herd Problem)。
Full Jitter 策略
backoffAlgorithm 库实现了 “Full Jitter” 指数退避策略,这是 AWS 推荐的一种退避算法变体。
核心思想:
- 指数增长:每次重试的等待时间上限呈指数增长(2^n)
- 随机抖动:在每次重试时,实际等待时间是在 [0, 最大等待时间] 范围内随机选择
- 避免同步:多个设备同时重试时,由于随机性,重试时间会分散,避免同时冲击服务器
算法公式
第 n 次重试的等待时间 = random(0, min(backOffBase * 2^n, maxBackoffDelay)) 其中:
backOffBase:基础退避时间(毫秒)2^n:指数增长因子maxBackoffDelay:最大退避延迟(毫秒)random(0, max):在 [0, max] 范围内随机选择
数据结构分析
BackoffAlgorithmContext_t 结构体
typedefstructBackoffAlgorithmContext{ uint16_t maxBackoffDelay;// 最大退避延迟(毫秒)uint32_t attemptsDone;// 已完成的尝试次数uint16_t nextJitterMax;// 下一次重试的最大抖动值(毫秒)uint32_t maxRetryAttempts;// 最大重试次数} BackoffAlgorithmContext_t;字段说明:
| 字段 | 类型 | 说明 |
|---|---|---|
maxBackoffDelay | uint16_t | 最大退避延迟(毫秒)。这是退避时间的上限,无论重试多少次,都不会超过这个值 |
attemptsDone | uint32_t | 已完成的尝试次数。每次调用 GetNextBackoff 时递增 |
nextJitterMax | uint16_t | 下一次重试的最大抖动值(毫秒)。这是当前重试周期中随机等待时间的上限,会指数增长 |
maxRetryAttempts | uint32_t | 最大重试次数。设置为 BACKOFF_ALGORITHM_RETRY_FOREVER (UINT32_MAX) 表示无限重试 |
关键常量:
#defineBACKOFF_ALGORITHM_RETRY_FOREVER( UINT32_MAX )核心算法逻辑
1. 初始化函数:BackoffAlgorithm_InitializeParams
函数签名:
voidBackoffAlgorithm_InitializeParams( BackoffAlgorithmContext_t * pContext,uint16_t backOffBase,uint16_t maxBackOff,uint32_t maxAttempts );参数说明:
| 参数 | 类型 | 说明 |
|---|---|---|
pContext | BackoffAlgorithmContext_t* | 要初始化的上下文结构体指针 |
backOffBase | uint16_t | 基础退避时间(毫秒)。第一次重试的等待时间上限 |
maxBackOff | uint16_t | 最大退避延迟(毫秒)。所有重试的等待时间上限 |
maxAttempts | uint32_t | 最大重试次数。设置为 BACKOFF_ALGORITHM_RETRY_FOREVER 表示无限重试 |
实现代码:
voidBackoffAlgorithm_InitializeParams( BackoffAlgorithmContext_t * pContext,uint16_t backOffBase,uint16_t maxBackOff,uint32_t maxAttempts ){ assert( pContext !=NULL);/* 初始化上下文,设置计算下一次退避值所需的参数 */ pContext->nextJitterMax = backOffBase;// 第一次重试的最大抖动值 = 基础值 pContext->maxBackoffDelay = maxBackOff;// 设置最大退避延迟 pContext->maxRetryAttempts = maxAttempts;// 设置最大重试次数/* 初始化时,已完成的尝试次数为 0 */ pContext->attemptsDone =0;}初始化逻辑:
- 将
nextJitterMax设置为backOffBase(第一次重试的等待时间上限) - 设置
maxBackoffDelay(所有重试的等待时间上限) - 设置
maxRetryAttempts(最大重试次数) - 将
attemptsDone初始化为 0
2. 核心算法函数:BackoffAlgorithm_GetNextBackoff
函数签名:
BackoffAlgorithmStatus_t BackoffAlgorithm_GetNextBackoff( BackoffAlgorithmContext_t * pRetryContext,uint32_t randomValue,uint16_t* pNextBackOff );参数说明:
| 参数 | 类型 | 说明 |
|---|---|---|
pRetryContext | BackoffAlgorithmContext_t* | 退避算法上下文(输入/输出) |
randomValue | uint32_t | 随机值,范围 [0, UINT32_MAX],用于计算随机等待时间 |
pNextBackOff | uint16_t* | 输出参数,返回计算出的退避时间(毫秒) |
返回值:
| 返回值 | 说明 |
|---|---|
BackoffAlgorithmSuccess | 成功计算出下一个退避值 |
BackoffAlgorithmRetriesExhausted | 所有重试次数已用完 |
实现代码:
BackoffAlgorithmStatus_t BackoffAlgorithm_GetNextBackoff( BackoffAlgorithmContext_t * pRetryContext,uint32_t randomValue,uint16_t* pNextBackOff ){ BackoffAlgorithmStatus_t status = BackoffAlgorithmSuccess;assert( pRetryContext !=NULL);assert( pNextBackOff !=NULL);/* 如果 maxRetryAttempts 设置为最大值,或者已完成次数小于最大次数,则继续重试 */if(( pRetryContext->maxRetryAttempts == BACKOFF_ALGORITHM_RETRY_FOREVER )||( pRetryContext