6

我正在监视Azure服务的性能。确定Web角色实例的关联w3wp进程

目前有两个Web角色实例(同一网站)上运行 - 每一个都有自己W3WP.EXE(W3WP和W3WP#1)

我如何才能找到w3wp进程属于哪个角色实例,该实例?

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

因此最终结果在AzureStorage表WADPerformanceCounters仅具有类似于条目:

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

大气压其像

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启动后获得所有的进程列表 - 确定加入其中之一,然后决定代码库上下文明智哪个角色实例刚刚启动。

回答

0

我得到了它的工作 - allthough它并不真正直接。

首先,我必须对我以前的陈述进行一些更正 - 只是要在同一水平上。

在Cloud Service中,有几个虚拟机,每个虚拟机承载WebRole实例或WorkerRole实例。 因此,在一台虚拟机上,只有一个w3wp运行,或者根本没有w3wp,只有一个waworkerhost进程。

在我的特殊情况下,可能会在单个虚拟机上运行两个w3wp。所以我需要在这两者之间进行区分 - 因此需要我进行某种过程 - 实例关联。

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

对于每个虚拟机,CPU负载的PerformanceCounter很容易和相等:\ Processor(_Total)\%Processortime 对于webrole VM,我不能只使用\ process(w3wp)\%processortime counter,因为我不能知道它的正确的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); 
    } 

GetProcessInstanceName(process.Id)现在被称为上的每个VM,并获取processName所提供process.Id - 这允许您在单个虚拟机上区分多个w3wps,因为与由GetCurrentProcess提供的processName(它是allways w3wp)相反,返回的instanceNames是w3wp,w3wp#1,w3wp#2等。为了这个,我修改了codesample我发现这里的计算器 - 你可以在下面找到它:

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存储API,如果你有任何关于这部分有任何疑问,或只问。

相关问题