Token导航 LogoToken导航TokenDH.com
开发需要联网github未标认证来源可访问许可证需确认审计异常

dotnet-resilience点网弹性

Agent Skill

dotnet-resilience 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要围绕仓库状态、代码变更或协作事项进行整理时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

367

周安装

15

GitHub Stars

15

下载量

118
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:dotnet-resilience(点网弹性)
来源仓库:https://github.com/wshaddix/dotnet-skills
仓库路径:skills/dotnet-resilience
安装命令:
npx skills add https://github.com/wshaddix/dotnet-skills --skill dotnet-resilience
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/wshaddix/dotnet-skills --skill dotnet-resilience

简介

实现现代弹性模式,使用 Polly v8 和 Microsoft.Extensions.Http.Resilience。

  • 支持速率限制、超时、重试和断路器组合,集成依赖注入系统。
  • 通过 GitHub 安装,需迁移旧版 Microsoft.Extensions.Http.Polly 项目。
  • 不涉及 DI 容器机制或服务生命周期管理等底层细节。
  • dotnet-resilience 属于开发类 Skill,可作为该场景下的辅助能力补充。

SKILL.md

dotnet-resilience

Modern resilience patterns for.NET applications using Polly v8 and Microsoft.Extensions.Http.Resilience. Covers the standard resilience pipeline (rate limiter, total timeout, retry, circuit breaker, attempt timeout), custom pipeline configuration, and integration with the.NET dependency injection system.

Superseded package: Microsoft.Extensions.Http.Polly is superseded by Microsoft.Extensions.Http.Resilience. Do not use Microsoft.Extensions.Http.Polly for new projects. See the migration guide for upgrading existing code.

Out of scope: DI container mechanics and service lifetimes -- see [skill:dotnet-csharp-dependency-injection]. Async/await patterns and cancellation token propagation -- see [skill:dotnet-csharp-async-patterns]. HTTP client factory patterns (typed clients, named clients, DelegatingHandlers) are covered in [skill:dotnet-http-client]. Testing resilience policies -- see [skill:dotnet-integration-testing] for testing with WebApplicationFactory and [skill:dotnet-xunit] for unit testing resilience handlers.

Cross-references: [skill:dotnet-csharp-dependency-injection] for service registration, [skill:dotnet-csharp-async-patterns] for cancellation token propagation, [skill:dotnet-http-client] for applying resilience to HTTP clients.


Package Landscape

PackageStatusPurpose
Polly (v8+)CurrentCore resilience library -- strategies, pipelines, telemetry
Microsoft.Extensions.ResilienceCurrentDI integration for non-HTTP resilience pipelines
Microsoft.Extensions.Http.ResilienceCurrentDI integration for IHttpClientFactory resilience pipelines
Microsoft.Extensions.Http.PollySupersededLegacy HTTP resilience -- migrate to Microsoft.Extensions.Http.Resilience
Polly (v7 and earlier)LegacyOlder API -- migrate to v8

Install the modern stack:

<PackageReference Include="Microsoft.Extensions.Http.Resilience" Version="9.*" />
<!-- Transitively brings in Polly v8 and Microsoft.Extensions.Resilience -->

For non-HTTP scenarios only:

<PackageReference Include="Microsoft.Extensions.Resilience" Version="9.*" />

Standard Resilience Pipeline

Microsoft.Extensions.Http.Resilience provides a standard resilience pipeline that follows the recommended order. The pipeline layers execute from outermost to innermost:

Request
  --> Rate Limiter        (1. shed excess load)
    --> Total Timeout      (2. cap total wall-clock time)
      --> Retry             (3. retry transient failures)
        --> Circuit Breaker  (4. stop calling failing services)
          --> Attempt Timeout (5. cap individual attempt time)
            --> HTTP call

Why This Order Matters

  • Rate limiter first: prevents retry storms from overwhelming downstream services
  • Total timeout wraps retry: ensures the entire operation (including all retries) has a deadline
  • Retry wraps circuit breaker: retries can try again after the breaker resets; a broken circuit counts as a retriable failure
  • Circuit breaker wraps attempt timeout: timed-out attempts count toward the breaker's failure threshold
  • Attempt timeout innermost: each individual HTTP call has its own deadline

Standard Pipeline with Defaults

