简体   繁体   中英

Azure ASP.NET WebAPI performance

While trying to investigate a problem in a real life project I am trying to gain some insights in the performance of ASP.NET WebAPI hosted in an Azure web app. As a first step, I have created an ASP.NET WebAPI project in Visual Studio using the default template, which contains, among others, the following dummy controller:

public class ValuesController : ApiController
{
    // GET api/values
    public IEnumerable<string> Get()
    {
        return new string[] { "value1", "value2" };
    }

    // ...
}

I deployed the API to a D1 Azure web app:

Shared infrastructure 
1 GB memory 
240 minutes/day compute

Then, I implemented a simple, quick and dirty client console app:

var client = new RestClient("https://foo.azurewebsites.net/api/");
var request = new RestRequest("values", Method.GET);

var callsToExecute = 1000;
var totalElapsed = .0;
var responseCount = 0;

var totalSw = new Stopwatch();
totalSw.Start();

for (var i = 0; i < callsToExecute; i++)
{
    var sw = new Stopwatch();
    sw.Start();
    client.ExecuteAsync(request, (r, h) => {
        sw.Stop();
        totalElapsed += sw.ElapsedMilliseconds;
        responseCount++;
        if (responseCount == callsToExecute) totalSw.Stop();
    });

    Thread.Sleep(10);
}

while(responseCount < callsToExecute)
{
    Thread.Sleep(1000);
}

System.Console.WriteLine("Average time to response: " + totalElapsed / callsToExecute);
System.Console.WriteLine("Total duration: " + totalSw.ElapsedMilliseconds);
System.Console.ReadLine();

This little stress test sends 1000 requests in a timerange of 10 seconds, which doesn't seem that much to me, given the comparably simple controller method.

The result is:

Average time to response: 5065.38 ms
Total duration: 23028 ms

I've also tried a version making the controller method async, which doesn't change the results. Using WebClient instead of RestSharp doesn't change the results either.

The network traffic is marginal at around 2.5 kB/s according to Resource Monitor.

The response time when sending requests in large intervals (>1000ms) is around 270ms which is an order of magnitude I regard as reasonable.

My questions:

  • Why is this so slow?? How hard can it be to return { "value1", "value2" } 1000 times?
  • Does this performance fall within the expected range given the scenario?
  • Is there some kind of bug in my client app?
  • If this is expected behavior: What are the approximate call rate limits given the scenario?

Why is this so slow?? How hard can it be to return { "value1", "value2" } 1000 times?

The kind of test you are performing is a spike or burst test. Regardless of what controller returns there is limit to how many request a particular server can handle based on thread pool. Thread pool depends on CPU , If you have more requests than thread pool can handle then it get queued.The test you are doing depends on CPU and since you are using Test/Dev infrastructure you need to scale up your instance. After certain limits your requests are getting queued up.

Does this performance fall within the expected range given the scenario?

I believe yes. Like i said you are doing request burst with very short ramp up. Azure web apps is not ideal for spikes unless you over provision the instances and load balance the requests. If you know that you would get spikes at times , then you need to look into serverless or Kubernetes with virtual nodes. Else you have to over provision azure web apps.

Is there some kind of bug in my client app?

you can use professional tools for better results gathering. eg turn on Application insight and get the actual insight of server performance. JMeter is decent in terms of testing. You can also look into Azure web app load test. The reason i am suggesting is you get another perspective to look into how server is handling the request and why it would take this much time.

Load Test

Application insight

If this is expected behavior: What are the approximate call rate limits given the scenario?

App pool limits

ASP.NET Threads

Recommendations

If you are going with green field project you should definitely look into asp.net core. According to independent bench mark providers asp.net core is one of the highest performer frame works. It's always a balance of best practices , infrastructure and technical stack we are using. Based on one test we can't determine the performance when we ignore underlined limitations. Do different combinatiosn of testing eg choose different OS , Different asp.net version , Different region to come up with concrete results.

techempower benchmark

ASP.NET CORE test

Hope that helps !

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM