本文面向希望在生产中落地 .NET 8 的团队,通过“可验证”的最小用例与参数配置,在保障稳定性的前提下获得吞吐与时延的改进。
## 版本与环境校验(可验证)
dotnet --info
输出中应包含 `NET SDK` 与 `Runtime Environment` 的版本信息,确认 `Runtime: .NET 8` 与 `ASP.NET Core` 组件版本一致;如多版本并存,请以部署管道实际使用的 SDK/Runtime 为准。
## Minimal APIs 基线(可验证)
using System.IO.Compression;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.ResponseCompression;
using Microsoft.Extensions.DependencyInjection;
var builder = WebApplication.CreateBuilder(args);
// 压缩(示例,见下文详细说明)
builder.Services.AddResponseCompression(options =>
{
options.EnableForHttps = true;
options.Providers.Add<GzipCompressionProvider>();
});
builder.Services.Configure<GzipCompressionProviderOptions>(o => o.Level = CompressionLevel.Fastest);
// 速率限制(示例,见下文详细说明)
builder.Services.AddRateLimiter(_ => { /* 统一在下文配置 */ });
var app = builder.Build();
app.UseResponseCompression();
app.UseRateLimiter();
app.MapGet("/ping", () => new { ok = true, ts = DateTimeOffset.UtcNow })
.RequireRateLimiting("fixed-window");
app.Run();
验证:本地运行后访问 `http://localhost:5000/ping`(或控制台显示的实际端口),返回 JSON,作为后续压测的基线端点。
## Kestrel 关键参数(可验证)
builder.WebHost.ConfigureKestrel(options =>
{
// 并发连接与头超时(根据压测再行收敛)
options.Limits.MaxConcurrentConnections = 10000; // 示例值,请以容量评估为准
options.Limits.KeepAliveTimeout = TimeSpan.FromSeconds(120);
options.Limits.RequestHeadersTimeout = TimeSpan.FromSeconds(30);
// HTTP/2 限制(仅在启用 HTTP/2 场景下生效)
options.Limits.Http2.MaxStreamsPerConnection = 100; // 与下游/客户端能力匹配
options.AddServerHeader = false; // 隐藏 Server 头,减少信息暴露
});
说明与验证要点:
- `MaxConcurrentConnections`、`KeepAliveTimeout`、`RequestHeadersTimeout` 为 Kestrel 官方支持参数;高并发场景下需要结合连接特性与负载均衡策略调整。
- 如启用 HTTP/2,`options.Limits.Http2.*` 系列参数有效;未启用则不影响连接行为。
- 在压测中观察 `p95/p99` 时延与错误分布,确保变更不会引入连接重置或超时异常。
## ResponseCompression(可验证)
using System.IO.Compression;
using Microsoft.AspNetCore.ResponseCompression;
builder.Services.AddResponseCompression(options =>
{
options.EnableForHttps = true; // HTTPS 下启用
options.Providers.Add<GzipCompressionProvider>();
});
builder.Services.Configure<GzipCompressionProviderOptions>(o =>
{
o.Level = CompressionLevel.Fastest; // CPU 与带宽的权衡,可在压测中对比 Optimal/Fastest
});
app.UseResponseCompression();
验证:对返回体较大的端点进行前后对比,记录响应体大小与 CPU 使用率变化;在小响应(如 `/ping`)场景下不强制开启压缩,避免额外开销。
## 速率限制(Rate Limiting,中间件,可验证)
using System.Threading.RateLimiting;
using Microsoft.AspNetCore.RateLimiting;
builder.Services.AddRateLimiter(options =>
{
options.RejectionStatusCode = StatusCodes.Status429TooManyRequests;
options.AddFixedWindowLimiter("fixed-window", limiterOptions =>
{
limiterOptions.PermitLimit = 100; // 每窗口可通过请求数(示例值)
limiterOptions.Window = TimeSpan.FromSeconds(1);
limiterOptions.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
limiterOptions.QueueLimit = 0; // 无排队,快速失败
});
});
app.UseRateLimiter();
验证:并发压测下观察 429 命中率与整体延迟分布;结合上游网关/负载策略,设定合理的窗口与队列策略。
## EF Core 性能要点(可验证)
using Microsoft.EntityFrameworkCore;
builder.Services.AddDbContextPool<AppDbContext>(options =>
{
options.UseSqlServer(builder.Configuration.GetConnectionString("Default"));
options.EnableThreadSafetyChecks(false); // 在明确线程模型下可关闭额外检查
});
// 查询示例
var app = builder.Build();
app.MapGet("/users/{id}", async (int id, AppDbContext db) =>
{
var user = await db.Users.AsNoTracking().FirstOrDefaultAsync(x => x.Id == id);
return user is null ? Results.NotFound() : Results.Ok(user);
});
验证要点:
- `AddDbContextPool` 复用上下文,降低频繁创建的成本;适配连接池与并发模型。
- 读操作默认使用 `AsNoTracking`,减少跟踪开销;写操作使用批量 API(如 `ExecuteUpdate`)按需优化。
- 在迁移到 .NET 8 后,评估编译模型(Compiled Models)与实体配置的静态化收益。
## Native AOT(原生 AOT,可验证)
发布示例:
dotnet publish -r win-x64 -c Release -p:PublishAot=true
要点与约束:
- 动态生成/反射(如运行时加载未标注的类型)会被裁剪,需要保留说明或替代方案;优先使用显式配置与源生成器(Source Generators)。
- 使用第三方库前确认其对 AOT 的支持情况;如不支持,采用非 AOT 发布或进行保留根配置。
- AOT 二进制启动更快、占用更小,但调试与诊断手段与常规发布不同,需要在预演环境验证端到端链路。
验证:在 AOT 构建后运行集成测试与端点回归;如出现裁剪导致的功能缺失,结合 `DynamicDependency`/`RequiresUnreferencedCode` 注解或替换实现。
## 线程池与 GC(可验证)
- 在压测与生产运行时采集 `ThreadPool Completed Work Item Count` 与 `Queue Length`,避免长时间排队;必要时通过负载均衡与速率限制分流。
- 观察垃圾回收(GC)模式(Server/Workstation)与代回收分布,评估大对象分配(LOH)与响应抖动关系;按需调整对象复用与缓冲策略。
## 压测建议(可验证)
- 选择通用端点(如 `/ping` 与典型业务查询)进行 60–120 秒压测,记录 `RPS`、`p95/p99` 与错误率。
- 举例工具:`bombardier` 或 `wrk`(根据团队现有工具链),参数以 CPU/带宽特性与业务延迟目标为准。
## 注意事项
- 以“可验证”为原则进行每项优化:先最小用例验证,再在预演环境跑通完整链路,最终进入生产发布。
- 任何参数(连接并发、压缩、速率限制)都需要压测与监控数据支撑,避免纸面优化。
- 升级到 .NET 8 前,统一 `SDK/Runtime` 版本与 CI/CD 构建环境,确保线上一致性。
## 结语
通过 Minimal APIs、Kestrel 参数、ResponseCompression、速率限制与 EF Core 的组合优化,并在合适场景采用 Native AOT,团队可以在 .NET 8 上获得可观的启动与吞吐收益。坚持“可验证”的方法论与监控回归,才能把收益稳定地带入生产环境。

发表评论 取消回复