我正在监视Azure服务的性能。

当前有两个Web角色实例(用于同一网站)正在运行-每个实例都有其自己的W3WP.exe(w3wp和w3wp#1)

我如何找出哪个w3wp进程属于哪个角色实例?

有了这些信息,我想为azure.diagnostics.monitor提供一些性能计数器-即Process(w3wp)\ProcessorTime(%)和Thread Count。
但是为了获取任何有意义的数据,我必须将w3wp进程的进程ID附加到性能计数器(例如Process(w3wp_PID)\processorTime(%))-不知道语法是否正确,但是有一种方法可以附加PID)

因此,AzureStorage表WADPerformanceCounters中的最终结果仅具有以下条目:

WebRoleInstance_n_0 | process(w3wp_1033)\processorTime (%) |  12.4
WebRoleInstance_n_1 | process(w3wp_1055)\processorTime (%) |  48.4

atm就像
WebRoleInstance_n_0 | process(w3wp)\processorTime (%) |  12.4
WebRoleInstance_n_1 | process(w3wp)\processorTime (%) |  12.4

我认为:如果我为每个角色启动DiagnosticsMonitor,则该监视器将使用正确的进程-属于启动该监视器的Roleinstance。但实际上这不起作用-或至少在查看结果值后,我认为它不起作用。

//update:在manage.windowsazure门户上,您可以定义性能监控的自定义指标。在这里可以选择专门监视的webrole实例。
这也是我想做的。对该页面实际作用的见解也可能有所帮助。

进行比较:
http://puu.sh/1xp7q

我想得到这些信息的唯一愚蠢的方式是:
要获取每个w3wp启动之前和之后的所有进程的列表-确定添加了哪个进程,然后根据代码库上下文确定刚刚启动的角色实例。

最佳答案

我让它工作了-尽管不是很简单。

首先,我必须对我之前的陈述进行一些更正-只是处于同一水平。

在Cloud Service中,有几个虚拟机,每个虚拟机托管一个WebRole实例或一个WorkerRole实例。
因此,在单个VM上,只有一个w3wp运行,或者仅一个w3wp运行,而一个waworkerhost进程则不运行。

在我的特殊情况下,可以在单个VM上运行两个w3wp。所以我需要区分这两者-因此需要我进行某种流程-实例关联。

我要记录的是:单个VM的总CPU负载,在VM上运行的实例进程的CPU负载(w3wp,waworkerhost)。

每个虚拟机的PerformanceCounter的总CPU负载很容易且相等:\Processor(_Total)\%Processortime
对于webrole VM,我无法使用\process(w3wp)\%Processortime计数器,因为我无法确定其是否正确w3wp(请参见上文)

现在这是我所做的:
由于必须在WebRole.cs或WorkerRole.cs中为每个角色实例OnStart()启动性能计数器监视器,因此我认为这是我可以以某种方式收集所需信息的唯一位置。

在WorkerRole.cs中,我做了:

int pc = Environment.ProcessorCount;
        string instance = RoleEnvironment.CurrentRoleInstance.Id;

        SomeOtherManagementClass.StartDiagnosticMonitorService(pc, instance, Process.GetCurrentProcess());

在WebRole.cs中,CurrentProcess还返回WaWorkerHost,因此我不得不将上述代码行移至WebRole的global.asax中。此处提供了正确的过程。

在SomeOtherManagementClass中,我放置了StartDiagnosticsMonitorService,它现在接收从中调用StartDiagnosticsMonitorService的CurrentProcess。
(它将从workerrole.cs接收WaWorkerHost进程,从WebRoles接收w3wp进程-包括PID)
public static void StartDiagnosticMonitorService(int coreCount, string currentRole, Process process)
    {
        string processName = GetProcessInstanceName(process.Id);
        SetCPUCoreData(coreCount, currentRole, processName, process.Id);
         ...
    instanceProcessLoadCounterName = String.Format(@"\Process({0})\% Processor Time", processName);
    }

现在,在每个VM上调用GetProcessInstanceName(process.Id),并将processName获取到所提供的process.Id-这使您可以区分单个VM上的多个w3wps,因为返回的instanceName是w3wp,w3wp#1,w3wp#与GetCurrentProcess提供的processName相反(始终为w3wp)与2等相反。为此,我修改了我在stackoverflow上找到的代码样本-您可以在下面找到它:
private static string GetProcessInstanceName(int pid)
    {
        PerformanceCounterCategory cat = new PerformanceCounterCategory("Process");

        string[] instances = cat.GetInstanceNames();
        foreach (string instance in instances)
        {
            try
            {
                using (PerformanceCounter cnt = new PerformanceCounter("Process",
                 "ID Process", instance, true))
                {
                    int val = (int)cnt.RawValue;
                    if (val == pid)
                    {
                        return instance;
                    }
                }
            }
            catch (InvalidOperationException)
            {
                //this point is reached when a process terminates while iterating the processlist- this it cannot be found
            }
        }
        return "";
    }

最后但并非最不重要的一点是:SetCPUCoreData(coreCount,currentRole,processName,process.Id)将进程的所有相关数据保存到Azure存储中,因此可以在应用程序中的任何位置使用:
private static void SetCPUCoreData(int count, string roleinstance, string processName, int processID)
    {
        string[] instances = roleinstance.Split('.');
        CloudStorageAccount storageAccount = CloudStorageAccount.Parse(GetSettingValue("LoadMonitor.Connection.String"));
        CloudTableClient cloudTableClient = storageAccount.CreateCloudTableClient();
        const string tableName = "PerformanceMonitorCoreCount";
        cloudTableClient.CreateTableIfNotExist(tableName);
        TableServiceContext serviceContext = cloudTableClient.GetDataServiceContext();


        PerformanceCounterCPUCoreEntity ent = new PerformanceCounterCPUCoreEntity(count, instances[instances.Count() - 1],processName, processID);
        serviceContext.AttachTo(tableName, ent);
        serviceContext.UpdateObject(ent);
        serviceContext.SaveChangesWithRetries(SaveChangesOptions.ReplaceOnUpdate);
    }

PerformanceCounterCPUCoreEntity是StorageTable的模板-如果对本部分有任何疑问,请咨询azure Storage API。

关于azure - 识别Web角色实例的关联w3wp流程,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13709158/

10-11 01:52