.NET6空ASP.NET Core项目Locust压测响应慢,MiniProfiler耗时近零的原因与优化
问题:.NET6空ASP.NET Core项目Locust压测响应慢但MiniProfiler显示API执行时间近乎为零
我基于.NET6创建了一个空ASP.NET Core项目,使用Python Locust进行负载测试,平均响应时间约900ms,但通过MiniProfiler监控发现API执行时间近乎为零。请问这是什么原因?该如何优化?
负载测试结果

MiniProfiler监控API执行时间

资源使用情况

相关代码
Program.cs
var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); builder.Services.AddMemoryCache(); builder.Services.AddMiniProfiler(opt => { opt.RouteBasePath = "/profiler"; }); var app = builder.Build(); app.UseMiniProfiler(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } // app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run();
HomeController.cs
using Microsoft.AspNetCore.Mvc; namespace del.Controllers; [Route("[controller]")] public class HomeController : ControllerBase { [HttpGet] public IActionResult Get() => Ok(); [HttpPost] public IActionResult Post() => Ok(); }
Python Locust脚本
from locust import HttpUser, task class Date(HttpUser): @task def get_date(self): self.client.get('/home')
原因分析
- 请求排队/线程池阻塞:从资源截图看CPU占用极低,说明ASP.NET Core的请求处理线程未处于繁忙状态,大概率是请求在进入控制器之前就处于排队等待状态。而MiniProfiler仅统计控制器内部的执行时间,排队等前置环节的耗时不会被计入,因此出现控制器执行时间近乎为零但整体响应慢的矛盾现象。
- 开发环境性能限制:当前项目运行在开发环境,Swagger、MiniProfiler等诊断中间件会增加请求管道的额外开销;同时开发环境下Kestrel服务器的默认配置未针对高并发优化,比如线程池最小线程数设置较低,请求涌入时需要动态扩容线程池,这个过程会产生明显延迟。
- 连接与网络因素:如果Locust与被测服务在同一机器运行,可能存在端口资源竞争;若为远程测试,网络延迟也可能占比不小,但结合CPU低的表现,本地请求排队的可能性更大。
优化方案
1. 调整Kestrel服务器并发配置
在Program.cs中添加Kestrel的性能配置,提升并发处理能力:
builder.WebHost.ConfigureKestrel(options => { options.Limits.MaxConcurrentConnections = 1000; options.Limits.MaxConcurrentUpgradedConnections = 1000; options.Limits.MinResponseDataRate = null; });
2. 预设置线程池最小线程数
避免请求涌入时线程池动态扩容的延迟,在项目启动阶段设置线程池参数:
// 放在builder.Build()之前 System.Threading.ThreadPool.SetMinThreads(100, 100);
3. 切换至生产环境运行
开发环境的调试、诊断组件会带来额外开销,用生产环境模式启动服务:
- 命令行启动:
dotnet run --configuration Release - 或修改launchSettings.json,将环境变量设为
ASPNETCORE_ENVIRONMENT=Production
4. 移除非必需中间件
生产环境下移除Swagger、MiniProfiler等非核心中间件,精简请求管道:
// 仅在开发环境启用诊断类中间件 if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); app.UseMiniProfiler(); }
5. 优化Locust测试配置
- 确保Locust与被测服务网络连接稳定,优先选择本地或同一局域网测试
- 调整Locust的并发用户数和孵化速率,避免瞬间打满服务连接上限
内容的提问来源于stack exchange,提问作者WENJUN CHI
相关产品推荐
相关产品推荐