builder.Services
    .AddHttpClient("catalog-api", client =>
    {
        client.BaseAddress = new Uri("https://catalog.internal");
    })
    .AddStandardResilienceHandler();

This applies the standard pipeline with sensible defaults:

  • Rate limiter: 1000 concurrent requests
  • Total timeout: 30 seconds
  • Retry: 3 attempts, exponential backoff (2s base), jitter
  • Circuit breaker: 10% failure ratio, 100 sample size, 5s break duration
  • Attempt timeout: 10 seconds

Standard Pipeline with Custom Options

builder.Services
    .AddHttpClient("catalog-api", client =>
    {
        client.BaseAddress = new Uri("https://catalog.internal");
    })
    .AddStandardResilienceHandler(options =>
    {
        // Total timeout for the entire operation including retries
        options.TotalRequestTimeout.Timeout = TimeSpan.FromSeconds(60);

        // Retry strategy
        options.Retry.MaxRetryAttempts = 5;
        options.Retry.Delay = TimeSpan.FromSeconds(1);
        options.Retry.BackoffType = DelayBackoffType.Exponential;
        options.Retry.UseJitter = true;
        options.Retry.ShouldHandle = args => ValueTask.FromResult(
            args.Outcome.Result?.StatusCode is
                HttpStatusCode.RequestTimeout or
                HttpStatusCode.TooManyRequests or
                >= HttpStatusCode.InternalServerError);

        // Circuit breaker
        options.CircuitBreaker.SamplingDuration = TimeSpan.FromSeconds(30);
        options.CircuitBreaker.FailureRatio = 0.1;
        options.CircuitBreaker.MinimumThroughput = 20;
        options.CircuitBreaker.BreakDuration = TimeSpan.FromSeconds(10);

        // Per-attempt timeout
        options.AttemptTimeout.Timeout = TimeSpan.FromSeconds(5);
    });

Configuration via appsettings.json

Bind resilience options from configuration for environment-specific tuning:

builder.Services
    .AddHttpClient("catalog-api", client =>
    {
        client.BaseAddress = new Uri("https://catalog.internal");
    })
    .AddStandardResilienceHandler(options =>
    {
        builder.Configuration
            .GetSection("Resilience:CatalogApi")
            .Bind(options);
    });
{
  "Resilience": {
    "CatalogApi": {
      "Retry": {
        "MaxRetryAttempts": 5,
        "Delay": "00:00:02",
        "BackoffType": "Exponential"
      },
      "CircuitBreaker": {
        "BreakDuration": "00:00:15"
      },
      "TotalRequestTimeout": {
        "Timeout": "00:01:00"
      }
    }
  }
}

Custom Resilience Pipelines

When the standard pipeline does not fit, build custom pipelines with Polly v8 directly.

Retry Strategy

builder.Services.AddResiliencePipeline("db-retry", pipelineBuilder =>
{
    pipelineBuilder.AddRetry(new RetryStrategyOptions
    {
        MaxRetryAttempts = 3,
        Delay = TimeSpan.FromMilliseconds(500),
        BackoffType = DelayBackoffType.Exponential,
        UseJitter = true,
        ShouldHandle = new PredicateBuilder()
            .Handle<DbUpdateConcurrencyException>()
            .Handle<TimeoutException>(),
        OnRetry = args =>
        {
            // Structured logging of retry attempts
            var logger = args.Context.Properties
                .GetValue(new ResiliencePropertyKey<ILogger>("logger"), null!);
            logger?.LogWarning(
                args.Outcome.Exception,
                "Retry attempt {AttemptNumber} after {Delay}ms",
                args.AttemptNumber,
                args.RetryDelay.TotalMilliseconds);
            return ValueTask.CompletedTask;
        }
    });
});

// Inject and use
public sealed class OrderRepository(
    [FromKeyedServices("db-retry")] ResiliencePipeline pipeline,
    AppDbContext db)
{
    public async Task<Order> UpdateAsync(Order order, CancellationToken ct)
    {
        return await pipeline.ExecuteAsync(async token =>
        {
            db.Orders.Update(order);
            await db.SaveChangesAsync(token);
            return order;
        }, ct);
    }
}

Circuit Breaker Strategy

