code:https://github.com/lvy010/Component-study
前言
在分布式系统开发中,弹性设计是确保系统可靠性的关键。本文将带您从零开始构建一个完整的Polly弹性上下文示例项目,通过实战演示如何在.NET应用中使用这一强大功能。
环境准备
首先确保您的开发环境已配置好.NET 8.0 SDK:
bash
# 检查.NET版本
dotnet --version
# 若未安装,使用以下命令安装
sudo apt update
sudo apt install -y dotnet-sdk-8.0
项目创建
我们创建一个新的控制台应用项目:
bash
dotnet new console -n PollyResilienceDemo -f net8.0
cd PollyResilienceDemo
添加Polly依赖
编辑项目文件添加Polly包引用:
xml
<ItemGroup>
<PackageReference Include="Polly" Version="8.3.1" />
</ItemGroup>
然后恢复依赖:
bash
dotnet restore
核心代码实现
以下是完整的Program.cs
实现,展示了弹性上下文的核心功能:
csharp
using Polly;
using Polly.Retry;
// 定义上下文键
public static class ContextKeys
{
public static readonly ResiliencePropertyKey<string> TraceId = new("TraceId");
public static readonly ResiliencePropertyKey<int> AttemptCount = new("AttemptCount");
}
var pipeline = new ResiliencePipelineBuilder()
.AddRetry(new RetryStrategyOptions
{
MaxRetryAttempts = 3,
Delay = TimeSpan.FromSeconds(1),
OnRetry = args =>
{
// 从上下文中读取追踪ID
var traceId = args.Context.Properties.GetValue(ContextKeys.TraceId, "N/A");
Console.WriteLine($"重试中 - 追踪ID: {traceId}, 尝试次数: {args.AttemptNumber}");
// 记录当前尝试次数
args.Context.Properties.Set(ContextKeys.AttemptCount, args.AttemptNumber);
return default;
}
})
.Build();
// 创建并配置弹性上下文
var context = ResilienceContextPool.Shared.Get();
context.Properties.Set(ContextKeys.TraceId, Guid.NewGuid().ToString()[..8]);
try
{
await pipeline.ExecuteAsync(async ctx =>
{
// 模拟可能失败的操作
var attempts = ctx.Properties.GetValue(ContextKeys.AttemptCount, 0);
Console.WriteLine($"执行操作 - 追踪ID: {ctx.Properties.GetValue(ContextKeys.TraceId, "N/A")}");
if (attempts < 2)
throw new InvalidOperationException("模拟失败");
Console.WriteLine("操作成功完成!");
}, context);
}
finally
{
// 将上下文返回到池中
ResilienceContextPool.Shared.Return(context);
}
项目构建与运行
构建并运行项目:
bash
dotnet build
dotnet run
预期输出示例:

关键知识点
-
弹性上下文(ResilienceContext):
- 作为操作执行的共享状态容器
- 通过
ResilienceContextPool
高效管理 - 包含唯一ID和取消令牌等核心属性
-
上下文属性(Properties):
- 类型安全的键值存储
- 使用
ResiliencePropertyKey<T>
定义键 - 贯穿整个操作生命周期
-
策略间通信:
- 允许不同策略共享数据
- 可在回调中读写上下文
- 支持复杂决策逻辑
进阶应用
扩展示例展示上下文在复杂场景中的应用:
csharp
// 添加超时策略
pipeline = pipeline.AddTimeout(TimeSpan.FromSeconds(2));
// 执行带上下文的操作
await pipeline.ExecuteAsync(async ctx =>
{
// 使用上下文中的取消令牌
await Task.Delay(1000, ctx.CancellationToken);
// 记录操作耗时
ctx.Properties.Set("OperationDuration", stopwatch.Elapsed);
}, context);
实践
- 始终通过
ResilienceContextPool
获取和返回上下文 - 为上下文键定义明确的类型
- 避免在上下文中存储大型对象
- 合理使用取消令牌实现协作式取消
总结
本文介绍了如何在.NET应用中使用Polly构建弹性上下文,通过实战演示了从项目创建到核心代码实现的全过程。重点讲解了弹性上下文(ResilienceContext)的概念、上下文属性的使用方法以及策略间通信机制,并提供了进阶应用示例。文章强调通过ResilienceContextPool管理上下文、定义类型安全键值等最佳实践,展示了Polly弹性上下文在构建可靠分布式系统中的重要作用,为.NET开发者提供了实用的弹性编程指南。
通过本文的实战演练,我们深入理解了Polly弹性上下文的核心概念和应用场景。这一机制为构建可靠的分布式系统提供了强大的状态管理和策略间通信能力,是.NET弹性编程中不可或缺的工具。