1. Polly實現(xiàn)失敗重試
1.1 Polly組件包
- Polly
- Polly.Extensions.Http
- Microsoft.Extensions.Http.Polly
1.2 Polly的能力
- 失敗重試
- 服務熔斷 ? 部分服務不可用時,可以快速響應熔斷,避免持續(xù)請求不可用服務而導致整個應用程序宕掉
- 超時處理 ? 請求響應超過設置的時間,可按照預定的操作進行處理
- 艙壁隔離 ? 為服務定義最大流量和隊列,避免服務應請求量過大而被壓崩
- 緩存策略 ? 類似AOP為應用嵌入緩存機制,當緩存命中時可以快速響應緩存
- 失敗降級 ? 當服務不可用時可以響應一個更友好的結果而非報錯
- 組合策略 ? 將上面的策略組合在一起
1.3 Polly使用步驟
- 定義要處理的異常類型或返回值
- 定義要處理動作(重試、熔斷、降級響應等)
- 使用定義的策略來執(zhí)行代碼
1.4 適合失敗重試的場景
- 服務“失敗”是暫時的,可自愈的
- 服務是冪等的,重復調用不會有副作用
場景舉例
- 網(wǎng)絡閃斷
- 部分服務節(jié)點異常
1.5 最佳實踐
- 設置失敗重試次數(shù)
- 設置帶有步長策略的失敗等待間隔 ? 防止持續(xù)不斷的重試,出現(xiàn)類似DDOS的情況
- 設置降級響應 ? 重試達到上限時,需要為服務設置降級響應
- 設置斷路器
public void ConfigureServices(IServiceCollection services)
{
// HttpClientFactory Polly內(nèi)置的重試策略
services.AddGrpcClient<OrderGrpc.OrderGrpcClient>(options =>
{
options.Address = new Uri("https://localhost:5001");
})
.ConfigurePrimaryHttpMessageHandler(provider =>
{
var handler = new SocketsHttpHandler();
handler.SslOptions.RemoteCertificateValidationCallback = (a, b, c, d) => true; //允許無效、或自簽名證書
return handler;
}).AddTransientHttpErrorPolicy(p => p.WaitAndRetryForeverAsync(i => TimeSpan.FromSeconds(i * 3)));// 設置響應500或408時重試,不指定次數(shù)直到成功
// 定義個性化策略
var reg = services.AddPolicyRegistry();
reg.Add("retryforever", Policy.HandleResult<HttpResponseMessage>(message =>
{
return message.StatusCode == System.Net.HttpStatusCode.Created;
}).RetryForeverAsync());
// 應用策略
services.AddHttpClient("orderclient").AddPolicyHandlerFromRegistry("retryforever");
services.AddHttpClient("orderclientv2").AddPolicyHandlerFromRegistry((registry, message) =>
{
return message.Method == HttpMethod.Get ? registry.Get<IAsyncPolicy<HttpResponseMessage>>("retryforever") : Policy.NoOpAsync<HttpResponseMessage>();
});
}
2.Polly實現(xiàn)熔斷限流避免雪崩效應
2.1 策略類型
- 被動策略(異常處理,結果處理)
- 主動策略(超時處理,斷路器,艙壁隔離,緩存)
被動策略:當服務響應出現(xiàn)一些異?;蚪Y果時進行處理
主動策略:根據(jù)策略實例去判斷是否超時或異常等情況,這是由策略進行主動觸發(fā)的一些操作
2.2 組合策略
- 降級響應
- 失敗重試
- 斷路器
- 艙壁隔離
限流、熔斷策略都是有狀態(tài)的,這指的是在策略中設置的并發(fā)數(shù),隊列數(shù),還有熔斷的采樣時間和吞吐量,錯誤數(shù)這些計數(shù)器的狀態(tài),這些是由一個策略的實例去承載。在對不同服務進行不同的策略定義,單獨計算它的熔斷限流數(shù)值時,就需要單獨定義不同的策略的實例,去完成不同服務之間的定義的隔離文章來源:http://www.zghlxwxcb.cn/news/detail-675985.html
// startup
public void ConfigureServices(IServiceCollection services)
{
// 熔斷策略
services.AddHttpClient("orderclientv3").AddPolicyHandler(Policy<HttpResponseMessage>.Handle<HttpRequestException>().CircuitBreakerAsync(
handledEventsAllowedBeforeBreaking: 10,// 報錯10次后熔斷服務
durationOfBreak: TimeSpan.FromSeconds(10), // 熔斷時間
onBreak: (r, t) => { }, // 發(fā)生熔斷后觸發(fā)事件
onReset: () => { }, // 熔斷恢復后觸發(fā)事件
onHalfOpen: () => { }// 當熔斷恢復之前進行驗證服務是否可用的請求
));
}
//更高級設置
services.AddHttpClient("orderclientv3").AddPolicyHandler(Policy<HttpResponseMessage>.Handle<HttpRequestException>().AdvancedCircuitBreakerAsync(
// 請求失敗比例占80%時熔斷
failureThreshold: 0.8,
// 計算請求失敗比例的時間范圍,當前為10秒內(nèi)80%請求失敗
samplingDuration: TimeSpan.FromSeconds(10),
// 最小吞吐量,在達到100個請求的時候再去計算上去失敗比例,用于請求量小的時候不進行熔斷
minimumThroughput: 100,
durationOfBreak: TimeSpan.FromSeconds(20),// 熔斷時長
onBreak: (r, t) => { }, // 發(fā)生熔斷后觸發(fā)事件
onReset: () => { },// 熔斷恢復后觸發(fā)事件
onHalfOpen: () => { }));// 當熔斷恢復之前進行驗證服務是否可用的請求
// 服務降級
var message = new HttpResponseMessage()
{
Content = new StringContent("{}")
};
var fallback = Policy<HttpResponseMessage>.Handle<BrokenCircuitException>().FallbackAsync(message);
// 重試機制,重試3次,每次等1秒鐘
var retry = Policy<HttpResponseMessage>.Handle<Exception>().WaitAndRetryAsync(3, i => TimeSpan.FromSeconds(1));
// 組合策略
//執(zhí)行順序breakPolicy -> retry -> fallback
var fallbackBreak = Policy.WrapAsync(fallback, retry, breakPolicy);
services.AddHttpClient("httpv3").AddPolicyHandler(fallbackBreak);
// 限流
var bulk = Policy.BulkheadAsync<HttpResponseMessage>(
// 最大請求數(shù)
maxParallelization: 30,
// 最大隊列數(shù),指的是達到最大請求數(shù)后又多少個請求可以被放到隊列中;
// 若不設置這個值,達到最大請求數(shù)后程序會拋出異常,如果隊列數(shù)超出最大隊列數(shù),也會拋出異常
maxQueuingActions: 20,
// 請求被限流時執(zhí)行的處理方式
onBulkheadRejectedAsync: contxt => Task.CompletedTask
);
// 限流出現(xiàn)異常時,響應降級
var message2 = new HttpResponseMessage()
{
Content = new StringContent("{}")
};
var fallback2 = Policy<HttpResponseMessage>.Handle<BulkheadRejectedException>().FallbackAsync(message);
// 組合策略
var fallbackbulk = Policy.WrapAsync(fallback2, bulk);
services.AddHttpClient("httpv4").AddPolicyHandler(fallbackbulk);
當服務發(fā)生熔斷時,策略會拋出CircuitBreakerException異常,也就是熔斷異常文章來源地址http://www.zghlxwxcb.cn/news/detail-675985.html
到了這里,關于【微服務】04-Polly實現(xiàn)失敗重試和限流熔斷的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!