关于 resilience-patterns
resilience-patterns 是面向 .NET 的技能,帮助设计并审查同步调用和异步消息处理的弹性策略。它结合 Polly 与 Brighter 指南,并可生成代码库审计报告。
主要功能
- 01Polly HTTP 弹性指南
- 02Brighter 消息处理指南
- 03重试、断路器、超时与回退模式
- 04死信队列指南
- 05生成含优先级建议的代码库审计
适用场景
- 01为 HTTP 客户端添加弹性策略
- 02为外部服务规划重试和断路器
- 03通过重试和死信队列处理失败消息
- 04审查代码库中的弹性缺口
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ melodic-software/ claude-code-plugins --skill resilience-patterns安装后在 Claude Code 中输入/resilience-patterns确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/brighter-resilience.mdcircuit-breaker-config.mddlq-patterns.mdpolly-patterns.mdretry-strategies.md详细介绍
弹性模式技能
概述
此技能介绍如何在 .NET 应用程序中实现弹性模式,涵盖使用 Polly 实现同步弹性(HTTP 客户端、服务调用),以及使用 Brighter 实现异步弹性(消息处理器)。
核心原则: 面向故障进行设计。系统应妥善处理瞬时故障、防止故障级联,并提供有意义的回退行为。
何时使用此技能
关键词: 弹性、熔断器、重试、polly、brighter、容错、瞬时故障、DLQ、死信队列、超时、舱壁、回退、HTTP 客户端弹性
在以下情况下使用此技能:
- 实现 HTTP 客户端弹性
- 为瞬时故障配置重试策略
- 设置熔断器以防止故障级联
- 设计消息处理器的错误处理
- 实现死信队列模式
- 为服务调用添加超时策略
- 配置舱壁隔离
弹性策略概览
同步弹性(Polly)
适用于 HTTP 调用和同步服务通信:
| 模式 | 用途 | 使用时机 |
|---|---|---|
| 重试 | 重试失败的操作 | 瞬时故障(网络、503、超时) |
| 熔断器 | 停止调用故障服务 | 反复故障表明服务已宕机 |
| 超时 | 限制操作耗时 | 防止无限期等待 |
| 舱壁 | 隔离故障 | 防止单个调用方耗尽资源 |
| 回退 | 提供替代方案 | 平稳降级 |
异步弹性(Brighter)
适用于基于消息的操作和异步操作:
| 模式 | 用途 | 使用时机 |
|---|---|---|
| 重试 | 重新投递失败的消息 | 瞬时处理故障 |
| 死信队列 | 暂存无法处理的消息 | 毒消息、业务规则故障 |
| 熔断器 | 暂停处理 | 下游服务不可用 |
| 超时 | 限制处理器的执行时间 | 防止处理器阻塞 |
快速入门:使用 HttpClient 的 Polly v8
基本设置
// Program.cs or Startup.cs
builder.Services.AddHttpClient<IOrderService, OrderService>()
.AddStandardResilienceHandler();
AddStandardResilienceHandler() 会添加一个预配置的管道,其中包含:
- 速率限制器
- 请求总超时
- 重试(指数退避)
- 熔断器
- 单次尝试超时
自定义配置
builder.Services.AddHttpClient<IOrderService, OrderService>()
.AddResilienceHandler("custom-pipeline", builder =>
{
// Retry with exponential backoff
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)
});
// Circuit breaker
builder.AddCircuitBreaker(new HttpCircuitBreakerStrategyOptions
{
FailureRatio = 0.5,
MinimumThroughput = 10,
SamplingDuration = TimeSpan.FromSeconds(30),
BreakDuration = TimeSpan.FromSeconds(30)
});
// Timeout per attempt
builder.AddTimeout(TimeSpan.FromSeconds(10));
});
Polly 模式详解: 请参阅 references/polly-patterns.md
快速入门:Brighter 消息处理器
基本重试策略
public class OrderCreatedHandler : RequestHandler<OrderCreated>
{
[UsePolicy("retry-policy", step: 1)]
public override OrderCreated Handle(OrderCreated command)
{
// Process order
return base.Handle(command);
}
}
策略注册表设置
var policyRegistry = new PolicyRegistry
{
{
"retry-policy",
Policy
.Handle<Exception>()
.WaitAndRetry(
retryCount: 3,
sleepDurationProvider: attempt =>
TimeSpan.FromSeconds(Math.Pow(2, attempt)))
}
};
services.AddBrighter()
.UseExternalBus(/* config */)
.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 // Immediate retry
});
指数退避
适用于需要等待一段时间才能恢复的瞬时故障:
.AddRetry(new RetryStrategyOptions
{
MaxRetryAttempts = 4,
Delay = TimeSpan.FromSeconds(1),
BackoffType = DelayBackoffType.Exponential,
UseJitter = true // Prevents thundering herd
});
延迟: 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, // Open after 25% failures
MinimumThroughput = 5, // Need at least 5 calls to evaluate
SamplingDuration = TimeSpan.FromSeconds(10),
BreakDuration = TimeSpan.FromSeconds(60) // Stay open 60s
});
激进(高可用)
.AddCircuitBreaker(new CircuitBreakerStrategyOptions
{
FailureRatio = 0.5, // Open after 50% failures
MinimumThroughput = 20, // Need 20 calls before evaluation
SamplingDuration = TimeSpan.FromSeconds(30),
BreakDuration = TimeSpan.FromSeconds(15) // Quick recovery attempt
});
**详细配置:**请参阅 references/circuit-breaker-config.md
死信队列模式
消息处理失败时
1. Message received
2. Handler attempts processing
3. Failure occurs
4. Retry policy applied (1...N attempts)
5. All retries exhausted
6. Message moved to DLQ
7. Alert/monitoring triggered
8. Manual investigation
Brighter DLQ 设置
services.AddBrighter()
.UseExternalBus(config =>
{
config.Publication.RequeueDelayInMs = 500;
config.Publication.RequeueCount = 3;
// After 3 requeues, message goes to DLQ
});
**完整的 DLQ 模式:**请参阅 references/dlq-patterns.md
组合模式
具备完整弹性的 HTTP 客户端
builder.Services.AddHttpClient<IPaymentGateway, PaymentGateway>()
.AddResilienceHandler("payment-gateway", builder =>
{
// Order matters: outer to inner
// 1. Total timeout (outer boundary)
builder.AddTimeout(TimeSpan.FromSeconds(30));
// 2. Retry (with circuit breaker inside)
builder.AddRetry(new HttpRetryStrategyOptions
{
MaxRetryAttempts = 3,
Delay = TimeSpan.FromMilliseconds(500),
BackoffType = DelayBackoffType.Exponential,
UseJitter = true
});
// 3. Circuit breaker
builder.AddCircuitBreaker(new HttpCircuitBreakerStrategyOptions
{
FailureRatio = 0.5,
MinimumThroughput = 10,
BreakDuration = TimeSpan.FromSeconds(30)
});
// 4. Per-attempt timeout (inner)
builder.AddTimeout(TimeSpan.FromSeconds(5));
});
带回退机制的消息处理程序
public class ProcessPaymentHandler : RequestHandler<ProcessPayment>
{
[UsePolicy("circuit-breaker", step: 1)]
[UsePolicy("retry", step: 2)]
[UsePolicy("fallback", step: 3)]
public override ProcessPayment Handle(ProcessPayment command)
{
_paymentService.Process(command);
return base.Handle(command);
}
}
可观测性
Polly 遥测
services.AddResiliencePipeline("my-pipeline", builder =>
{
builder.AddRetry(/* options */)
.ConfigureTelemetry(LoggerFactory.Create(b => b.AddConsole()));
});
需要监控的关键指标
| 指标 | 用途 | 告警阈值 |
|---|---|---|
| 重试次数 | 跟踪瞬时故障 | 每分钟 > 3 次 |
| 熔断器状态 | 跟踪服务健康状况 | 状态 = Open |
| DLQ 深度 | 跟踪处理失败 | > 0 |
| 超时率 | 跟踪响应缓慢的服务 | > 5% |
反模式
过度重试
**问题:**重试次数过多,间隔过短。
// BAD: 10 immediate retries
.AddRetry(new RetryStrategyOptions { MaxRetryAttempts = 10 });
**修复:**使用指数退避并限制重试次数:
// GOOD: 3 retries with backoff
.AddRetry(new RetryStrategyOptions
{
MaxRetryAttempts = 3,
Delay = TimeSpan.FromSeconds(1),
BackoffType = DelayBackoffType.Exponential
});
重试非瞬时故障
**问题:**重试业务逻辑故障。
// BAD: Retrying 400 Bad Request
ShouldHandle = new PredicateBuilder<HttpResponseMessage>()
.HandleResult(r => !r.IsSuccessStatusCode)
**修复:**仅重试瞬时故障:
// GOOD: Only retry transient HTTP codes
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
面向用户的界面
用户直接调用此技能时,它会审计代码库中的弹性模式。
执行工作流
- 解析参数 - 提取范围(默认为当前目录)、
--detailed标志和输出目录。 - 启动弹性分析 Agent - 分析 HTTP 客户端、消息处理程序、数据库调用和外部服务连接中的弹性模式(重试、熔断器、超时、DLQ)。
- 识别缺口 - 比较发现的依赖项与配置了弹性处理程序的依赖项。检测反模式(捕获后忽略、缺少超时)。
- 生成审计报告 - 生成包含执行摘要、附有代码位置和建议的关键缺口、现有良好实践、检测到的反模式及优先级改进计划的报告。
- 详细输出(如果使用
--detailed)- 包含代码片段、前后对比示例、配置模板和测试指南。 - 保存结果 - 保存到
docs/audits/resilience-audit-[date].md(或自定义--dir)。
版本历史
- v1.0.0(2025-12-26):首次发布