0

0

c# 如何在c#中实现断路器(Circuit Breaker)模式

煙雲

煙雲

发布时间:2026-01-04 08:12:08

|

857人浏览过

|

来源于php中文网

原创

直接用 polly 而非手写断路器,因其线程安全、状态严谨、已深度集成生态;手写易致并发探测异常或内存泄漏,polly 支持 httpclient 原生集成及自定义策略组合与状态监听。

c# 如何在c#中实现断路器(circuit breaker)模式

为什么直接用 Polly 而不是手写断路器

手写一个线程安全、状态切换严谨、支持超时/重试/降级的断路器非常容易出错。比如 CircuitState.HalfOpen并发请求可能触发多次探测,或计时器未正确清理导致内存泄漏。生产环境建议直接用成熟库——Polly 是 .NET 生态事实标准,已深度适配 IHttpClientFactoryMicrosoft.Extensions.DependencyInjection

安装与基础用法:Polly + AddCircuitBreaker

从 .NET 6 开始,Microsoft.Extensions.Http.Resilience 提供了原生集成(基于 Polly),推荐优先使用:

dotnet add package Microsoft.Extensions.Http.Resilience

Program.cs 中注册:

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpClient<MyApiClient>()
    .AddCircuitBreaker(policy => policy
        .HandledStatusCodes(500, 502, 503, 504)
        .FailureThreshold(0.3) // 连续失败率阈值
        .SamplingDuration(TimeSpan.FromSeconds(30))
        .MinimumThroughput(10) // 每 30 秒至少 10 次调用才触发统计
        .BreakDuration(TimeSpan.FromMinutes(1))); // 熔断时长

关键点:

  • FailureThreshold 不是固定次数,而是失败率;低流量下即使只失败 1 次也可能不触发熔断(因未达 MinimumThroughput
  • BreakDuration 是“硬暂停”,期间所有请求直接抛 BrokenCircuitException,不会转发
  • 该配置仅对 HttpClient 生效;若需保护普通方法(如数据库访问),仍需手动包装 Policy

保护非 HTTP 方法:用 Policy.WrapAsync 组合策略

比如封装一个可能抛异常的仓储方法:

LogoAi
LogoAi

利用AI来设计你喜欢的Logo和品牌标志

下载
private readonly AsyncCircuitBreakerPolicy _circuitBreaker = Policy
    .Handle<SqlException>(ex => ex.Number is 1205 or 1222) // 死锁/超时
    .Or<TimeoutException>()
    .CircuitBreakerAsync(
        exceptionsAllowedBeforeBreaking: 3,
        durationOfBreak: TimeSpan.FromMinutes(2));

调用时必须显式包裹:

try
{
    await _circuitBreaker.ExecuteAsync(async () => await _repository.FetchDataAsync());
}
catch (BrokenCircuitException)
{
    // 返回缓存或默认值
    return _cache.GetOrAdd("fallback", _ => new List<Item>());
}

注意:

  • 不要把 ExecuteAsync 写在循环里——每次调用都计入熔断统计,高频调用会快速触发熔断
  • exceptionsAllowedBeforeBreaking 是绝对次数,和时间窗口无关;适合低频、高价值操作(如支付确认)
  • 若需同时加重试,用 Policy.WrapAsync(retryPolicy, circuitBreaker),顺序很重要:外层是熔断器,内层是重试

自定义状态监听与诊断:别只靠日志

熔断器状态变化(如 Open → HalfOpen)是关键信号,但默认不输出。启用监听:

var breaker = Policy
    .Handle<Exception>()
    .CircuitBreakerAsync(3, TimeSpan.FromMinutes(1),
        onBreak: (ex, ts) => {
            Console.WriteLine($"Circuit broken for {ts.TotalMinutes} min due to {ex.GetType().Name}");
        },
        onReset: () => Console.WriteLine("Circuit reset"),
        onHalfOpen: () => Console.WriteLine("Circuit half-open: allowing one probe")); 

生产环境应将这些回调对接到指标系统(如 Prometheus 的 counter),而不是仅打印日志。特别注意 onHalfOpen——它只在第一个试探请求前触发,不代表试探成功。

真正难的是状态同步:分布式场景下,单机熔断器无法共享状态。这时得上 Redis 或专用服务(如 Resilience4j 的集中式断路器),Polly 默认不解决这个问题。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
什么是分布式
什么是分布式

分布式是一种计算和数据处理的方式,将计算任务或数据分散到多个计算机或节点中进行处理。本专题为大家提供分布式相关的文章、下载、课程内容,供大家免费下载体验。

404

2023.08.11

分布式和微服务的区别
分布式和微服务的区别

分布式和微服务的区别在定义和概念、设计思想、粒度和复杂性、服务边界和自治性、技术栈和部署方式等。本专题为大家提供分布式和微服务相关的文章、下载、课程内容,供大家免费下载体验。

250

2023.10.07

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

763

2023.08.10

常用的数据库软件
常用的数据库软件

常用的数据库软件有MySQL、Oracle、SQL Server、PostgreSQL、MongoDB、Redis、Cassandra、Hadoop、Spark和Amazon DynamoDB。更多关于数据库软件的内容详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1003

2023.11.02

内存数据库有哪些
内存数据库有哪些

内存数据库有Redis、Memcached、Apache Ignite、VoltDB、TimesTen、H2 Database、Aerospike、Oracle TimesTen In-Memory Database、SAP HANA和ache Cassandra。更多关于内存数据库相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

669

2023.11.14

mongodb和redis哪个读取速度快
mongodb和redis哪个读取速度快

redis 的读取速度比 mongodb 更快。原因包括:1. redis 使用简单的键值存储,而 mongodb 存储 json 格式的数据,需要解析和反序列化。2. redis 使用哈希表快速查找数据,而 mongodb 使用 b-tree 索引。因此,redis 在需要高性能读取操作的应用程序中是一个更好的选择。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

501

2024.04.02

redis怎么做缓存服务器
redis怎么做缓存服务器

redis 作为缓存服务器的答案:redis 是一款开源、高性能、分布式的键值存储,可作为缓存服务器使用。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

413

2024.04.07

redis怎么解决数据一致性
redis怎么解决数据一致性

redis 提供了两种一致性模型,以维护副本数据一致性:强一致性 (sync) 确保写操作仅在复制到所有从节点后才完成;最终一致性 (async) 则在主节点上写操作后认为已完成,牺牲一致性换取性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

407

2024.04.07

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

23

2026.03.06

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
进程与SOCKET
进程与SOCKET

共6课时 | 0.4万人学习

Redis+MySQL数据库面试教程
Redis+MySQL数据库面试教程

共72课时 | 7.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号