6

Azure サービスのパフォーマンスの監視に取り組んでいます。

現在、2 つの Web ロール インスタンス (同じ 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

atm そのような

WebRoleInstance_n_0 | process(w3wp)\processorTime (%) |  12.4
WebRoleInstance_n_1 | process(w3wp)\processorTime (%) |  12.4

私は考えました:各役割のDiagnosticsMonitorを開始した場合、モニターは正しいプロセスを使用します-モニターを開始したRoleinstanceに属します。しかし、実際にはそれは機能しません-または、機能しないと思います-少なくとも結果の値を見た後。

//更新: manage.windowsazure ポータルで、パフォーマンス監視用のカスタム メトリックを定義できます。ここで、排他的に監視する Webrole インスタンスを選択することができます。これは私もやりたいことです。このページが実際に何をするかについての洞察も役立つかもしれません。

比較用: http://puu.sh/1xp7q

この情報を取得するために私が考えることができる唯一の愚かな方法は、各 w3wp が開始される前後のすべてのプロセスのリストを取得することです。

4

1 に答える 1

0

私はそれを機能させました-それは本当に簡単ではありませんでしたが。

まず第一に、以前の発言をいくつか訂正しなければなりません - ただ同じレベルになるために。

クラウド サービスには複数の仮想マシンがあり、それぞれが WebRole インスタンスまたは WorkerRole インスタンスをホストしています。したがって、単一の VM では、単一の w3wp のみが実行されるか、waworkerhost プロセス以外の w3wp がまったく実行されません。

私の特別なケースでは、単一の VM で 2 つの w3wp を実行する可能性があります。そのため、これら 2 つを区別する必要がありました。そのため、何らかのプロセスとインスタンスの関連付けを行う必要がありました。

私がログに記録したかったのは、単一の VM の合計 CPU 負荷、VM で実行されているインスタンス プロセスの CPU 負荷 (w3wp、waworkerhost) です。

合計 CPU 負荷の PerformanceCounter は簡単で、VM ごとに同じです: \Processor(_Total)\% Processortime for webrole VM 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 で呼び出され、指定された process.Id の processName を取得するようになりました。これにより、返される instanceNames が w3wp、w3wp#1、w3wp# であるため、単一の VM で複数の w3wps を区別することができます。 2 など、常に w3wp である GetCurrentProcess によって提供される processName とは対照的です。このために、スタックオーバーフローで見つけたコードサンプルを変更しました-以下で見つけることができます:

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 を調べるか、質問してください。

于 2012-12-18T11:19:30.270 に答える