Exportar (0) Imprimir
Expandir todo
Este tema aún no ha recibido ninguna valoración - Valorar este tema

Real World: Simulating Load on a Windows Azure Application

Actualizado: octubre de 2011

Author: http://msdn.microsoft.com/es-es/library/hh307529.aspx

Imagen de referencia

Learn more about RBA Consulting.

Summary: This article discusses load simulation for web applications that are hosted in Windows Azure. In this article, a simple load test scenario is used.

Windows Azure allows you to host and manage scalable applications in the cloud. The Windows Azure compute service provides different types of roles, such as a web role or a worker role. When these roles are configured with the appropriate size and number of instances, they will be able to handle your application's predicted load. You might use heuristics or formulas to determine the configuration settings for your roles, but you may also need to load test the application to ensure that its configuration is realistic. Additionally, your application may need other tests such as performance and stress tests that require load to be simulated. Applications that run in Windows Azure require a different approach to load simulation than do on-premises applications. This article discusses load simulation for web applications running in Windows Azure.

Load Types

For most web applications, a request is a unit of work. Thus, generating requests will simulate load on your application. There are different types of load that you can apply to your application which relate to the type of test you want to perform. You may want to apply a constant and realistic load on your application to ensure it is able to perform at expected levels. You may also apply an increasing load to stress test your application to the point of failure if you want to determine how it recovers. Alternatively, you can methodically apply well-controlled load scenarios to test the performance of your application. A performance test may uncover system bottlenecks and yield performance benchmarks that can be used in future tests.

In most testing scenarios, your application will require a significant number of parallel requests. You can generate requests from sources that are external from your application, such as on-premises servers and development machines. You should consider that the metrics you gather from tests using external requests can be affected by Internet and network factors, such as latency and bandwidth. If you want your test to not include such factors, you should consider using internal requests instead.

For a Windows Azure application, an internal request is one that is generated from another set of instances from the same data center (also known as a region) that the application to be tested is located at. An internal request requires a minimal number of network hops to reach your application which removes the external latency and bandwidth factors from your test. Using internal requests may also have a cost benefit. In cases where your requests need to originate from many different servers, you can spin up Windows Azure worker roles to generate the requests. When the test is completed, the worker roles are deleted. This is more cost effective than standing up new servers to perform the test.

Denial of Service Attacks and Windows Azure

If you will be generating a large number of requests from external resources, you may be considering the security impact of such requests. You may be worried that Windows Azure will see the requests as a Denial of Service (DoS) or Distributed Denial of Service (DDoS) attack. A DoS or DDoS attack floods servers with requests that can severely degrade their performance, or cause the failures at the server or application level. Indeed, Windows Azure detects such attacks and is handled at the infrastructure or platform level. If you generate a large number of requests for your application, Windows Azure will not detect them as Dos attacks. DoS attacks usually involve malformed requests that specify incorrect source IP addresses, or whose source never acknowledges the packets for such requests. Because the load on your application will be from legitimate requests, Windows Azure will not filter such requests.

Gathering Performance Data

You must collect performance data in order to understand what happens during the load tests. Although your application may be instrumented with its own set of performance counters, Microsoft Windows also offers a helpful set of counters that provide important metrics. The following lists common counters used when performing load, stress and performance tests on an ASP.NET application.

  • \ASP.NET Apps v4.0.30319(__Total__)\Requests/Sec

  • \Processor(_Total)\% Processor Time

  • \Memory\Available Bytes, \Memory\Available Kbytes, \Memory\Available MBytes

The Requests/Sec counter is an application performance counter that measures the number of requests that are executed per second by your application. The throughput of your application will be reflected by the values of this counter. Your business requirements will dictate whether the values from this counter are acceptable or not.

The % Processor Time is a system performance counter that measures processor utilization. This counter indicates how active the processor is. Having high values for it is not necessarily a bad thing. You should consider keeping this value at approximately 85 percent utilization. A utilization level that is too low may indicate that the application is underutilized, or some sort of blocking is occurring, such as database locks. A utilization level above the 85 percent threshold may indicate that your application is overloaded.

The Available Bytes (or Available KBytes, Available MBytes) counters are a system performance counter that measures memory utilization. This counter indicates how much physical memory is available to all processes on the machine. You should maintain values greater than 20 to 25 percent of the RAM. Values lower than 20 (to 25) percent may indicate that an insufficient amount of memory for the machine.

See http://msdn.microsoft.com/en-us/library/fxk122b4.aspx for a complete list of system and application performance counters.

