指數退避: 一種常用于網絡請求重試的策略
"指數退避"(Exponential Backoff)是一種常用于網絡請求重試的策略。其核心思想是:每當操作失敗并需要重試時,不是立即重試,而是等待一段時間再重試,并且每次重試之間的等待時間呈指數級增長(通常是成倍增加)。
實現指數退避的邏輯:
await Task.Delay(delayMilliseconds * attempt);
這里,每重試一次,等待時間就會增加(第1次等待1倍,第2次2倍,第3次3倍……)。這樣做的好處是可以減輕服務器壓力,避免因頻繁重試導致網絡擁堵或服務雪崩。
常見的指數退避公式為:
等待時間 = 基礎延遲 * 2^重試次數
上面的實現是線性遞增(delayMilliseconds * attempt),如果要嚴格指數退避,可以改為:
await Task.Delay(delayMilliseconds * (int)Math.Pow(2, attempt));
總結:
指數退避就是每次重試等待的時間越來越長,常用于處理網絡異常、請求超時等場景,提高系統的健壯性和容錯能力。
C# 中實現指數退避的具體代碼示例:
using System;
using System.Net.Http;
using System.Threading.Tasks;
public static class RetryHelper
{
/// <summary>
/// 使用指數退避策略重試異步操作
/// </summary>
/// <typeparam name="T">返回類型</typeparam>
/// <param name="action">要執行的異步操作</param>
/// <param name="maxRetries">最大重試次數</param>
/// <param name="baseDelayMilliseconds">基礎延遲(毫秒)</param>
/// <returns>操作結果</returns>
public static async Task<T?> RetryWithExponentialBackoffAsync<T>(
Func<Task<T?>> action,
int maxRetries = 5,
int baseDelayMilliseconds = 500)
{
int attempt = 0;
while (true)
{
try
{
return await action();
}
catch (Exception ex) when (attempt < maxRetries)
{
attempt++;
int delay = baseDelayMilliseconds * (int)Math.Pow(2, attempt - 1);
Console.WriteLine($"第{attempt}次重試,等待{delay}ms,異常信息: {ex.Message}");
await Task.Delay(delay);
}
}
}
}
用法示例:
// 假設有一個可能拋出異常的異步方法
async Task<string?> GetDataAsync()
{
// 這里模擬網絡請求
throw new HttpRequestException("網絡錯誤");
}
// 調用帶指數退避的重試方法
var result = await RetryHelper.RetryWithExponentialBackoffAsync(GetDataAsync);
說明:
- 每次重試等待時間為 baseDelayMilliseconds * 2^(attempt-1),即 500ms, 1000ms, 2000ms, 4000ms, ...
- 只要未超過最大重試次數,遇到異常就會指數級延遲后重試。
- 你可以根據實際需求調整最大重試次數和基礎延遲時間。
如需將你現有的 RetryAsync 方法改為嚴格的指數退避,只需將 await Task.Delay(delayMilliseconds * attempt); 替換為:
await Task.Delay(delayMilliseconds * (int)Math.Pow(2, attempt - 1));
這樣即可實現標準的指數退避。
關聯項目
FreeSql QQ群:4336577
BA & Blazor QQ群:795206915
Maui Blazor 中文社區 QQ群:645660665
知識共享許可協議
本作品采用 知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議 進行許可。歡迎轉載、使用、重新發布,但務必保留文章署名AlexChow(包含鏈接: https://github.com/densen2014 ),不得用于商業目的,基于本文修改后的作品務必以相同的許可發布。如有任何疑問,請與我聯系 。
轉載聲明
本文來自博客園,作者:周創琳 AlexChow,轉載請注明原文鏈接:http://www.rzrgm.cn/densen2014/p/18927886
AlexChow
今日頭條 | 博客園 | 知乎 | Gitee | GitHub


浙公網安備 33010602011771號