Search code examples
c#.netms-yarp

Requests using YARP are much slower


I'm making API calls using Postman to some endpoint (e.g. https://example.com/api) and it takes between 150-200ms to get a response.

I'm trying to use IHttpForwarder from YARP 2.0. and suddenly my requests start to take 400-700ms to get a response. I added some events logging based on diagnosing YARP-based proxies and those are the results:

Forwarder Telemetry [13:30:40.534] => OnForwarderStage :: Stage: SendAsyncStart
Forwarder Telemetry [13:30:40.758] => OnForwarderStage :: Stage: SendAsyncStop
Forwarder Telemetry [13:30:40.966] => OnContentTransferred :: Content length: 510127, IOps: 24, Read time: 0.204, Write time: 0.003

Any idea how to fast those things up? Here is my code, which is more or less the same as in their documentation:

[ApiController]
[Route("/test")]
public class TestController : ControllerBase
{
    private readonly IHttpForwarder _forwarder;

    private readonly CustomTransformer _transformer;
    private readonly HttpMessageInvoker _httpClient;
    private readonly ForwarderRequestConfig _requestOptions;

    public TestController(IHttpForwarder forwarder)
    {
        _forwarder = forwarder;

        // Setup our own request transform class
        _transformer = new CustomTransformer();

        // Configure our own HttpMessageInvoker for outbound calls for proxy operations
        _httpClient = new HttpMessageInvoker(new SocketsHttpHandler()
        {
            UseProxy = false,
            AllowAutoRedirect = false,
            AutomaticDecompression = DecompressionMethods.None,
            UseCookies = false,
            ActivityHeadersPropagator = new ReverseProxyPropagator(DistributedContextPropagator.Current)
        });

        // Initialize the ForwarderRequestConfig
        _requestOptions = new ForwarderRequestConfig { ActivityTimeout = TimeSpan.FromSeconds(100) };
    }

    [HttpGet]
    [Route("{**catch-all}")]
    public async Task IndexAsync()
    {
        var error = await _forwarder.SendAsync(HttpContext, "https://example.com/api/", _httpClient, _requestOptions, _transformer);
    }
}

I have tried disabling TLS/SSL certificate check, and adding some PooledConnectionLifetime to SocketsHttpHandler but without success.

Thanks for help!


Solution

  • Avoid creating the HttpClient in the controller constructor. You want to do that once instead of per incoming request. Instead, register it as a singleton and pass it into the forwarder.