To activate these counters, use the web application's RoleEntryPoint class to configure the DiagnosticMonitor object with the appropriate data sources, and transfer periods. The following code demonstrates how to add the Requests/Sec and % Process Time counters.

public override bool OnStart()
{
    var sampleRate = TimeSpan.FromSeconds(5);
    var counters = new List<string>
    {
        @"\ASP.NET Apps v4.0.30319(__Total__)\Requests/Sec",
        @"\Processor(_Total)\% Processor Time
    };
 
    var configuration = DiagnosticMonitor.GetDefaultInitialConfiguration();
    configuration.PerformanceCounters.ScheduledTransferPeriod = TimeSpan.FromMinutes(5);
    counters.ForEach(counter => configuration.PerformanceCounters.DataSources.Add(
        new PerformanceCounterConfiguration
        {
            CounterSpecifier = counter,
            SampleRate = sampleRate
        })
    );
    DiagnosticMonitor.Start("DiagnosticConnectionString", configuration);
 
    return base.OnStart();
}

Custom Performance Counters

If the default set of Microsoft Windows counters are not enough, it is possible for you to create your own set of counters. However, there is a challenge associated with doing so because role instances are not granted write-access to the Windows Registry which is required for creating new Performance Counters. To circumvent this challenge, you must bootstrap an application that creates the counters using Windows Azure Startup Tasks. The startup task feature is available starting with Windows Azure 1.3 and it allows the application to run under NT AUTHORITY\SYSTEM which has the necessary write-access to the registry.

Creating the Test Web Application

This article will use a simple test web application to perform a load test. A load test is used to verify that the application meets the performance objectives. The performance objective for the test application is to achieve a throughput of 50 requests per second. The test application will also simulate spikes in CPU usage every few seconds so that it may be observed when the performance results are analyzed. To simulate the CPU spike, an un-optimized method for calculating a Fibonacci number is used. The optimized version of the method that caches previous results will not be used.

The test web application will use the ASP.NET MVC platform. This article assumes you are familiar with setting up an ASP.NET MVC project with Visual Studio. The following code shows the modified version of the HomeController class. The Index method is the MVC action that is executed when the base URL of the web application is requested.

public class HomeController : Controller
{
    private static DateTime last = DateTime.Now;
 
    public ActionResult Index()
    {
        if ((DateTime.Now - last).TotalSeconds >= 60)
        {
            last = DateTime.Now;
            for (int i = 0; i < 2; i++)
            {
                ThreadPool.QueueUserWorkItem(state =>
                {
                    ComputeFib(30);
                }, null);
            }
        }
        else
        {
            // Do Nothing
        }
 
        return View();
 
    }
 
    private int ComputeFib(int n)
    {
        if (n < 2)
        {
            return 1;
        }
        else
        {
            return ComputeFib(n - 1) + ComputeFib(n - 2);
        }
    }
}

The HomeController class is designed to spike the CPU every sixty seconds by executing two simultaneous (asynchronous) calls to the ComputeFib method for the Fibonacci number of 30.

Generating the Load

The types of requests that you generate can vary in complexity, depending on the application's requirements. For example, a request can be generated as a simple resource that is downloaded from a single URL, such as the website's landing HTML page. However, in many cases, a web page contains links to other resources such as images, cascading style sheets (CSS) and JavaScript files. On a single machine, the browser usually caches these files, but tests that require parallel requests for Windows Azure applications must simulate requests from many machines on the network. This means that you should download all of the linked resources. More complex requests may also need to examine the HTTP status code that is returned by a page, and handle it the way a browser would, such as redirecting to a page if an HTTP status code of 302 is returned. For example, a test that simulates logon requests may require the following actions to be performed in sequence. Note that the third action, "GET /", is based on the response from the second action returning a redirect to the home page.

  1. GET login.aspx

  2. POST login.aspx

  3. GET /

The following code demonstrates how a simple load test can be written for the test web application discussed in the previous section. The code is written as part of a worker role, which means the test can run from multiple deployed worker roles. The code can also run from a desktop application, such as a console application, by calling the Run method.

public class WorkerRole1 : RoleEntryPoint
{
    public override bool OnStart()
    {
        DiagnosticMonitor.Start("DiagnosticConnectionString");
 
        return base.OnStart();
    }
 
