对于演示,我打算运行一个基准测试,我将运行在Kestrel上的.NET Core与运行在IIS上的.NET Framework 4.6.1进行比较。两者都在本地机器上。
"The Internet"说Kestrel要快得多,但在我自己的基准测试中,IIS没有明显的区别。而且大多数时候IIS更快。那怎么样?
我在.NET Framework(使用EF)和.NET Core(使用EFCore)上运行“相同”代码。 controller
看起来像这样。它会向DB写一些东西,然后获取它并返回它。我关闭DBContext
以确保没有缓存。下面的.NET Core代码(除了没有DI,.NET Framework的代码类似)。
[Route("api/[controller]")]
public class ValuesController : Controller
{
private readonly DbContextOptions<DemoContext> options;
public ValuesController(DbContextOptionsBuilder<DemoContext> builder)
{
this.options = builder.Options;
}
// GET api/values
[HttpGet]
public async Task<IActionResult> Get()
{
var id = Guid.NewGuid();
using (var context = new DemoContext(options))
{
var newItem = new DemoTable()
{
Id = id,
Stamp = DateTime.Now,
System = "Core"
};
context.DemoTable.Add(newItem);
await context.SaveChangesAsync();
}
using (var context = new DemoContext(options))
{
var item = await context.DemoTable.SingleAsync(x => x.Id == id);
return Ok(item);
}
}
}
我的Program.cs
看起来像这样:
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseKestrel(options =>
{
options.Limits.MaxConcurrentConnections = 1000;
options.Listen(IPAddress.Loopback, 5050);
})
.ConfigureLogging((context, logging) =>
{
logging.ClearProviders();
})
.UseStartup<Startup>()
.Build();
我使用dotnet
dotnet demoApp.dll
运行它。
我使用提出大量请求的应用程序对其进行测试。
var cts = new CancellationTokenSource();
int processed = 0;
int seconds = 30;
var url = new Uri($"http://localhost:{port}");
var tasks = new Task[20];
for (int i = 0; i < tasks.Length; i++)
{
tasks[i] = Task.Factory.StartNew(() =>
{
while (!token.IsCancellationRequested)
{
var client = new RestClient(url);
var request = new RestRequest("/api/values");
client.ExecuteAsyncGet(request, (response, handle) =>
{
if(!token.IsCancellationRequested)
Interlocked.Add(ref processed, 1);
}, "GET");
}
});
}
Thread.Sleep(seconds * 1000);
cts.Cancel();
当我使用IIS运行.NET Framework时,我收到的请求多于我使用Kestrel运行Core时的请求。
我尝试在Kestrel中更改options.Limits
但没有成功。我的假设是我的“基准测试应用程序”出了问题,或者我的本地机器本身就是瓶颈。
为什么IIS比Kestrel更快地处理请求?
更新
如果我删除EF并且仅在控制器中返回OK()
,则IIS仍然表现更好。
在基准测试之前我将服务器唤醒。
我将其构建为Release
。
当我使用10个线程运行30秒时,IIS将处理600个请求和Kestrel 300请求。
gcServer
设置为true
。
答案 0 :(得分:1)
您无法通过将虚拟主机连接到数据库来测试其性能。数据库或您的业务逻辑将成为瓶颈。
从一个干净的项目开始,或者做得更好,但只要抓住基准。为了获得高端性能,很多事情都在起作用。
您正在处理300或600个请求(可怜)的事实暗示了管道中还有其他内容。请注意,您的控制器也在每个请求+您所拥有的任何中间件上注入db上下文。