工业上位机中企业微信推送(或其他网络调用,如 Modbus/OPC UA 读写、数据库写入、API 调用等)添加 Polly 重试机制的完整、实用实现方案
以下是针对工业上位机中企业微信推送或其他网络调用如 Modbus/OPC UA 读写、数据库写入、API 调用等添加Polly 重试机制的完整、实用实现方案。Polly 是 .NET 生态中最成熟、功能最强大的弹性与瞬时故障处理库在工业场景中特别适合处理网络抖动、PLC 短暂掉线、数据库连接超时、企业微信服务器偶发限流等情况。1. 安装 PollyNuGetPackageReferenceIncludePollyVersion8.*/!-- 核心库 --PackageReferenceIncludePolly.Extensions.HttpVersion8.*/!-- 如果使用 HttpClient --PackageReferenceIncludeMicrosoft.Extensions.Http.PollyVersion8.*/!-- DI 集成推荐 --2. Polly 重试策略推荐工业场景分类场景推荐策略组合最大重试次数等待时间策略触发条件StatusCode / 异常说明企业微信 Webhook 推送Retry WaitAndRetry Jitter3–5 次指数退避 JitterHttpRequestException、429、500–599避免触发频率限制Modbus TCP / OPC UA 读写Retry CircuitBreaker Timeout3 次线性/指数退避TimeoutException、SocketException、IOException典型网络/设备瞬时故障数据库批量写入Retry WaitAndRetry Bulkhead2–4 次固定 1–3s 或指数DbUpdateException、SqlException超时/死锁防止雪崩高可用关键指令下发Retry CircuitBreaker Fallback3 次指数退避所有异常 自定义业务失败码失败后执行备用方案如本地记录3. 推荐实现方式对比方式优点缺点推荐程度工业直接在方法中使用 Policy.ExecuteAsync最灵活、代码显式重复代码多★★★☆☆使用 HttpClientFactory Polly 扩展DI 友好、配置集中、全局统一只适用于 HttpClient 调用★★★★★自定义 PolicyWrap 扩展方法兼顾灵活与复用需维护扩展方法★★★★☆工业推荐HttpClientFactory Polly 扩展最符合 .NET 现代实践配置统一、易测试。4. 企业微信推送 Polly 重试完整示例方式一使用 HttpClientFactory Polly推荐Program.cs服务注册builder.Services.AddHttpClient(WeComWebhook,client{client.TimeoutTimeSpan.FromSeconds(10);}).AddPolicyHandler(GetWeComRetryPolicy()).AddPolicyHandler(GetCircuitBreakerPolicy());// 可选熔断Polly 策略定义可放在单独的 PolicyFactory 类中usingPolly;usingPolly.Extensions.Http;usingPolly.Contrib.WaitAndRetry;usingSystem.Net;privatestaticIAsyncPolicyHttpResponseMessageGetWeComRetryPolicy(){// 指数退避 Jitter抖动防止雪崩vardelayBackoff.DecorrelatedJitterBackoffV2(medianFirstRetryDelay:TimeSpan.FromMilliseconds(500),retryCount:4);// 总共尝试 5 次1 4returnHttpPolicyExtensions.HandleTransientHttpError()// 5xx 408 网络异常.OrResult(msgmsg.StatusCodeHttpStatusCode.TooManyRequests)// 429 限流.OrResult(msg!msg.IsSuccessStatusCode)// 其他非 2xx.WaitAndRetryAsync(delay,onRetry:(outcome,timespan,retryAttempt,context){Log.Warning(企业微信推送失败第 {Attempt} 次重试等待 {Delay}s - {Reason},retryAttempt,timespan.TotalSeconds,outcome.Exception?.Message??outcome.Result?.StatusCode.ToString());});}privatestaticIAsyncPolicyHttpResponseMessageGetCircuitBreakerPolicy(){returnHttpPolicyExtensions.HandleTransientHttpError().CircuitBreakerAsync(handledEventsAllowedBeforeBreaking:5,// 连续 5 次失败熔断durationOfBreak:TimeSpan.FromSeconds(30),// 熔断 30sonBreak:(outcome,breakDuration){Log.Error(企业微信推送熔断持续 {Break}s - {Reason},breakDuration.TotalSeconds,outcome.Exception?.Message??outcome.Result?.StatusCode.ToString());},onReset:()Log.Information(企业微信推送熔断恢复));}WeComWebhookNotifier 更新版使用注入的 HttpClientFactorypublicclassWeComWebhookNotifier{privatereadonlyIHttpClientFactory_httpClientFactory;privatereadonlystring_webhookUrl;publicWeComWebhookNotifier(IHttpClientFactoryhttpClientFactory,IConfigurationconfig){_httpClientFactoryhttpClientFactory;_webhookUrlconfig[WeCom:WebhookUrl]??thrownewInvalidOperationException(缺少 WebhookUrl 配置);}publicasyncTaskboolSendTextAsync(stringcontent,string[]?mentionedListnull){varclient_httpClientFactory.CreateClient(WeComWebhook);varpayloadnew{msgtypetext,textnew{content,mentioned_listmentionedList??Array.Emptystring()}};varjsonJsonSerializer.Serialize(payload);varcontentBodynewStringContent(json,Encoding.UTF8,application/json);try{varresponseawaitclient.PostAsync(_webhookUrl,contentBody);response.EnsureSuccessStatusCode();// Polly 已处理失败重试varresultawaitresponse.Content.ReadFromJsonAsyncWeComResponse();returnresult?.Errcode0;}catch(Exceptionex){Log.Error(ex,企业微信推送最终失败);returnfalse;}}}publicclassWeComResponse{publicintErrcode{get;set;}publicstringErrmsg{get;set;}string.Empty;}5. 其他场景的 Polly 扩展示例快速参考Modbus TCP 读取 重试varretryPolicyPolicy.HandleIOException().OrTimeoutException().OrModbusException().WaitAndRetryAsync(3,retryAttemptTimeSpan.FromSeconds(Math.Pow(2,retryAttempt)));varresultawaitretryPolicy.ExecuteAsync(async(){returnawait_modbus.ReadHoldingRegistersAsync(1,100,20);});数据库批量写入 熔断 回退varpolicyWrapPolicy.WrapAsync(Policy.HandleDbUpdateException().CircuitBreakerAsync(3,TimeSpan.FromSeconds(30)),Policy.HandleException().WaitAndRetryAsync(2,_TimeSpan.FromSeconds(2)),Policy.HandleException().FallbackAsync(async(){/* 本地 SQLite 缓存 */}));awaitpolicyWrap.ExecuteAsync(()_dbContext.BulkInsertAsync(points));6. 生产建议与注意事项日志记录每次重试方便事后分析网络/服务器问题熔断后告警熔断触发时额外推送到管理员配置化重试次数、等待时间、熔断阈值写入 appsettings.json测试用 Polly Chaos 工程注入故障延迟、抛异常验证策略效果指标监控用 App.Metrics / Prometheus 暴露重试次数、熔断状态如果需要更复杂的组合策略重试 熔断 限流 降级、Polly 在 BackgroundService 中的全局包装、与企业微信卡片消息结合的完整推送流程或者Polly Cache 降级方案直接告诉我我继续给出针对性代码。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2434604.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!