13

WCF サービス インターフェイスを介していくつかの仮想キューのメッセージを提供する Windows サービスがあります。2 つのパフォーマンス カウンターを公開したかった -

  1. キューにあるアイテムの数
  2. 1 秒あたりのキューから削除されたアイテムの数

最初のものは正常に動作し、RawValue が正しいように見えるにもかかわらず、2 番目のものは PerfMon.exe で常に 0 として表示されます。

私はそのようにカウンターを作成しています-

    internal const string PERF_COUNTERS_CATEGORY = "HRG.Test.GDSSimulator";
    internal const string PERF_COUNTER_ITEMSINQUEUE_COUNTER = "# Messages on queue";
    internal const string PERF_COUNTER_PNR_PER_SECOND_COUNTER = "# Messages read / sec";

if (!PerformanceCounterCategory.Exists(PERF_COUNTERS_CATEGORY))
{
    System.Diagnostics.Trace.WriteLine("Creating performance counter category: " + PERF_COUNTERS_CATEGORY);
    CounterCreationDataCollection counters = new CounterCreationDataCollection();

    CounterCreationData numberOfMessagesCounter = new CounterCreationData();
    numberOfMessagesCounter.CounterHelp = "This counter provides the number of messages exist in each simulated queue";
    numberOfMessagesCounter.CounterName = PERF_COUNTER_ITEMSINQUEUE_COUNTER;
    numberOfMessagesCounter.CounterType = PerformanceCounterType.NumberOfItems32;
    counters.Add(numberOfMessagesCounter);

    CounterCreationData messagesPerSecondCounter= new CounterCreationData();
    messagesPerSecondCounter.CounterHelp = "This counter provides the number of messages read from the queue per second";
    messagesPerSecondCounter.CounterName = PERF_COUNTER_PNR_PER_SECOND_COUNTER;
    messagesPerSecondCounter.CounterType = PerformanceCounterType.RateOfCountsPerSecond32;
    counters.Add(messagesPerSecondCounter);

    PerformanceCounterCategory.Create(PERF_COUNTERS_CATEGORY, "HRG Queue Simulator performance counters", PerformanceCounterCategoryType.MultiInstance,counters);
}

次に、各サービス コールで、関連するカウンターをインクリメントします。現在、1 秒あたりのカウンターは次のようになっています。

messagesPerSecCounter = new PerformanceCounter();
messagesPerSecCounter.CategoryName = QueueSimulator.PERF_COUNTERS_CATEGORY;
messagesPerSecCounter.CounterName = QueueSimulator.PERF_COUNTER_PNR_PER_SECOND_COUNTER;
messagesPerSecCounter.MachineName = ".";
messagesPerSecCounter.InstanceName = this.ToString().ToLower();
messagesPerSecCounter.ReadOnly = false;

messagesPerSecCounter.Increment();

前述のように、increment の呼び出しの後にブレークポイントを配置すると、サービスへの呼び出しと一致して、RawValue が絶えず増加していることがわかります (かなり頻繁に、1 秒に 1 回以上だと思います)。しかし、パフォーマンス カウンター自体はオンのままです。 0.

「キュー」の項目数を提供するパフォーマンス カウンターは、同じ方法で実装されます (ただし、Increment を呼び出すのではなく、RawValue を割り当てます)。

私は何が欠けていますか?

4

4 に答える 4

15

また、最初はこのカウンターに問題がありました。MSDN には、私を大いに助けてくれた完全に機能する例があります。

http://msdn.microsoft.com/en-us/library/4bcx21aa.aspx

彼らの例はかなり長くなってしまったので、私はそれを 1 つのメソッドに要約して、必要最小限の機能を示しました。実行すると、PerfMon で 1 秒あたり 10 カウントの期待値が表示されます。

public static void Test()
{
    var ccdc = new CounterCreationDataCollection();

    // add the counter
    const string counterName = "RateOfCountsPerSecond64Sample";
    var rateOfCounts64 = new CounterCreationData
    {
        CounterType = PerformanceCounterType.RateOfCountsPerSecond64,
        CounterName = counterName
    };
    ccdc.Add(rateOfCounts64);

    // ensure category exists
    const string categoryName = "RateOfCountsPerSecond64SampleCategory";
    if (PerformanceCounterCategory.Exists(categoryName))
    {
        PerformanceCounterCategory.Delete(categoryName);
    }
    PerformanceCounterCategory.Create(categoryName, "",
        PerformanceCounterCategoryType.SingleInstance, ccdc);

    // create the counter
    var pc = new PerformanceCounter(categoryName, counterName, false);

    // send some sample data - roughly ten counts per second
    while (true)
    {
        pc.IncrementBy(10);
        System.Threading.Thread.Sleep(1000);
    }
}

これが誰かに役立つことを願っています。

于 2011-02-22T02:34:13.980 に答える
4

タイプパフォーマンスカウンターを使用Averageする場合、分子と分母の2つのコンポーネントがあります。平均を使用しているため、カウンターは「yインスタンスあたりxインスタンス」として計算されます。あなたの場合、「秒数」あたりの「アイテム数」を計算しています。つまり、キューから取り出したアイテムの数と、それらが削除されるのにかかる秒数の両方をカウントする必要があります。

Averageタイプパフォーマンスカウンターは、実際には2つのカウンターを作成します。分子コンポーネントはと呼ばれ、{name}分母コンポーネントはと呼ばれ{name}Baseます。パフォーマンスカウンタースナップインに移動すると、すべてのカテゴリとカウンターを表示できます。Baseカウンターの名前を確認できます。キュー処理プロセスが開始されたら、次のことを行う必要があります

  • ストップウォッチを開始します
  • キューからアイテムを削除します
  • ストップウォッチを停止します
  • {name}キューから削除されたアイテムの数だけカウンターをインクリメントします
  • {name}Baseストップウォッチのティック数だけカウンターをインクリメントします

カウンターは、最初のカウンターを2番目のカウンターで割って、平均レートを算出することを自動的に認識しているはずです。これがどのように機能するかの良い例については、CodeProjectを確認してください。


このタイプのカウンターは必要ない可能性があります。これらのAverageカウンターは、操作の1秒あたりに発生するインスタンスの数を判別するために使用されます。たとえば、注文を完了したり、複雑なトランザクションやプロセスを実行したりするのにかかる平均秒数。必要なの、処理時間ではなく、「リアルタイム」でのインスタンスの平均数です。

キューに1つのアイテムがあり、削除に1ミリ秒かかった場合、これは1秒あたり1000アイテムの速度です。しかし、1秒後には1つのアイテムしか削除されていないため(これですべてです)、「リアルタイム」で1秒あたり1つのアイテムを処理しています。同様に、キューに100万個のアイテムがあるが、サーバーが他の作業を実行しているために1つしか処理していない場合、1000アイテム/秒理論または1アイテム/秒実数を表示しますか?

理論上のスループットの数値ではなく、この「実際の」数値が必要な場合、このシナリオはパフォーマンスカウンターにはあまり適していません。代わりに、開始時刻、終了時刻、および処理されたアイテムの数を知る必要があります。単純な「カウンター」では実際にはできません。代わりに、システムの起動時間をどこかに保存し、を計算し(number of items) / (now - startup time)ます。

于 2011-02-06T02:54:41.590 に答える
0

カウンターを永続化するには何らかの方法が必要だと思います。サービス呼び出しが開始されるたびに、カウンターが再作成されるようです。

そのため、カウンターを DB、フラット ファイル、またはユーザーに固有にしたい場合はセッション変数に保存することもできます。

于 2011-02-06T00:50:56.253 に答える