IIS与Kestrel差异解析:高并发下为何Kestrel断连IIS正常?
问题分析:Kestrel vs IIS 高并发连接差异
我有两个项目:一个控制台应用和一个API。控制台应用向API项目并发发送100,000次请求。
- 当API运行在Kestrel上时,数秒后控制台应用出现如下错误:
System.Net.Http.HttpRequestException:
An error occurred while sending the request.System.IO.IOException:
Unable to write data to the transport connection: An established connection was aborted by the software in your host machine..System.Net.Sockets.SocketException (10053):
An established connection was aborted by the software in your host machine
- 但当API运行在IIS上时,控制台应用可发送所有请求且无异常。
控制台应用代码
var services = new ServiceCollection(); services.AddHttpClient("Test", options => { options.BaseAddress = new Uri("http://127.0.0.1:34399"); options.Timeout = TimeSpan.FromMinutes(5); }) .RemoveAllLoggers(); var builder = services.BuildServiceProvider(); var httpClientFactory = builder.GetRequiredService<IHttpClientFactory>(); List<Task> tasks = new List<Task>(); for (int i = 0; i < 100_000; i++) { tasks.Add(CallApi(httpClientFactory)); } await Task.WhenAll(tasks); static async Task CallApi(IHttpClientFactory httpClientFactory) { try { var client = httpClientFactory.CreateClient("Test"); await client.GetAsync("/WeatherForecast"); } catch (Exception ex) { Console.WriteLine(ex); throw; } }
API项目代码
private static readonly string[] Summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }; [HttpGet(Name = "GetWeatherForecast")] public async Task<IEnumerable<WeatherForecast>> Get() { await Task.Delay(10); return Enumerable.Range(1, 5).Select(index => new WeatherForecast { Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)), TemperatureC = Random.Shared.Next(-20, 55), Summary = Summaries[Random.Shared.Next(Summaries.Length)] }) .ToArray(); }
核心差异与原因分析
IIS具备的Kestrel没有的关键机制
- 底层连接处理依赖HTTP.sys:IIS基于Windows系统的HTTP.sys驱动管理连接,HTTP.sys会维护大容量的待处理连接队列,能缓冲瞬间涌入的高并发请求,避免直接拒绝新连接;Kestrel作为用户态服务器,默认连接队列长度有限。
- 系统级TCP优化:HTTP.sys集成了Windows原生的TCP优化策略,包括动态调整TCP窗口、智能连接超时管理等,能更高效地分配连接资源;Kestrel默认配置无此类系统级优化支持。
- 多进程负载调度:IIS通过应用池实现进程隔离,可自动调整工作进程数量分摊负载,还能借助Windows资源监控机制动态分配CPU、内存;Kestrel默认单进程运行,未手动配置时易出现资源耗尽。
为何Kestrel拒绝连接而IIS不会
- 连接队列容量限制:Kestrel默认
ListenOptions.Backlog(待处理连接队列长度)仅为100左右,10万并发请求瞬间涌入时,大量请求无法进入队列,直接被TCP层中止,抛出10053错误;而HTTP.sys默认队列长度远大于此,能容纳更多待处理连接。 - 线程池资源瓶颈:Kestrel请求处理依赖.NET线程池,短时间高并发会耗尽可用线程,后续请求无法被处理,连接因资源不足超时中止;HTTP.sys会先接管连接,再逐步将请求分发给工作进程,缓解了线程池的瞬间压力。
- 默认配置的场景偏向:Kestrel默认配置针对轻量、中等并发场景优化,而IIS作为企业级服务器,默认配置就适配高并发场景,无需额外调整即可应对大规模请求。
内容的提问来源于stack exchange,提问作者Farhad Zamani
相关产品推荐
相关产品推荐

