韧性模式实现技能Skill resilience-patterns

本技能提供在.NET应用程序中实施韧性模式的全面指南,涵盖断路器、重试、死信队列等关键模式,使用Polly和Brighter库实现故障容错和瞬态故障处理。关键词:韧性模式、断路器、重试、死信队列、.NET、Polly、Brighter、故障容错、瞬态故障、HTTP客户端韧性、消息处理程序韧性。

架构设计 0 次安装 0 次浏览 更新于 3/11/2026

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

用户界面

当用户直接调用时,此技能审计代码库中的韧性模式。

执行工作流

  1. 解析参数 - 提取范围(默认:当前目录)、--详细标志和输出目录。
  2. 生成韧性分析器代理 - 分析HTTP客户端、消息处理程序、数据库调用和外部服务连接的韧性模式(重试、断路器、超时、DLQ)。
  3. 识别差距 - 比较找到的依赖项与带有韧性处理程序的依赖项。检测反模式(捕捉并吞下、缺少超时)。
  4. 生成审计报告 - 生成报告,包括执行摘要、关键差距(带代码位置和建议)、现有良好实践、检测到的反模式以及优先级改进计划。
  5. 详细输出(如果--详细) - 包括代码片段、前后示例、配置模板和测试指南。
  6. 保存结果 - 保存到docs/audits/resilience-audit-[日期].md(或自定义--目录)。

版本历史

  • v1.0.0(2025-12-26):初始发布