azure - 识别 Web 角色实例的关联 w3wp 进程

标签 azure azure-web-roles multiple-instances w3wp performance-monitor

我正在致力于监控 Azure 服务的性能。

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

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

有了这些信息,我想向 azure.diagnostics.monitor 提供一些性能计数器 - 即 Process(w3wp)\ProcessorTime (%) 和线程计数。 但为了获得任何有意义的数据,我必须将 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,那么监视器将使用正确的进程 - 属于启动监视器的角色实例。但实际上这不起作用 - 或者我认为它不起作用 - 至少在查看结果值之后。

//更新:在manage.windowsazure门户上,您可以定义性能监控的自定义指标。这里可以选择要专门监控的 webrole 实例。 这也是我想做的。深入了解此页面的实际用途也可能有所帮助。

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

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

最佳答案

我成功了 - 尽管它并不是很直接。

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

云服务中有多个虚拟机,每个虚拟机托管一个 WebRole 实例或一个 WorkerRole 实例。 因此,在单个 VM 上,只有一个 w3wp 运行,或者除了 waworkerhost 进程之外根本没有 w3wp 运行。

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

我想要记录的是:单个虚拟机的总 CPU 负载、虚拟机上运行的实例进程的 CPU 负载(w3wp、waworkerhost)。

总 CPU 负载的性能计数器对于每个 VM 来说都很简单且相同:\Processor(_Total)\% Processortime 对于 webrole VM,我不能只使用\process(w3wp)\% 处理器时间计数器,因为我无法确定它是否是正确的 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) 并获取所提供的 process.Id 的 processName - 这允许您区分单个虚拟机上的多个 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 "";
    }

最后但并非最不重要的一点: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/

相关文章:

postgresql - 多服务器实例负载和数据库平衡

sql - 无法将 Windows Azure 连接到 MySQL WorkBench

azure - 如何停止 Azure Pipelines 上当前运行的 WebJobs?

wpf - PublicClientApplication - AcquireTokenInteractive - 组成员资格

azure - 在 Azure 数据工厂的查找阶段在 SQL 查询内传递动态内容

c# - Azure 中的 ClientBuildManager.PrecompileApplication 不使用预编译版本

azure - 如何使用站点管理器获取webrole实例的域名?

azure - 一个 Azure WebRole 中的多个站点

一页上不同日期选择器的 jQuery 问题