name: 韧性模式 description: 使用Polly和Brighter为.NET实现断路器、重试和死信队列模式。用于实施故障容错、处理瞬态故障、配置重试策略或设置死信队列。包括Polly HttpClient模式和Brighter消息处理程序韧性。 argument-hint: [范围] [–详细] [–目录 <路径>] allowed-tools: 读取, 写入, 全局搜索, 搜索, Bash, 技能, 任务
韧性模式技能
概述
本技能提供在.NET应用程序中实现韧性模式的指南。它涵盖使用Polly的同步韧性(HTTP客户端、服务调用)和使用Brighter的异步韧性(消息处理程序)。
关键原则: 为失败而设计。系统应优雅处理瞬态故障,防止级联失败,并提供有意义的回退行为。
何时使用此技能
关键词: 韧性、断路器、重试、polly、brighter、故障容错、瞬态故障、DLQ、死信队列、超时、隔舱、回退、http客户端韧性
在以下情况使用此技能:
- 实施HTTP客户端韧性
- 为瞬态故障配置重试策略
- 设置断路器以防止级联失败
- 设计消息处理程序错误处理
- 实施死信队列模式
- 为服务调用添加超时策略
- 配置隔舱隔离
韧性策略概述
同步韧性(Polly)
用于HTTP调用和同步服务通信:
| 模式 | 目的 | 何时使用 |
|---|---|---|
| 重试 | 重试失败的操作 | 瞬态故障(网络、503、超时) |
| 断路器 | 停止调用失败的服务 | 重复失败表明服务已关闭 |
| 超时 | 限制操作时间 | 防止无限等待 |
| 隔舱 | 隔离故障 | 防止一个调用者耗尽资源 |
| 回退 | 提供替代方案 | 优雅降级 |
异步韧性(Brighter)
用于基于消息和异步操作:
| 模式 | 目的 | 何时使用 |
|---|---|---|
| 重试 | 重新传递失败的消息 | 瞬态处理故障 |
| 死信队列 | 停放无法处理的消息 | 毒消息、业务规则失败 |
| 断路器 | 暂时停止处理 | 下游服务不可用 |
| 超时 | 限制处理程序执行 | 防止处理程序阻塞 |
快速开始:Polly v8与HttpClient
基本设置
// Program.cs或Startup.cs
builder.Services.AddHttpClient<IOrderService, OrderService>()
.AddStandardResilienceHandler();
AddStandardResilienceHandler()添加一个预配置的管道,包括:
- 速率限制器
- 总请求超时
- 重试(指数回退)
- 断路器
- 尝试超时
自定义配置
builder.Services.AddHttpClient<IOrderService, OrderService>()
.AddResilienceHandler("自定义管道", builder =>
{
// 重试与指数回退
builder.AddRetry(new HttpRetryStrategyOptions
{
MaxRetryAttempts = 3,
Delay = TimeSpan.FromSeconds(1),
BackoffType = DelayBackoffType.Exponential,
UseJitter = true,
ShouldHandle = new PredicateBuilder<HttpResponseMessage>()
.Handle<HttpRequestException>()
.HandleResult(r => r.StatusCode == HttpStatusCode.ServiceUnavailable)
});
// 断路器
builder.AddCircuitBreaker(new HttpCircuitBreakerStrategyOptions
{
FailureRatio = 0.5,
MinimumThroughput = 10,
SamplingDuration = TimeSpan.FromSeconds(30),
BreakDuration = TimeSpan.FromSeconds(30)
});
// 每次尝试超时
builder.AddTimeout(TimeSpan.FromSeconds(10));
});
详细Polly模式: 参见references/polly-patterns.md
快速开始:Brighter消息处理程序
基本重试策略
public class OrderCreatedHandler : RequestHandler<OrderCreated>
{
[UsePolicy("重试策略", step: 1)]
public override OrderCreated Handle(OrderCreated command)
{
// 处理订单
return base.Handle(command);
}
}
策略注册表设置
var policyRegistry = new PolicyRegistry
{
{
"重试策略",
Policy
.Handle<Exception>()
.WaitAndRetry(
retryCount: 3,
sleepDurationProvider: attempt =>
TimeSpan.FromSeconds(Math.Pow(2, attempt)))
}
};
services.AddBrighter()
.UseExternalBus(/* 配置 */)
.UsePolicyRegistry(policyRegistry);
详细Brighter模式: 参见references/brighter-resilience.md
模式决策树
何时使用重试
使用重试当:
- 故障可能是瞬态的(网络闪烁、临时503)
- 操作是幂等的
- 重试之间的延迟可接受
不使用重试当:
- 故障是业务逻辑(验证错误、400 Bad Request)
- 操作不是幂等的(除非使用幂等性键)
- 需要立即响应
何时使用断路器
使用断路器当:
- 调用可能关闭的外部服务
- 需要快速失败而不是等待
- 想要防止级联失败
- 服务恢复需要时间
配置指南: 参见references/circuit-breaker-config.md
何时使用DLQ
使用DLQ当:
- 消息在最大重试后无法处理
- 业务规则阻止处理
- 需要手动干预
- 故障需要审计跟踪
DLQ模式: 参见references/dlq-patterns.md
重试策略模式
立即重试
对于非常瞬态的故障:
.AddRetry(new RetryStrategyOptions
{
MaxRetryAttempts = 2,
Delay = TimeSpan.Zero // 立即重试
});
指数回退
对于需要时间的瞬态故障:
.AddRetry(new RetryStrategyOptions
{
MaxRetryAttempts = 4,
Delay = TimeSpan.FromSeconds(1),
BackoffType = DelayBackoffType.Exponential,
UseJitter = true // 防止惊群效应
});
延迟: 1s → 2s → 4s → 8s(带抖动)
线性回退
对于速率限制服务:
.AddRetry(new RetryStrategyOptions
{
MaxRetryAttempts = 3,
Delay = TimeSpan.FromSeconds(2),
BackoffType = DelayBackoffType.Linear
});
延迟: 2s → 4s → 6s
完整重试策略: 参见references/retry-strategies.md
断路器配置
保守(敏感服务)
.AddCircuitBreaker(new CircuitBreakerStrategyOptions
{
FailureRatio = 0.25, // 25%失败后打开
MinimumThroughput = 5, // 至少需要5次调用评估
SamplingDuration = TimeSpan.FromSeconds(10),
BreakDuration = TimeSpan.FromSeconds(60) // 保持打开60秒
});
激进(高可用性)
.AddCircuitBreaker(new CircuitBreakerStrategyOptions
{
FailureRatio = 0.5, // 50%失败后打开
MinimumThroughput = 20, // 需要20次调用评估
SamplingDuration = TimeSpan.FromSeconds(30),
BreakDuration = TimeSpan.FromSeconds(15) // 快速恢复尝试
});
详细配置: 参见references/circuit-breaker-config.md
死信队列模式
当消息处理失败时
1. 消息接收
2. 处理程序尝试处理
3. 发生故障
4. 应用重试策略(1...N次尝试)
5. 所有重试耗尽
6. 消息移至DLQ
7. 触发警报/监控
8. 手动调查
Brighter DLQ设置
services.AddBrighter()
.UseExternalBus(config =>
{
config.Publication.RequeueDelayInMs = 500;
config.Publication.RequeueCount = 3;
// 3次重新排队后,消息进入DLQ
});
完整DLQ模式: 参见references/dlq-patterns.md
组合模式
HTTP客户端全韧性
builder.Services.AddHttpClient<IPaymentGateway, PaymentGateway>()
.AddResilienceHandler("支付网关", builder =>
{
// 顺序重要:外到内
// 1. 总超时(外部边界)
builder.AddTimeout(TimeSpan.FromSeconds(30));
// 2. 重试(内部带断路器)
builder.AddRetry(new HttpRetryStrategyOptions
{
MaxRetryAttempts = 3,
Delay = TimeSpan.FromMilliseconds(500),
BackoffType = DelayBackoffType.Exponential,
UseJitter = true
});
// 3. 断路器
builder.AddCircuitBreaker(new HttpCircuitBreakerStrategyOptions
{
FailureRatio = 0.5,
MinimumThroughput = 10,
BreakDuration = TimeSpan.FromSeconds(30)
});
// 4. 每次尝试超时(内部)
builder.AddTimeout(TimeSpan.FromSeconds(5));
});
带回退的消息处理程序
public class ProcessPaymentHandler : RequestHandler<ProcessPayment>
{
[UsePolicy("断路器", step: 1)]
[UsePolicy("重试", step: 2)]
[UsePolicy("回退", step: 3)]
public override ProcessPayment Handle(ProcessPayment command)
{
_paymentService.Process(command);
return base.Handle(command);
}
}
可观察性
Polly遥测
services.AddResiliencePipeline("我的管道", builder =>
{
builder.AddRetry(/* 选项 */)
.ConfigureTelemetry(LoggerFactory.Create(b => b.AddConsole()));
});
关键监控指标
| 指标 | 目的 | 警报阈值 |
|---|---|---|
| 重试次数 | 跟踪瞬态故障 | > 每分钟3次 |
| 断路器状态 | 跟踪服务健康 | 状态 = 打开 |
| DLQ深度 | 跟踪处理故障 | > 0 |
| 超时率 | 跟踪慢服务 | > 5% |
反模式
过度重试
问题: 重试次数太多、太快。
// 错误:10次立即重试
.AddRetry(new RetryStrategyOptions { MaxRetryAttempts = 10 });
修复: 使用指数回退,限制重试次数:
// 正确:3次重试带回退
.AddRetry(new RetryStrategyOptions
{
MaxRetryAttempts = 3,
Delay = TimeSpan.FromSeconds(1),
BackoffType = DelayBackoffType.Exponential
});
重试非瞬态故障
问题: 重试业务逻辑故障。
// 错误:重试400 Bad Request
ShouldHandle = new PredicateBuilder<HttpResponseMessage>()
.HandleResult(r => !r.IsSuccessStatusCode)
修复: 只重试瞬态故障:
// 正确:只重试瞬态HTTP代码
ShouldHandle = new PredicateBuilder<HttpResponseMessage>()
.Handle<HttpRequestException>()
.HandleResult(r => r.StatusCode is
HttpStatusCode.ServiceUnavailable or
HttpStatusCode.GatewayTimeout or
HttpStatusCode.RequestTimeout)
缺少断路器
问题: 服务关闭时无休止重试。
修复: 对外部调用始终配对重试与断路器。
DLQ作为黑洞
问题: 消息进入DLQ后从未处理。
修复:
- 监控DLQ深度
- 设置警报
- 实施重播机制
- 记录调查程序
参考文献
references/polly-patterns.md- 全面Polly v8模式references/circuit-breaker-config.md- 断路器配置指南references/retry-strategies.md- 重试策略模式references/brighter-resilience.md- Brighter消息处理程序韧性references/dlq-patterns.md- 死信队列模式
相关技能
fitness-functions- 使用性能适应函数测试韧性modular-architecture- 按模块隔离韧性关注点adr-management- 记录韧性决策
最后更新: 2025-12-22
用户界面
当用户直接调用时,此技能审计代码库中的韧性模式。
执行工作流
- 解析参数 - 提取范围(默认:当前目录)、
--详细标志和输出目录。 - 生成韧性分析器代理 - 分析HTTP客户端、消息处理程序、数据库调用和外部服务连接的韧性模式(重试、断路器、超时、DLQ)。
- 识别差距 - 比较找到的依赖项与带有韧性处理程序的依赖项。检测反模式(捕捉并吞下、缺少超时)。
- 生成审计报告 - 生成报告,包括执行摘要、关键差距(带代码位置和建议)、现有良好实践、检测到的反模式以及优先级改进计划。
- 详细输出(如果
--详细) - 包括代码片段、前后示例、配置模板和测试指南。 - 保存结果 - 保存到
docs/audits/resilience-audit-[日期].md(或自定义--目录)。
版本历史
- v1.0.0(2025-12-26):初始发布