We are experiencing issues with high load on our dotnet-core (3.1) application.
Beyond a certain amount of connection (virtual users), we encouter a bottleneck, the server is starved and we get request timeout but the process doesn't crash (no kestrel logs). We are using K6 to benchmark our app. For now the load test only performs GET requests on the login page which trigger one basic SQL request on a small dataset (no join, etc).
We used Visual Studio 2019 Perfomance Profiler tool and perfview to investigate the issue, but none of these tools helped us to identify the portion of code that caused this bottleneck.
I found this article about ThreadPool starvation : https://learn.microsoft.com/fr-fr/archive/blogs/vancem/diagnosing-net-core-threadpool-starvation-with-perfview-why-my-service-is-not-saturating-all-cores-or-seems-to-stall When we tweak the minimum ThreadPool with arbitrary values as the example after, we've got a huge improvement in performance (not on the graph). This seems like a stop gap, how bad is it to use it ?
System.Threading.ThreadPool.SetMinThreads(200, 200);
Explanation : 2C_2G/100.csv => 2 cores, 2Go RAM, 100 virtual users
Environment:
- nginx as reverse proxy
- K6 as benchmark tool
- dotnet-core 3.1 (with EntityFramework)
- operating system : Ubuntu 20.04
- mariadb as database
async
and Tasks. Without code we cannot help further. – Hoon