偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

為什么這個(gè)API慢得離譜?從400ms到40ms的.NET 9性能優(yōu)化實(shí)戰(zhàn)

開發(fā) 前端
如果這對(duì)你有幫助,請(qǐng)點(diǎn)贊并與你的團(tuán)隊(duì)分享。如果你在.NET Minimal API中遇到性能瓶頸,我很想知道你是如何解決的——或者你仍然卡在哪里。?

和其他“簡單”的性能抱怨一樣,這個(gè)故事始于一個(gè)看似普通的性能問題。我們的.NET 9 Minimal API擁有所有時(shí)髦的特性——輕量級(jí)、快速啟動(dòng)、簡潔的端點(diǎn)。但在生產(chǎn)環(huán)境中?平均延遲高達(dá)400毫秒。

這還發(fā)生在熱路徑上。一個(gè)GET請(qǐng)求。甚至沒有數(shù)據(jù)庫調(diào)用。

作為長期使用C#的開發(fā)者,我能感覺到事情不對(duì)勁。于是我打開性能分析器,準(zhǔn)備深入調(diào)查。隨后便陷入了一系列“無害”中間件、不當(dāng)使用的HttpClient和出乎意料的異步開銷的迷宮。

經(jīng)過兩天殘酷的優(yōu)化,我們將這個(gè)API的中位延遲降低到了約40毫秒。本文記錄了每一個(gè)關(guān)鍵的修復(fù)步驟、基準(zhǔn)測(cè)試和代碼調(diào)整。

如果你在生產(chǎn)環(huán)境運(yùn)行.NET 9 API,這可能是你這周最有價(jià)值的10分鐘閱讀。

第一步:先分析,別猜測(cè)

在深入代碼之前,重要提醒:不要盲目優(yōu)化。我使用了以下工具:

? dotnet-trace:追蹤GC壓力和方法級(jí)性能

? dotnet-counters:監(jiān)控CPU、分配率和請(qǐng)求吞吐量

? JetBrains Rider Profiler:深入分析調(diào)用棧和慢端點(diǎn)

這是我立即發(fā)現(xiàn)的問題:

[400ms總延遲]└── 120ms: 中間件(自定義日志、CORS、指標(biāo)收集)└── 80ms: JSON序列化└── 60ms: HttpClient實(shí)例化(??)└── 40ms: GC暫停(分配密集型代碼)└── 100ms: 實(shí)際處理邏輯

現(xiàn)在我們來逐一解決。

第二步:無情削減中間件

我們喜歡可觀測(cè)性,但在Minimal API中,中間件的成本是真實(shí)存在的。

原來代碼:

app.Use(async (context, next) => {
    var sw = Stopwatch.StartNew();
    await next();
    logger.LogInformation($"Request took {sw.ElapsedMilliseconds}ms");
});

app.UseCors(...);
app.Use(async (context, next) => {
    metrics.Increment("api_requests");
    await next();
});

問題:每個(gè)Use都增加異步開銷,Stopwatch增加每次請(qǐng)求的分配

? 修復(fù):

? 使用Middleware類替代內(nèi)聯(lián)中間件(減少lambda捕獲)

? 通過OpenTelemetry將日志和指標(biāo)推送到ActivityListener

? 內(nèi)部API完全移除CORS

效果:節(jié)省約80ms

第三步:重用你的HttpClient

這個(gè)有點(diǎn)尷尬。在我們的處理程序中:

app.MapGet("/data", async () => {
    using var client = new HttpClient();
    var result = await client.GetStringAsync("https://internal-api/data");
    return Results.Ok(result);
});

經(jīng)典新手錯(cuò)誤:每次請(qǐng)求都銷毀HttpClient會(huì)殺死socket復(fù)用

? 修復(fù):

var httpClient = new HttpClient(new SocketsHttpHandler {
    PooledConnectionLifetime = TimeSpan.FromMinutes(5)
});

app.MapGet("/data", async () => {
    var result = await httpClient.GetStringAsync("https://internal-api/data");
    return Results.Ok(result);
});

或者更推薦使用IHttpClientFactory(如果需要策略)

效果:節(jié)省約60ms,負(fù)載下CPU降低12%

第四步:異步并不總是免費(fèi)的

有個(gè)誤區(qū):異步=快速。并非總是如此。

