c# Minimal API 如何处理高并发

来源:这里教程网 时间:2026-02-21 17:38:51 作者:

Minimal API 默认就是高并发友好的

ASP.NET Core Minimal API 基于 Kestrel 和

Task
-based 异步管道构建,底层复用
ThreadPool
和 I/O 完成端口(Windows)或
epoll
/
kqueue
(Linux/macOS),只要你不写阻塞代码(比如
Task.Wait()
Result
Thread.Sleep()
),它天然能支撑数千并发连接。瓶颈通常不出在框架层,而出在你的业务逻辑、IO 调用或资源争用上。

避免同步阻塞和共享状态竞争

常见误操作会让 Minimal API 在高并发下迅速退化为串行处理:

MapGet
MapPost
处理函数里调用
HttpClient.GetStringAsync().Result
—— 会死锁或耗尽线程池
用静态字段或
static readonly Dictionary<string object></string>
缓存数据但没加锁 ——
ArgumentException: An item with the same key has already been added
或数据错乱
直接 new
SqlConnection
但没用
using
或没启用连接池(实际默认开启,但显式关闭
Pooling=false
就会崩)

正确做法是全程

async/await
,缓存用
ConcurrentDictionary
MemoryCache
,数据库连接靠连接池自动复用。

合理配置 Kestrel 和连接生命周期

默认 Kestrel 配置适合开发,生产需调整关键参数:

MaxConcurrentConnections
:Linux 下可设为
null
(不限制),但建议结合 ulimit 控制
KeepAliveTimeout
:默认 2 分钟,短连接场景可降到 30 秒减少空闲连接堆积
RequestHeadersTimeout
:防止慢速 HTTP 攻击,设为 15–30 秒较稳妥
禁用
UseHttpsRedirection()
(若已由前置 LB 终止 HTTPS),减少 TLS 握手开销
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.Limits.MaxConcurrentConnections = null;
    serverOptions.Limits.KeepAliveTimeout = TimeSpan.FromSeconds(30);
    serverOptions.Limits.RequestHeadersTimeout = TimeSpan.FromSeconds(20);
});

用中间件做轻量级限流和熔断

Minimal API 不自带限流,但可以零依赖接入

Microsoft.AspNetCore.RateLimiting
(.NET 7+):

按 IP 或用户 ID 限流,防爬虫或误调用
TokenBucketRateLimiter
比滑动窗口更省内存
配合
AddConcurrencyLimiter
防止下游 DB/Redis 过载(例如限制最多 100 个并发 DB 查询)

注意:限流策略必须注册在

builder.Services
中,且中间件顺序要在
app.UseRouting()
之后、
app.Map*
之前。

builder.Services.AddRateLimiter(options =>
{
    options.AddTokenBucketLimiter("fixed", opt =>
    {
        opt.TokenLimit = 100;
        opt.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
        opt.QueueLimit = 20;
        opt.ReplenishmentPeriod = TimeSpan.FromSeconds(1);
        opt.TokensPerPeriod = 20;
    });
});
// ... 在 app.Build() 后
app.UseRateLimiter();
app.MapGet("/api/data", () => "ok").RequireRateLimiting("fixed");

真正卡住高并发的,往往不是路由注册方式,而是你查一次 DB 就等 200ms、缓存没命中就全量扫表、或是日志写磁盘用了

File.AppendAllText
。Minimal API 的轻量只放大了这些细节问题——它不替你做性能优化,只确保不拖后腿。

相关推荐