Jal*_*hra 6 multiple-instances w3wp azure performance-monitor azure-web-roles
我正在努力监控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
Run Code Online (Sandbox Code Playgroud)
atm就像
WebRoleInstance_n_0 | process(w3wp)\processorTime (%) | 12.4
WebRoleInstance_n_1 | process(w3wp)\processorTime (%) | 12.4
Run Code Online (Sandbox Code Playgroud)
我想:如果我为每个角色启动了DiagnosticsMonitor,那么监视器将使用正确的进程 - 属于启动监视器的Roleinstance.但实际上这不起作用 - 或者我认为它不起作用 - 至少在查看结果值之后.
// update:在manage.windowsazure门户上,您可以为性能监视定义自定义指标.这里可以选择专门监控的webrole实例.这也是我想要做的.对此页面实际执行的操作的见解也可能有所帮助.
比较:http: //puu.sh/1xp7q
他们只想到获取此信息的愚蠢方式是:获取每个w3wp启动前后所有进程的列表 - 确定添加了哪个进程,然后确定代码库上下文明智地启动了哪个角色实例.
我让它工作了——尽管它并不是很直接。
首先,我必须对我之前的言论做出一些更正——只是为了保持在同一水平上。
在云服务中有多个虚拟机,每个虚拟机托管一个 WebRole 实例或一个 WorkerRole 实例。因此,在单个 VM 上,只有一个 w3wp 运行,或者除了 waworkerhost 进程之外根本没有 w3wp 运行。
在我的特殊情况下,可以在单个虚拟机上运行两个 w3wp。所以我需要区分这两者 - 因此要求我进行某种流程实例关联。
我想要记录的是:单个虚拟机的总 CPU 负载、虚拟机上运行的实例进程的 CPU 负载(w3wp、waworkerhost)。
总 CPU 负载的性能计数器对于每个 VM 来说都很简单且相等: \Processor(_Total)\% Processortime for the 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());
Run Code Online (Sandbox Code Playgroud)
在 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);
}
Run Code Online (Sandbox Code Playgroud)
现在,在每个 VM 上调用 GetProcessInstanceName(process.Id) 并获取提供的 process.Id 的 processName - 这允许您区分单个 VM 上的多个 w3wp,因为返回的实例名称为 w3wp、w3wp#1、w3wp# 2 等与 GetCurrentProcess 提供的 processName 相反,它始终是 w3wp。为此,我修改了我在 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 "";
}
Run Code Online (Sandbox Code Playgroud)
最后但并非最不重要的一点是: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);
}
Run Code Online (Sandbox Code Playgroud)
PerformanceCounterCPUCoreEntity 是 StorageTable 的模板 - 如果您对此部分有任何疑问,请查看 azure Storage API,或者直接提问。
| 归档时间: |
|
| 查看次数: |
1270 次 |
| 最近记录: |