Kestrel搭配IIS反向代理时HttpClient调用缓慢问题咨询
IIS反向代理下ASP.NET Core WebApi请求延迟的原因与解决方案
这种场景我之前排查过好几次,直接跑Kestrel快但过IIS代理就慢2-3秒,大概率是代理环境下的连接复用、配置限制或者DNS解析的问题,咱们一步步来解决:
可能的原因分析
- HttpClient实例化方式不合理:你代码里每次请求都
new HttpClient+using,虽然语法没问题,但直接Kestrel时连接池复用效率高,而IIS的进程模型会导致连接池频繁重建,每次请求都要重新TCP握手,耗时剧增。 - IIS ARR代理的默认缓冲设置:ARR(Application Request Routing)默认会开启请求缓冲,也就是等后端请求完全接收后再转发给客户端,这会额外增加等待时间。
- IIS的出站连接限制:Windows和IIS默认对出站HTTP连接的并发数有保守限制,当请求量上来或者连接复用差时,会出现排队等待的情况。
- DNS解析延迟:IIS运行在系统服务环境下,可能没有启用DNS缓存,每次请求都要重新解析
google.ca的IP,这在网络环境一般的情况下会占不少时间。
针对性解决方案
1. 重构HttpClient的使用(最优先尝试)
不要每次请求都创建新的HttpClient,改用单例或者依赖注入的方式复用连接池:
// 在Startup.cs的ConfigureServices中注册单例HttpClient public void ConfigureServices(IServiceCollection services) { services.AddMvc(); // 注册单例HttpClient,并预先设置BaseAddress services.AddSingleton<HttpClient>(sp => { var client = new HttpClient(); client.BaseAddress = new Uri("http://www.google.ca"); return client; }); } // 在Controller中注入使用 public class YourApiController : Controller { private readonly HttpClient _httpClient; public YourApiController(HttpClient httpClient) { _httpClient = httpClient; } [HttpGet] public async Task<IActionResult> YourRoute() { HttpResponseMessage response = await _httpClient.GetAsync("/search?q=test&oq=test"); return Ok(); } }
这样可以复用TCP连接,避免每次请求都握手,这一步基本能解决大部分延迟问题。
2. 调整IIS ARR代理配置
打开IIS管理器,找到你的站点对应的ARR代理规则:
- 进入「代理设置」,关闭启用请求缓冲,让IIS实时转发响应,不用等完整接收。
- 调整超时设置,把连接超时、响应超时缩短到合理范围(比如10秒以内,和直接Kestrel的请求时间匹配)。
- 若适合你的业务场景,可开启内核模式缓存,减少重复请求的处理时间。
3. 提升IIS出站连接限制
修改Windows注册表来放宽连接限制:
- 打开注册表编辑器,定位到
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HTTP\Parameters - 添加两个DWORD值:
MaxConnectionsPerServer:设置为1000(根据你的并发需求调整)MaxConnectionsPer1_0Server:同样设置为1000(兼容HTTP 1.0)
- 执行命令
iisreset重启IIS服务生效。
4. 配置DNS缓存
给HttpClient设置DNS缓存超时,避免重复解析域名:
var handler = new HttpClientHandler { DnsRefreshTimeout = TimeSpan.FromMinutes(10) // 10分钟内复用DNS解析结果 }; var client = new HttpClient(handler) { BaseAddress = new Uri("http://www.google.ca") };
如果是用依赖注入,把这段逻辑放到Startup的注册代码里即可。
5. 优化应用池设置
- 确保应用池的托管管道模式为「集成模式」,ASP.NET Core在集成模式下的代理兼容性更好。
- 调整应用池的最大工作进程数(根据服务器核心数设置,比如4核设为4),避免进程阻塞导致请求排队。
验证步骤
先尝试重构HttpClient的使用方式,这是改动最小、见效最快的方案。如果延迟依然存在,再依次调整ARR配置、连接限制和DNS缓存设置,每调整一项就测试一次请求耗时,直到找到问题根源。
内容的提问来源于stack exchange,提问作者user875318
相关产品推荐
相关产品推荐

