You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用YARP的IHttpForwarder转发请求速度过慢的优化求助

优化YARP IHttpForwarder转发耗时的建议

从你的遥测日志和代码来看,耗时主要集中在两个阶段:YARP向目标服务器发送请求并接收响应头(约224ms),以及读取目标服务器响应内容(约204ms),结合Postman的基准耗时,给出以下具体优化方案:

1. 复用HttpMessageInvoker与SocketsHttpHandler

你当前在Controller构造函数中每次创建新的HttpMessageInvoker和SocketsHttpHandler,这会导致每次请求都重新建立TCP连接,完全浪费了连接池的优势。正确的做法是将HttpMessageInvoker注册为单例,让所有请求复用同一个连接池:

// 在Program.cs中注册
builder.Services.AddSingleton<HttpMessageInvoker>(sp =>
{
    return new HttpMessageInvoker(new SocketsHttpHandler()
    {
        UseProxy = false,
        AllowAutoRedirect = false,
        AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate,
        UseCookies = false,
        ActivityHeadersPropagator = new ReverseProxyPropagator(DistributedContextPropagator.Current),
        // 连接池优化配置
        MaxConnectionsPerServer = 100,
        PooledConnectionLifetime = TimeSpan.FromMinutes(5),
        PooledConnectionIdleTimeout = TimeSpan.FromMinutes(2),
        EnableHttp2 = true
    });
});

// 在Controller中注入
public TestController(IHttpForwarder forwarder, HttpMessageInvoker httpClient)
{
    _forwarder = forwarder;
    _httpClient = httpClient;
    _transformer = new CustomTransformer();
    _requestOptions = new ForwarderRequestConfig { ActivityTimeout = TimeSpan.FromSeconds(100) };
}

2. 开启自动解压减少响应体积

你的SocketsHttpHandler设置了AutomaticDecompression = DecompressionMethods.None,如果目标服务器返回的是压缩内容(如Gzip),YARP会读取原始的大体积内容,增加读取耗时。Postman默认会自动处理解压,所以这部分差异会直接体现在耗时上。建议开启自动解压:

AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate

同时确保请求头中包含Accept-Encoding: gzip, deflate,可以在CustomTransformer中添加:

public override ValueTask TransformRequestAsync(HttpContext context, HttpRequestMessage proxyRequest, string destinationPrefix)
{
    proxyRequest.Headers.AcceptEncoding.ParseAdd("gzip, deflate");
    return base.TransformRequestAsync(context, proxyRequest, destinationPrefix);
}

3. 优化响应内容传输逻辑

从日志看,响应内容有510KB,Read time: 0.204秒是YARP从目标服务器读取内容的时间。可以调整YARP的响应缓冲区大小,减少IO操作次数:

在注册YARP时配置HttpForwarderOptions:

builder.Services.AddHttpForwarder(options =>
{
    options.ResponseBodyBufferSize = 65536; // 64KB缓冲区,默认可能更小
});

另外,如果你的CustomTransformer没有修改响应内容的需求,可以直接跳过额外的内容处理,让YARP直接转发响应流,避免内存拷贝开销。

4. 排查CustomTransformer的额外开销

如果你的CustomTransformer中实现了复杂的请求/响应转换逻辑(比如修改Body、遍历并修改大量Headers),会增加额外的耗时。可以暂时替换为默认的Transformer测试:

// 替换为默认Transformer
_transformer = new Transformer();

如果耗时明显下降,再逐一排查Transformer中的代码是否有可以优化的地方。

5. 强制使用HTTP/2

Postman通常默认支持HTTP/2,而SocketsHttpHandler默认可能会协商使用HTTP/1.1。强制开启HTTP/2可以利用多路复用特性,减少连接建立的开销:

new SocketsHttpHandler()
{
    // 其他配置
    EnableHttp2 = true
}

内容的提问来源于stack exchange,提问作者HC1122

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 08:42:15