microsoft / reverse-proxy

A toolkit for developing high-performance HTTP reverse proxy applications.
https://microsoft.github.io/reverse-proxy
MIT License
8.27k stars 812 forks source link

Memory surge during load testing #2527

Open jinzaz opened 2 weeks ago

jinzaz commented 2 weeks ago

Describe the bug

When I created an empty Web API Project and only added the reverse proxy service, and then used JMeter for load testing, I found a surge in memory. Below was the stack information monitored using dotnet dump and dotnet counters. I suspected that Jeeter was using keep-alive, but I added the app UseRequestTimeouts(); There will still be these phenomena, and I don't know what causes them screenshot-20240621-232017 screenshot-20240621-231923

Further technical details

MihaZupan commented 1 week ago

Was the memory dump screenshot you shared taken after all the requests already completed?

Also just in case, can you share how you're using YARP (e.g. config file) / whether and how you're using the IHttpForwarder directly.

jinzaz commented 1 week ago

yeah this dump was after all the requests already completed!,this is my YARP config

  "ReverseProxy": {
    "Routes": {
      "basic-apiservice": {
        "Match": {
          "Methods": null,
          "Hosts": null,
          "Path": "/xxx/xxxx/{**catch-all}",
          "QueryParameters": null,
          "Headers": null
        },
        "ClusterId": "basic-apiservice",
        "AuthorizationPolicy": null,
        "RateLimiterPolicy": null,
        "Timeout": "00:00:20",
        "CorsPolicy": null,
        "Metadata": null,
        "Transforms": [
          {
            "PathRemovePrefix": "/xxxx/xxxx"
          }
        ]
      }
    },
    "Clusters": {
      "basic-apiservice": {
        "LoadBalancingPolicy": null,
        "SessionAffinity": null,
        "HealthCheck": null,
        "HttpClient": {
          "EnableMultipleHttp2Connections": true
        },
        "HttpRequest": {
          "AllowResponseBuffering": "false"
        },
        "Destinations": {
          "basic-apiservice/destination1": {
            "Address": "http://xxxx",
            "Health": "http://xxxxxx",
            "Metadata": null,
            "Host": null
          }
        },
        "Metadata": null
      }
    }
  }

I seem to have found a solution, I seem to have found the cause of the problem, partly due to the PinnedBlockMemoryPool in aspnetcore when the container memory is not restricted. This is similar to this problem ,https://github.com/dotnet/aspnetcore/issues/24958 and partly due to the low execution frequency of GC Server Mode in GC mode,But now I'm solving it by using GarbageCollectionAdaptationMode

jinzaz commented 1 week ago

But I found that YARP's CPU usage is very high, and I'm not sure if this is normal, or can you recommend optimization methods