在 Azure 计算模拟器中使用 Visual Studio 探查器来本地测试云服务的性能Testing the Performance of a Cloud Service Locally in the Azure Compute Emulator Using the Visual Studio Profiler

可通过各种工具和技术来测试云服务的性能。A variety of tools and techniques are available for testing the performance of cloud services. 在将云服务发布到 Azure 后,可以让 Visual Studio 收集分析数据,并在本地进行分析,如 分析 Azure 应用程序中所述。When you publish a cloud service to Azure, you can have Visual Studio collect profiling data and then analyze it locally, as described in Profiling an Azure Application. 也可以使用诊断来跟踪各种性能计数器,如 在 Azure 中使用性能计数器中所述。You can also use diagnostics to track a variety of performance counters, as described in Using performance counters in Azure. 此外,在将应用程序部署到云之前,您可能需要在计算模拟器中本地分析应用程序。You might also want to profile your application locally in the compute emulator before deploying it to the cloud.

本文包含了 CPU 采样分析方法,可在模拟器中本地执行该方法。This article covers the CPU Sampling method of profiling, which can be done locally in the emulator. CPU 采样是一种干预性不是很强的分析方法。CPU sampling is a method of profiling that is not very intrusive. 探查器将按照指定的采样时间间隔拍摄调用堆栈的快照。At a designated sampling interval, the profiler takes a snapshot of the call stack. 将收集一段时间内的数据并将其显示在报告中。The data is collected over a period of time, and shown in a report. 此分析方法倾向于指示在具有大量计算的应用程序中执行大多数 CPU 工作的位置。This method of profiling tends to indicate where in a computationally intensive application most of the CPU work is being done. 这使你能够侧重于应用程序在其上花费最多时间的“热路径”。This gives you the opportunity to focus on the "hot path" where your application is spending the most time.

1:配置 Visual Studio 以进行分析1: Configure Visual Studio for profiling

首先,提供了几个 Visual Studio 配置选项,这些选项在分析时可能会有用。First, there are a few Visual Studio configuration options that might be helpful when profiling. 为便于理解分析报表,需要应用程序的符号(.pdb 文件)与系统库的符号。To make sense of the profiling reports, you'll need symbols (.pdb files) for your application and also symbols for system libraries. 需确保引用可用的符号服务器。You'll want to make sure that you reference the available symbol servers. 为此,请在 Visual Studio 中的“工具”菜单上,依次选择“选项”、“调试”和“符号”。To do this, on the Tools menu in Visual Studio, choose Options, then choose Debugging, then Symbols. 确保“符号文件(.pdb)位置”下方列出了 Microsoft 符号服务器。Make sure that Microsoft Symbol Servers is listed under Symbol file (.pdb) locations. 还可以引用 http://referencesource.microsoft.com/symbols,它可能具有附加的符号文件。You can also reference http://referencesource.microsoft.com/symbols, which might have additional symbol files.

“符号”选项

如果需要,可通过设置“仅我的代码”来简化探查器生成的报告。If desired, you can simplify the reports that the profiler generates by setting Just My Code. 通过启用“仅我的代码”,可简化函数调用堆栈,以便从报告中隐藏对库和 .NET Framework 的完全内部调用。With Just My Code enabled, function call stacks are simplified so that calls entirely internal to libraries and the .NET Framework are hidden from the reports. 在“工具”菜单上,选择“选项”。On the Tools menu, choose Options. 然后展开“性能工具”节点,并选择“常规”。Then expand the Performance Tools node, and choose General. 选中“为探查器报告启用‘仅我的代码’”的复选框 。Select the checkbox for Enable Just My Code for profiler reports.

“仅我的代码”选项

可以在现有项目或新项目中使用这些说明。You can use these instructions with an existing project or with a new project. 如果创建新项目的目的是尝试下面描述的技术,请选择 C# Azure 云服务项目,并选择“Web 角色”和“辅助角色”。If you create a new project to try the techniques described below, choose a C# Azure Cloud Service project, and select a Web Role and a Worker Role.

Azure 云服务项目角色

为了进行演示,请将一些代码添加到项目中,这些代码将占用大量时间,从而演示某个明显的性能问题。For example purposes, add some code to your project that takes a lot of time and demonstrates some obvious performance problem. 例如,将以下代码添加到辅助角色项目:For example, add the following code to a worker role project:

public class Concatenator
{
    public static string Concatenate(int number)
    {
        int count;
        string s = "";
        for (count = 0; count < number; count++)
        {
            s += "\n" + count.ToString();
        }
        return s;
    }
}

在辅助角色的 RoleEntryPoint-derived 类中从 RunAsync 方法调用此代码。Call this code from the RunAsync method in the worker role's RoleEntryPoint-derived class. (忽略有关以同步方式运行方法的警告。)(Ignore the warning about the method running synchronously.)

private async Task RunAsync(CancellationToken cancellationToken)
{
    // TODO: Replace the following with your own logic.
    while (!cancellationToken.IsCancellationRequested)
    {
        Trace.TraceInformation("Working");
        Concatenator.Concatenate(10000);
    }
}

本地生成并运行云服务且不进行调试 (Ctrl+F5),并将解决方案配置设置为“发布”。Build and run your cloud service locally without debugging (Ctrl+F5), with the solution configuration set to Release. 这会确保创建的所有文件和文件夹都用于本地运行应用程序,并确保启动所有仿真程序。This ensures that all files and folders are created for running the application locally, and ensures that all the emulators are started. 从任务栏启动计算模拟器 UI,以验证辅助角色是否正在运行。Start the Compute Emulator UI from the taskbar to verify that your worker role is running.

2:附加到进程2: Attach to a process

必须将探查器附加到正在运行的进程,而不是通过从 Visual Studio 2010 IDE 中启动应用程序来分析该应用程序。Instead of profiling the application by starting it from the Visual Studio 2010 IDE, you must attach the profiler to a running process.

若要将探查器附加到进程,请在“分析”菜单上选择“探查器”和“附加/分离”。To attach the profiler to a process, on the Analyze menu, choose Profiler and Attach/Detach.

“附加配置文件”选项

对于辅助角色,请查找 WaWorkerHost.exe 进程。For a worker role, find the WaWorkerHost.exe process.

WaWorkerHost 进程

如果项目文件夹位于网络驱动器上,则探查器会要求你提供其他位置来保存分析报告。If your project folder is on a network drive, the profiler will ask you to provide another location to save the profiling reports.

也可以通过附加到 WaIISHost.exe 来附加到 Web 角色。You can also attach to a web role by attaching to WaIISHost.exe. 如果应用程序中有多个辅助角色进程,则需要使用 processID 将它们区分开来。If there are multiple worker role processes in your application, you need to use the processID to distinguish them. 可以通过访问 Process 对象以编程方式查询 processID。You can query the processID programmatically by accessing the Process object. 例如,如果将此代码添加到角色中 RoleEntryPoint 派生的类的 Run 方法,则可在计算模拟器 UI 中查看日志以了解要连接到的进程。For example, if you add this code to the Run method of the RoleEntryPoint-derived class in a role, you can look at the log in the Compute Emulator UI to know what process to connect to.

var process = System.Diagnostics.Process.GetCurrentProcess();
var message = String.Format("Process ID: {0}", process.Id);
Trace.WriteLine(message, "Information");

若要查看日志,请启动计算模拟器 UI。To view the log, start the Compute Emulator UI.

启动计算模拟器 UI

通过单击控制台窗口的标题栏,在计算模拟器 UI 中打开辅助角色日志控制台窗口。Open the worker role log console window in the Compute Emulator UI by clicking on the console window's title bar. 可以在日志中查看进程 ID。You can see the process ID in the log.

查看进程 ID

完成附加后,请在应用程序的 UI 中执行这些步骤(如果需要),重现该方案。One you've attached, perform the steps in your application's UI (if needed) to reproduce the scenario.

如果想要停止分析,请选择“停止分析”链接 。When you want to stop profiling, choose the Stop Profiling link.

“停止探查”选项

3:查看性能报告3: View performance reports

这会显示应用程序的性能报告。The performance report for your application is displayed.

此时,探查器将停止执行,将数据保存到 .vsp 文件中,并显示一个展示对此数据的分析的报告。At this point, the profiler stops executing, saves data in a .vsp file, and displays a report that shows an analysis of this data.

探查器报告

如果你在热路径中看到 String.wstrcpy,请单击“仅我的代码”以将视图更改为仅显示用户代码。If you see String.wstrcpy in the Hot Path, click on Just My Code to change the view to show user code only. 如果看到 String.Concat,请尝试按“显示所有代码”按钮。If you see String.Concat, try pressing the Show All Code button.

您会看到占用大部分执行时间的 Concatenate 方法和 String.Concat。You should see the Concatenate method and String.Concat taking up a large portion of the execution time.

报告分析

如果添加了本文中的字符串串联代码,则此代码的任务列表中会显示一个警告。If you added the string concatenation code in this article, you should see a warning in the Task List for this. 此外,还可能会显示一条警告,指示存在大量垃圾回收,这是由于创建和释放了大量字符串导致的。You may also see a warning that there is an excessive amount of garbage collection, which is due to the number of strings that are created and disposed.

性能警告

4:进行更改并比较性能4: Make changes and compare performance

也可在代码更改之前或之后比较性能。You can also compare the performance before and after a code change. 停止正在运行的进程,并编辑代码以将字符串串联操作替换为使用 StringBuilder:Stop the running process, and edit the code to replace the string concatenation operation with the use of StringBuilder:

public static string Concatenate(int number)
{
    int count;
    System.Text.StringBuilder builder = new System.Text.StringBuilder("");
    for (count = 0; count < number; count++)
    {
         builder.Append("\n" + count.ToString());
    }
    return builder.ToString();
}

执行其他性能运行,并比较性能。Do another performance run, and then compare the performance. 在性能资源管理器中,如果运行位于同一会话中,则只需选择两个报告,打开快捷菜单,并选择“比较性能报告” 。In the Performance Explorer, if the runs are in the same session, you can just select both reports, open the shortcut menu, and choose Compare Performance Reports. 若要与其他性能会话中的运行进行比较,请打开“分析”菜单,并选择“比较性能报表”。If you want to compare with a run in another performance session, open the Analyze menu, and choose Compare Performance Reports. 在显示的对话框中指定这两个文件。Specify both files in the dialog box that appears.

“比较性能报告”选项

报告将突出显示两个运行之间的差异。The reports highlight differences between the two runs.

比较报告

祝贺!Congratulations! 已开始使用探查器。You've gotten started with the profiler.

故障排除Troubleshooting

  • 请确保正在分析 Release 生成,并在不调试的情况下启动。Make sure you are profiling a Release build and start without debugging.

  • 如果未在“探查器”菜单上启用“附加/分离”选项,请运行性能向导。If the Attach/Detach option is not enabled on the Profiler menu, run the Performance Wizard.

  • 使用计算模拟器 UI 来查看应用程序的状态。Use the Compute Emulator UI to view the status of your application.

  • 如果在模拟器中启动应用程序时或附加探查器时出现问题,请关闭并重新启动计算模拟器。If you have problems starting applications in the emulator, or attaching the profiler, shut down the compute emulator and restart it. 如果这样做无法解决问题,请尝试重新启动。If that doesn't solve the problem, try rebooting. 如果使用计算模拟器挂起或删除正在运行的部署,则会出现此问题。This problem can occur if you use the Compute Emulator to suspend and remove running deployments.

  • 如果已从命令行使用任一分析命令(尤其是全局设置),请确保已调用 VSPerfClrEnv /globaloff 并已关闭 VsPerfMon.exe。If you have used any of the profiling commands from the command line, especially the global settings, make sure that VSPerfClrEnv /globaloff has been called and that VsPerfMon.exe has been shut down.

  • 如果采样时显示了消息“PRF0025: 未收集数据”,请检查附加的进程是否有 CPU 活动。If when sampling, you see the message "PRF0025: No data was collected," check that the process you attached to has CPU activity. 未执行任何计算工作的应用程序无法生成任何采样数据。Applications that are not doing any computational work might not produce any sampling data. 此外,在执行任何采样前可能会退出进程。It's also possible that the process exited before any sampling was done. 查看以验证正在分析的角色的 Run 方法是否已终止。Check to see that the Run method for a role that you are profiling does not terminate.

后续步骤Next Steps

Visual Studio 探查器不支持在模拟器中检测 Azure 二进制文件,但要测试内存分配,可以在分析时选择该选项。Instrumenting Azure binaries in the emulator is not supported in the Visual Studio profiler, but if you want to test memory allocation, you can choose that option when profiling. 此外,可以选择并发分析,这有助于确定线程是否正在浪费时间竞争锁;也可以选择层交互分析,这有助于跟踪在应用程序的各个层之间(最常见的是数据层和辅助角色之间)进行交互时的性能问题。You can also choose concurrency profiling, which helps you determine whether threads are wasting time competing for locks, or tier interaction profiling, which helps you track down performance problems when interacting between tiers of an application, most frequently between the data tier and a worker role. 可以查看应用程序生成的数据库查询并使用分析数据来改进对数据库的使用。You can view the database queries that your app generates and use the profiling data to improve your use of the database. 有关层交互分析的信息,请参阅博客文章 演练:在 Visual Studio Team System 2010 中使用层交互探查器For information about tier interaction profiling, see the blog post Walkthrough: Using the Tier Interaction Profiler in Visual Studio Team System 2010.