不能直接扛。YARP默认MaxConnectionsPerServer=2且ThreadPool配置保守,高并发下易现连接拒绝或超时;需调优HttpClientHandler参数、禁用同步IO、限流并发、优化压测环境及启用HTTP/2。

YARP 默认配置能否扛住高并发?
不能直接扛。YARP 本身基于 ASP.NET Core 的 HttpClient 和 HttpProxy 构建,底层复用 HttpClientHandler 连接池和 ThreadPool,但默认的 MaxConnectionsPerServer(默认 2)和 ThreadPool 队列行为会成为瓶颈——尤其在短连接、高 QPS 场景下,你很快会看到 HttpRequestException: Connection refused 或大量 TimeoutException。
必须调优的三个核心 HttpClientHandler 参数
YARP 的转发通道由 ClusterConfig 中的 Destinations 关联到 HttpClient 实例,而该实例的 Handler 才决定连接能力。你需要显式配置 HttpClientHandler 并注入:
-
MaxConnectionsPerServer:建议设为100~500(视后端节点数和单机资源而定),避免连接耗尽 -
MaxRequestContentBufferSize:默认2GB,但大上传会拖慢线程池;如无大文件转发,可设为10 * 1024 * 1024(10MB) -
AutomaticDecompression:设为GZip | Deflate可减少带宽,但增加 CPU;若后端已压缩且代理不改响应体,建议关闭以降低开销
var handler = new HttpClientHandler
{
MaxConnectionsPerServer = 200,
MaxRequestContentBufferSize = 10 * 1024 * 1024,
AutomaticDecompression = DecompressionMethods.None
};避免 ThreadPool 饥饿:禁用同步 IO + 控制并发请求数
YARP 在转发时若遇到阻塞式中间件(如未用 await 的 HttpContext.Request.Body.ReadAsync)、或下游响应极慢,会导致 ThreadPool 工作线程被长期占用。解决方案不是加线程数,而是切断阻塞源头:
- 确保所有自定义中间件使用异步 API(
ReadAsync/WriteAsync),禁用AllowSynchronousIO = true - 在
Program.cs中显式限制并发请求数:用WebHostBuilder.ConfigureKestrel设置LimitMaxConcurrentConnections和LimitMaxConcurrentUpgradedConnections - 对异常慢的下游服务启用
TimeoutPolicy:通过RouteConfig的Timeout属性(单位秒)快速失败,避免线程卡死
真实压测中容易被忽略的点
本地 ab 或 wrk 压测时,Windows 默认的 MaxUserPort(约 65535)和 TCPTimedWaitDelay(240 秒)会让客户端快速耗尽可用端口,表现为大量 Connection reset by peer ——这不是 YARP 的问题,而是发起方的限制。解决方式包括:










