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,如果你有任何關於這部分有任何疑問,或只問。

相關問題