You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Polly.Net嵌套使用Retry与Circuit Breaker策略出现意外重试问题咨询

问题原因

  1. 你当前采用「重试策略包裹熔断策略」的嵌套顺序,half-open状态下的健康校验请求返回500时,熔断会触发onBreak回到Open状态,但熔断策略仍会将500响应结果原样返回给外层的重试策略。
  2. 你的重试策略配置了对500、503状态码的响应触发重试,此时重试策略捕获到500响应后会直接触发重试,不会主动感知熔断已经切换为Open状态。
  3. 你原来写的BrokenCircuitException处理逻辑完全无效,谓词返回值写反,且即使写对也无法处理「响应结果触发重试」的场景。

解决方案

方案1:调整重试的结果判断逻辑(改动最小,推荐)

在重试的状态码判断条件中,增加熔断状态校验,只有当熔断处于非Open状态时,才对500/503的响应触发重试。
同时可以直接删除冗余的BrokenCircuitException处理代码:重试策略默认不会处理未注册的异常,遇到BrokenCircuitException会直接向外抛出,不会触发重试,刚好符合你的需求。

修正后的重试策略代码如下:

customRetryPolicy = Policy<HttpResponseMessage>   
    // 仅当熔断未开启且返回指定状态码时触发重试
    .OrResult(x => { 
        return httpStatusesToProcess.Contains(x.StatusCode) 
            && customCircuitBreakerPolicy.CircuitState != CircuitState.Open; 
    })
    // 重试2次,每次间隔5秒
    .WaitAndRetry(2, retryAttempt => TimeSpan.FromSeconds(5),
        (exception, timeSpan, retryCount, context) =>
        {
            System.Console.WriteLine("Retrying... " + retryCount);
        }
    );

方案2:调整异常处理逻辑(更规范)

你可以将熔断触发条件的500响应转换为自定义异常抛出,熔断策略处理异常触发熔断,同时重试策略配置为不对该自定义异常触发重试,从根源上避免half-open场景下的重试触发。


额外优化建议

建议使用异步的ExecuteAsync方法替代「同步Execute+.Result」的写法,避免异常被AggregateException包装,减少异常处理的复杂度。

内容的提问来源于stack exchange,提问作者diegobarriosdev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 22:45:03