<p>Resilience4j 官方无 C# 支持,.NET 应使用原生容错库 Polly;其 API 更贴合 C# 习惯,支持策略组合、状态持久化与 DI 深度集成,且需注册为 Singleton 以保证熔断器状态共享。</p>

Resilience4j 官方不支持 C#,你在 NuGet 上搜不到 resilience4j-csharp 或任何官方维护的 .NET 绑定包。所有声称“C#版 Resilience4j”的教程、GitHub 项目或 NuGet 包,要么是社区仿写(功能残缺、无维护)、要么是混淆了概念(把 Polly 当成 Resilience4j)。
为什么不能直接用 Resilience4j 的 Java 版本?
Java 的 Resilience4j 重度依赖 JVM 特性:函数式接口、Lambda 捕获、Spring AOP 字节码增强、CircuitBreakerRegistry 的单例线程安全实现等。.NET 运行时(CLR)没有等价机制,无法通过 JNI 或互操作桥接——这不是加个 wrapper 就能跑的事。
常见错误现象:
- 有人尝试用 IKVM.NET 把
resilience4j-circuitbreaker-2.1.0.jar转成 DLL,结果在 .NET 6+ 上抛出System.TypeLoadException: Could not load type 'io.vavr.collection.List' - 用 Java 进程做 gRPC 代理调用 Resilience4j,但每次调用增加 8–12ms 固定延迟,且无法共享熔断状态到其他 .NET 实例
- 文档里写的
RetryConfig.ofDefaults()在 C# 示例中直接照搬命名,实际编译报错:找不到类型RetryConfig
Polly 是 .NET 生态的事实标准
你真正该用的是 Polly——它不是 Resilience4j 的“移植版”,而是为 .NET 从零设计的容错库,API 更贴合 C# 习惯,且深度集成 IHttpClientFactory、Microsoft.Extensions.DependencyInjection 和 HealthChecks。
关键差异点:
-
Policy.Handle<httprequestexception>().WaitAndRetryAsync(3, i => TimeSpan.FromSeconds(Math.Pow(2, i)))</httprequestexception>—— 指数退避 + 异常过滤,一行代码替代 Resilience4j 里RetryConfig.custom().maxAttempts(3).waitDurationFunction(...)的 5 行配置 - 熔断器状态自动持久化到内存或 Redis(通过
ISyncPolicyRegistry),无需手动管理CircuitBreakerRegistry生命周期 - 所有策略(
Retry、CircuitBreaker、Timeout、RateLimit)都返回Policy或AsyncPolicy,可自由组合:Policy.WrapAsync(retryPolicy, circuitBreakerPolicy) - 不依赖 AOP:没有隐藏的代理类、无运行时反射开销,性能更可控
迁移 Resilience4j 风格配置到 Polly 的实操要点
如果你已有 Java 端 Resilience4j 配置(比如 YAML 中的 resilience4j.retry.instances.payment-service.max-attempts=3),不要试图逐字段映射。重点对齐语义,而非语法:
- Resilience4j 的
ignoreExceptions→ Polly 的HandleExcept<TException>(),但注意:Polly 默认只捕获指定异常,不会像 Resilience4j 那样默认忽略RuntimeException - Resilience4j 的
failAfterMaxAttempts(失败后抛原始异常)→ Polly 中就是默认行为;若需包装成BrokenCircuitException,得手动.FallbackAsync(...) - Resilience4j 的
recordExceptions列表 → 对应 Polly 的Handle<TException>().Or<TException2>()链式调用 - 超时单位:Resilience4j 默认毫秒,Polly 的
TimeSpan是纳秒精度,别写TimeSpan.FromMilliseconds(1000)这种低效写法,直接用TimeSpan.FromSeconds(1)
示例:等效于 Resilience4j 的 “重试 3 次,指数退避,仅对 TimeoutException 和 HttpRequestException 生效”:
var retryPolicy = Policy
.Handle<TimeoutException>()
.Or<HttpRequestException>()
.WaitAndRetryAsync(
retryCount: 3,
sleepDurationProvider: attempt => TimeSpan.FromSeconds(Math.Pow(2, attempt)),
onRetry: (outcome, timespan, retryCount, context) =>
{
// 日志建议:记录 retryCount 和当前等待时间,别只打 "retrying"
}
);
最易被忽略的一点:Polly 的策略实例是**有状态的**(尤其 CircuitBreaker),必须注册为 Singleton,否则每次新建策略都会重置熔断计数器——这和 Resilience4j 的 Registry 管理逻辑本质一致,但实现方式不同,容易在 DI 配置里漏掉 .AddSingleton。


















