Polly.Net嵌套使用Retry与Circuit Breaker策略出现意外重试问题咨询
问题原因
- 你当前采用「重试策略包裹熔断策略」的嵌套顺序,half-open状态下的健康校验请求返回500时,熔断会触发
onBreak回到Open状态,但熔断策略仍会将500响应结果原样返回给外层的重试策略。 - 你的重试策略配置了对500、503状态码的响应触发重试,此时重试策略捕获到500响应后会直接触发重试,不会主动感知熔断已经切换为Open状态。
- 你原来写的
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
相关产品推荐
相关产品推荐