如果你的端點(diǎn)不需要等待I/O(比如從內(nèi)存讀?。?,異步只會(huì)增加上下文切換和額外分配。

我們的“健康檢查”端點(diǎn)原來是這樣的:

app.MapGet("/health", async () => {
    return Results.Ok("Healthy");
});

? 修復(fù):直接改為同步

app.MapGet("/health", () => Results.Ok("Healthy"));

僅此一項(xiàng)就節(jié)省了約20ms(避免了異步狀態(tài)機(jī))

第五步:精簡JSONSystem.Text.Json很快——但需要正確配置。

我們使用了默認(rèn)設(shè)置,會(huì)序列化所有內(nèi)容:包括null值和不需要的巨大DTO屬性。

? 修復(fù):

? 使用[JsonIgnore]或創(chuàng)建精簡DTO

? 全局配置JSON:

builder.Services.Configure<JsonOptions>(options =>
{
    options.SerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
    options.SerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
});

? 序列化大型已知結(jié)構(gòu)時(shí)使用源生成器

效果:節(jié)省約30ms,響應(yīng)大小減少18%

第六步:啟用響應(yīng)壓縮(但非必需)GZip有幫助——除非你大規(guī)模壓縮300字節(jié)的有效負(fù)載。

我們?nèi)謫⒂昧藟嚎s。這是個(gè)壞主意。對(duì)于小負(fù)載,這是CPU浪費(fèi)。

? 修復(fù):

builder.Services.AddResponseCompression(options =>
{
    options.EnableForHttps = true;
    options.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(new[] {
        "application/json"
    });
});

然后在邏輯中:

app.UseWhen(ctx => ctx.Request.Path.StartsWithSegments("/big"), builder =>
{
    builder.UseResponseCompression();
});

現(xiàn)在只壓縮大型JSON,跳過其他內(nèi)容

效果:平均節(jié)省15-20ms

額外技巧:預(yù)熱JIT,緩存一切這在負(fù)載測(cè)試前并不明顯

? 添加[PreJIT]路由或在啟動(dòng)時(shí)通過虛擬請(qǐng)求強(qiáng)制預(yù)熱

? 在單例或作用域服務(wù)中緩存查找和配置讀取

? 將靜態(tài)數(shù)據(jù)移入內(nèi)存——如枚舉或只讀參考數(shù)據(jù)

app.Lifetime.ApplicationStarted.Register(() =>
{
    _ = httpClient.GetStringAsync("https://internal-api/warmup");
});

這些小調(diào)整又額外節(jié)省了10-15ms

最終基準(zhǔn)測(cè)試:優(yōu)化前后[圖片:優(yōu)化前后性能對(duì)比圖表]

結(jié)語:性能不是偶然Minimal API很快——但前提是你要像對(duì)待F1賽車而不是家用轎車那樣對(duì)待它們。

每一層都很重要。每次分配都會(huì)累積。每個(gè)中間件、序列化器配置和異步調(diào)用都會(huì)引入摩擦。

事實(shí)上,這篇文章不是關(guān)于“巧妙技巧”,而是關(guān)于殘酷的專注和對(duì)抽象成本的尊重。

如果你正在大規(guī)模部署API,性能分析不是可選的。優(yōu)化不是過早的。延遲就是一個(gè)功能特性。

TL;DR 檢查清單

? 移除或合并中間件

? 使用連接池重用HttpClient

? 在不需要的地方避免異步

? 精簡JSON輸出并使用源生成器

? 選擇性添加壓縮

? 預(yù)熱JIT并積極緩存

如果這對(duì)你有幫助,請(qǐng)點(diǎn)贊并與你的團(tuán)隊(duì)分享。如果你在.NET Minimal API中遇到性能瓶頸,我很想知道你是如何解決的——或者你仍然卡在哪里。

責(zé)任編輯:武曉燕 來源: 架構(gòu)師老盧
相關(guān)推薦

2022-08-14 14:32:06

接口優(yōu)化

2025-05-20 04:00:00

2020-09-01 11:10:39

數(shù)據(jù)庫鏈接池HikariCP

2025-10-27 02:11:00

2022-07-05 10:50:31

數(shù)據(jù)庫查詢實(shí)戰(zhàn)

2024-12-05 10:18:48

2021-07-05 08:58:17

Golang分布式性能

2025-09-30 01:33:00

2022-09-19 08:41:02

數(shù)據(jù)查詢分離

2023-09-27 08:21:00

查詢分離數(shù)據(jù)API

2024-05-28 08:47:52

2022-09-27 08:40:44

慢查詢MySQL定位優(yōu)化

2024-08-30 09:31:36

2022-06-30 19:40:36

查詢接口索引優(yōu)化

2020-08-06 11:25:29

數(shù)據(jù)庫鏈接池線程

2014-01-09 09:35:26

2009-12-09 10:56:53

MS VS.NET 2

2009-03-23 16:00:52

微軟

2024-05-16 11:51:44

前端性能優(yōu)化JavaScript

2025-01-03 08:29:53

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)