    public override void Run()
    {
        // The URL of the test application
        string baseUrl = "http://<DNS Prefix for test app>.cloudapp.net/";
 
        // Allow the web application to spin up before simulating the load
        Thread.Sleep(5000);
 
        // The number of total requests to execute
        int requests = 5000;
 
        // The remaining number of requests to execute
        int requestsRemaining = requests;
 
        // The number of concurrent requests
        int threads = 50;
 
        var sw = Stopwatch.StartNew();
        string query = "?ticks=" + Environment.TickCount.ToString();
        for (int i = 0; i < threads; i++)
        {
            var thread = new Thread(() =>
            {
                while (Interlocked.Decrement(ref requestsRemaining) > 0)
                {
                    Download(baseUrl, query);
                }
 
            });
            thread.Start();
        }
 
        // Wait until there are no requests left
        while (requestsRemaining > 0)
        {
            Thread.Sleep(100);
        }
 
        sw.Stop();
 
        // Output a rough calculation of rate
        var rate = requests / sw.Elapsed.TotalSeconds;
        Debug.WriteLine("Rate: {0}", rate);
 
        return;
    }
 
    private void Download(string baseUrl, string path)
    {
        var request = (HttpWebRequest)WebRequest.Create(baseUrl + path);
        var response = (HttpWebResponse)request.GetResponse();
 
        if (response.StatusCode == HttpStatusCode.OK)
        {
            using (var stream = response.GetResponseStream())
            {
                using (var r = new StreamReader(stream))
                {
                    string ss = r.ReadToEnd();
                    // Do something with the response
                }
            }
        }
        return;
    }
}

The code above uses 50 threads to simulate as many asynchronous requests to the test web application. When it starts, the load test application will issue 5,000 requests using the allocated threads. The length of time used to issue the requests is captured and used in a rough rate calculation. The rate, in this calculation, reflects the number of asynchronous requests every second that the application achieved.

Analyzing Performance

After the load tests are finished, the next step is to analyze the data. Performance counter data is stored in a Windows Azure table named WADPerformanceCountersData. Of particular interest are the CounterName and CounterValue columns. You may be able to determine how the application reacted to the load tests simply by looking at them. In other cases, you may need to represent the data as graphs. One way to do this is to export the data into an Excel spreadsheet with the Windows Azure Management Tool, which is available at http://wapmmc.codeplex.com/. The rows in the exported data represent the various counters that were collected. To represent the data together, the data needs to be organized to allow the Excel application to graph them. One way to organize them is to use the pivot feature in Excel. You can use the pivot feature to either create a table or a chart. In this example, a chart will be more useful. To create a pivot chart in Excel, follow these procedures:

  1. Click the Insert tab in Excel.



    Pantalla de referencia

  2. Click the PivotTable drop-down button and click the PivotChart menu button.



    Pantalla de referencia

  3. Choose the following options in the PivotTable Field List dialog box. Note that Value must be calculated as an average; therefore, you must click the drop-down menu button next to the Values to modify the field settings.



    Pantalla de referencia

After the pivot chart is created, a graph similar to the following image will be created. In this case, the graph displays that the requests per second is approximately 50. It also shows minimal spikes of the CPU, which is incurred by the calls to the ComputeFib method in the test web application. This indicates that the load test was successful by delivering a throughput of at least 50 requests per second.

Pantalla de referencia

In addition to using the Windows Azure Management Tool and Excel, many third-party tools provide streamlined and automatic visualizations of the data.

Using Remote Desktop

You also have the ability to log into any running instance of your web role by configuring and enabling Remote Desktop for the web role. Connecting to the web role may or may not be of value to you. If you are testing a single instance of the application, then it is viable for you to log into the single instance to examine the performance in real time. However, if you are running multiple instances of the web role, then connecting to a single instance will not provide you with a complete view of your application's performance. In this case, it is better to collect the data into the diagnostic logs, where they are aggregated, and graphing the results.

Summary

Test your Windows Azure applications with load simulation tests to better understand the types of loads your application can handle. Your application must be instrumented with performance counters. The metrics from these counters must be collected and transferred to the WADPerformanceCountersTable table. You can simulate a load for your application if you generate requests for a page, and for any linked resources on that page. The requests may be generated either externally or internally. You should consider which type of requests satisfies the goals of your test, and keeping in mind that bandwidth and latency factors may exists when using external requests. Internal requests can be generated from a Worker role that can be configured for instance size and number of instances. After the simulation is complete, you can download the performance counter data. Use tools such as Microsoft Excel to visualize the data. Its graphing features allow you to compare the various metrics in order to determine the load your application can handle. Third-party tools can also be used to visualize the results of your load test.

¿Te ha resultado útil?
(Caracteres restantes: 1500)
Gracias por sus comentarios
Mostrar:
© 2014 Microsoft. Reservados todos los derechos.