简体   繁体   English

Azure ASP.NET WebAPI性能

[英]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. 在尝试调查现实生活项目中的问题时,我试图获得一些在Azure Web应用程序中托管的ASP.NET WebAPI性能的见解。 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: 作为第一步,我使用默认模板在Visual Studio中创建了一个ASP.NET WebAPI项目,该模板包含以下虚拟控制器:

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: 我将API部署到D1 Azure Web应用程序:

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. 这个小小的压力测试在10秒的时间范围内发送了1000个请求,鉴于相对简单的控制器方法,这对我来说似乎并不多。

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. 使用WebClient而不是RestSharp也不会更改结果。

The network traffic is marginal at around 2.5 kB/s according to Resource Monitor. 根据资源监视器,网络流量约为2.5 kB / s。

The response time when sending requests in large intervals (>1000ms) is around 270ms which is an order of magnitude I regard as reasonable. 以大间隔(> 1000ms)发送请求的响应时间约为270ms,这是我认为合理的一个数量级。

My questions: 我的问题:

  • Why is this so slow?? 为什么这么慢? How hard can it be to return { "value1", "value2" } 1000 times? 返回{ "value1", "value2" } 1000次有多难?
  • 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? 返回{“value1”,“value2”} 1000次有多难?

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. 线程池依赖于CPU,如果您有比线程池更多的请求,那么它就会排队。您正在进行的测试取决于CPU,因为您使用的是Test / Dev基础架构,所以需要扩展您的实例。 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. 除非您过度配置实例并对请求进行负载平衡,否则Azure Web应用程序不适用于峰值。 If you know that you would get spikes at times , then you need to look into serverless or Kubernetes with virtual nodes. 如果您知道有时会出现峰值,那么您需要使用虚拟节点查看无服务器或Kubernetes。 Else you have to over provision azure web apps. 否则你必须过度配置azure web应用程序。

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. JMeter在测试方面很不错。 You can also look into Azure web app load test. 您还可以查看Azure Web应用程序负载测试。 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 ASP.NET线程

Recommendations 建议

If you are going with green field project you should definitely look into asp.net core. 如果你要参加绿色领域项目,你一定要看看asp.net核心。 According to independent bench mark providers asp.net core is one of the highest performer frame works. 根据独立基准测试提供商,asp.net核心是表现最好的框架之一。 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. 做不同的测试组合,例如选择不同的OS,不同的asp.net版本,不同的区域来提出具体的结果。

techempower benchmark techempower基准

ASP.NET CORE test ASP.NET CORE测试

Hope that helps ! 希望有所帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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