首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >标识web角色实例的关联w3wp流程

标识web角色实例的关联w3wp流程
EN

Stack Overflow用户
提问于 2012-12-05 02:06:43
回答 1查看 1.4K关注 0票数 6

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

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

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

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

因此,AzureStorage表WADPerformanceCounters中的最终结果只包含如下条目:

代码语言:javascript
运行
复制
WebRoleInstance_n_0 | process(w3wp_1033)\processorTime (%) |  12.4
WebRoleInstance_n_1 | process(w3wp_1055)\processorTime (%) |  48.4

atm就像

代码语言:javascript
运行
复制
WebRoleInstance_n_0 | process(w3wp)\processorTime (%) |  12.4
WebRoleInstance_n_1 | process(w3wp)\processorTime (%) |  12.4

我想:如果我为每个角色启动一个DiagnosticsMonitor,监控器将使用正确的进程-属于启动监控器的角色实例。但实际上这并不起作用--或者我认为它不起作用--至少在查看结果值之后是这样的。

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

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

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-12-18 19:19:30

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

首先,我必须对我之前的声明做一些更正--只是为了达到同样的水平。

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

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

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

CPU总负载的PerformanceCounter对于每个虚拟机都是简单且相等的:\Processor(_Total)\% Processortime对于webrole虚拟机我不能只使用\process( w3wp )\% processortime计数器,因为我不能确定它是否是正确的w3wp(如上所示)

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

在WorkerRole.cs中,我做到了:

代码语言:javascript
运行
复制
int pc = Environment.ProcessorCount;
        string instance = RoleEnvironment.CurrentRoleInstance.Id;

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

在WebRole.cs中,CurrentProcess也返回WaWorkerHost,所以我必须将上面的代码行移到WebRole的global.asax中。这里提供了正确的流程。

我将StartDiagnosticsMonitorService放在SomeOtherManagementClass中,它现在接收从中调用StartDiagnosticsMonitorService的CurrentProcess。(从workerrole.cs接收WaWorkerHost进程,从WebRoles接收w3wp进程-包括PID)

代码语言:javascript
运行
复制
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,因为返回的instanceNames是w3wp、w3wp#1、w3wp#2等,这与GetCurrentProcess提供的总是w3wp的processName相反。为此,我修改了我在stackoverflow上找到的一个代码样本-你可以在下面找到它:

代码语言:javascript
运行
复制
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存储中,以便在应用程序中的任何地方都可以使用:

代码语言:javascript
运行
复制
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,或者直接询问。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13709158

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档