c# YARP (Yet Another Reverse Proxy) 如何处理高并发请求转发

来源:这里教程网 时间:2026-02-21 17:37:16 作者:

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 的问题,而是发起方的限制。解决方式包括:

压测机上修改注册表:
MaxUserPort = 65534
TCPTimedWaitDelay = 30
HttpClient
池替代每次新建实例(YARP 内部已做,但自定义路由策略里别手写 new HttpClient)
检查后端服务是否启用了 HTTP/2(YARP 支持,但需 .NET 6+ + TLS + ALPN),HTTP/2 多路复用能显著降低连接数压力

相关推荐