builder.Services.AddResiliencePipeline("payment-gateway", pipelineBuilder =>
{
    pipelineBuilder.AddCircuitBreaker(new CircuitBreakerStrategyOptions
    {
        SamplingDuration = TimeSpan.FromSeconds(30),
        FailureRatio = 0.25,           // Open after 25% failure rate
        MinimumThroughput = 10,        // Need at least 10 calls to evaluate
        BreakDuration = TimeSpan.FromSeconds(15),
        ShouldHandle = new PredicateBuilder()
            .Handle<HttpRequestException>()
            .Handle<TimeoutException>()
    });
});

Timeout Strategy

builder.Services.AddResiliencePipeline("external-api", pipelineBuilder =>
{
    // Total timeout for the entire pipeline execution
    pipelineBuilder.AddTimeout(new TimeoutStrategyOptions
    {
        Timeout = TimeSpan.FromSeconds(30),
        OnTimeout = args =>
        {
            // Log timeout details for diagnostics
            return ValueTask.CompletedTask;
        }
    });
});

Composing Multiple Strategies

Build a composite pipeline by chaining strategies. Order matters -- outermost strategy is added first:

builder.Services.AddResiliencePipeline("composed", pipelineBuilder =>
{
    // 1. Total timeout (outermost -- caps entire operation)
    pipelineBuilder.AddTimeout(new TimeoutStrategyOptions
    {
        Timeout = TimeSpan.FromSeconds(45)
    });

    // 2. Retry (retries on transient failures)
    pipelineBuilder.AddRetry(new RetryStrategyOptions
    {
        MaxRetryAttempts = 3,
        Delay = TimeSpan.FromSeconds(1),
        BackoffType = DelayBackoffType.Exponential,
        UseJitter = true,
        ShouldHandle = new PredicateBuilder()
            .Handle<HttpRequestException>()
            .Handle<TimeoutException>()
    });

    // 3. Circuit breaker (stops calling failing services)
    pipelineBuilder.AddCircuitBreaker(new CircuitBreakerStrategyOptions
    {
        FailureRatio = 0.1,
        MinimumThroughput = 20,
        SamplingDuration = TimeSpan.FromSeconds(30),
        BreakDuration = TimeSpan.FromSeconds(10),
        ShouldHandle = new PredicateBuilder()
            .Handle<HttpRequestException>()
            .Handle<TimeoutException>()
    });

    // 4. Attempt timeout (innermost -- caps single attempt)
    pipelineBuilder.AddTimeout(new TimeoutStrategyOptions
    {
        Timeout = TimeSpan.FromSeconds(10)
    });
});

Typed Resilience Pipelines

For result-bearing operations, use ResiliencePipeline<T>:

builder.Services.AddResiliencePipeline<string, HttpResponseMessage>(
    "typed-http",
    pipelineBuilder =>
    {
        pipelineBuilder.AddRetry(new RetryStrategyOptions<HttpResponseMessage>
        {
            MaxRetryAttempts = 3,
            Delay = TimeSpan.FromSeconds(1),
            BackoffType = DelayBackoffType.Exponential,
            ShouldHandle = new PredicateBuilder<HttpResponseMessage>()
                .Handle<HttpRequestException>()
                .HandleResult(r => r.StatusCode >= HttpStatusCode.InternalServerError)
        });
    });

Hedging Strategy

Send parallel requests to reduce tail latency. The hedging strategy dispatches additional attempts if the initial request is slow:

builder.Services
    .AddHttpClient("search-api")
    .AddStandardHedgingHandler(options =>
    {
        options.Hedging.MaxHedgedAttempts = 2;
        options.Hedging.Delay = TimeSpan.FromMilliseconds(500);
        // Hedging sends a parallel request if the first hasn't
        // responded within 500ms
    });

Use hedging when:

  • Operations are idempotent (GET requests, read-only queries)
  • Tail latency reduction matters more than extra load

Do not use hedging when:

  • Operations have side effects (POST, PUT, DELETE)
  • Downstream services cannot handle increased load

Telemetry and Observability

Polly v8 emits metrics and traces via System.Diagnostics out of the box when using the DI integration.

Built-in Metrics

The Microsoft.Extensions.Resilience package automatically reports:

MetricDescription
polly.strategy.attempt.durationDuration of each attempt
polly.strategy.pipeline.durationDuration of the entire pipeline execution
polly.strategy.attempt.countCount of attempts (including retries)

These integrate with OpenTelemetry automatically when the OpenTelemetry SDK is configured in your application -- see [skill:dotnet-observability] for collector setup.

Enabling Telemetry

Resilience telemetry is enabled automatically when using the DI-based registration (AddResiliencePipeline, AddStandardResilienceHandler). The Microsoft.Extensions.Resilience package registers a MeteringEnricher and LoggingEnricher that emit structured logs and metrics through the standard ILoggerFactory and IMeterFactory from DI:

// Telemetry is automatic -- no extra configuration needed.
// Structured logs appear via ILogger; metrics via IMeter.
builder.Services
    .AddHttpClient("catalog-api")
    .AddStandardResilienceHandler();

// To see resilience logs, set the Polly category to Information:
// appsettings.json
// {
//   "Logging": {
//     "LogLevel": {
//       "Polly": "Information"
//     }
//   }
// }

Migrating from Microsoft.Extensions.Http.Polly

If upgrading from the superseded Microsoft.Extensions.Http.Polly package:

Before (Legacy)

// Using Microsoft.Extensions.Http.Polly (superseded)
builder.Services
    .AddHttpClient("catalog-api")
    .AddTransientHttpErrorPolicy(p =>
        p.WaitAndRetryAsync(3, attempt =>
            TimeSpan.FromSeconds(Math.Pow(2, attempt))))
    .AddTransientHttpErrorPolicy(p =>
        p.CircuitBreakerAsync(5, TimeSpan.FromSeconds(30)));

After (Modern)

// Using Microsoft.Extensions.Http.Resilience (current)
builder.Services
    .AddHttpClient("catalog-api")
    .AddStandardResilienceHandler(options =>
    {
        options.Retry.MaxRetryAttempts = 3;
        options.Retry.Delay = TimeSpan.FromSeconds(2);
        options.Retry.BackoffType = DelayBackoffType.Exponential;

        options.CircuitBreaker.MinimumThroughput = 5;
        options.CircuitBreaker.BreakDuration = TimeSpan.FromSeconds(30);
    });

Migration Steps

  1. Replace Microsoft.Extensions.Http.Polly NuGet reference with Microsoft.Extensions.Http.Resilience
  2. Replace AddTransientHttpErrorPolicy calls with AddStandardResilienceHandler or custom pipeline
  3. Translate Polly v7 policy configuration to v8 strategy options
  4. Remove explicit IAsyncPolicy<HttpResponseMessage> type references
  5. Verify retry/circuit breaker behavior matches previous configuration

Key Principles

  • Use the standard pipeline for HTTP -- AddStandardResilienceHandler() covers the most common case with battle-tested defaults
  • Customize via options, not custom code -- the standard handler options cover retry count, backoff, circuit breaker thresholds, and timeouts
  • Use AddResiliencePipeline for non-HTTP -- database calls, message queues, file I/O
  • Always add jitter to retries -- prevents thundering herd when multiple clients retry simultaneously
  • Configure via appsettings.json -- different environments need different thresholds; avoid hardcoded values in production
  • Do not suppress TimeoutRejectedException -- let it propagate through the pipeline so outer strategies (retry, circuit breaker) can react
  • Do not use Microsoft.Extensions.Http.Polly for new projects -- it wraps Polly v7 and is superseded

Agent Gotchas

  1. Do not mix Polly v7 and v8 APIs -- v8 uses ResiliencePipeline and strategy options; v7 uses IAsyncPolicy. They are not interchangeable.
  2. Do not add AddStandardResilienceHandler twice -- it composes a full pipeline; adding it twice doubles every strategy layer.
  3. Do not set attempt timeout higher than total timeout -- the attempt timeout must be shorter than the total timeout or it has no effect.
  4. Do not retry non-idempotent operations -- only retry operations that are safe to repeat (GETs, idempotent writes with idempotency keys).
  5. Do not use hardcoded retry delays in production -- always use UseJitter = true and configure delays via appsettings.

References

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

33.5%
按下载量换算40

Claude

33.03%
按下载量换算39

Cursor

17.74%
按下载量换算21

Gemini CLI

9.97%
按下载量换算12

安全审计

Gen Agent Trust Hub

通过

Socket

未通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。来源安全扫描存在 warning/failed 结果,不能写成本站确认安全。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills