6

カスタムパフォーマンスカウンターを作成して書き込むことで統計を追跡するASP.NETアプリケーションがあります。ときどき、現在のプロセスですでに使用されているためにカウンターを開くことができなかったことを示すエラーログが表示されます。これは、同じw3wp.exeプロセス内で.NETアプリドメインがリセットされたことが原因だと思います。アプリドメインがリサイクルされたときに、これらのエラーを回避し、パフォーマンスカウンターへの接続を再確立するにはどうすればよいですか?

カウンター構造:

PerformanceCounter pc = new PerformanceCounter();
pc.CategoryName = category_name;
pc.CounterName = counter_name;
pc.ReadOnly = false;
pc.InstanceLifetime =
PerformanceCounterInstanceLifetime.Process;
pc.InstanceName = instance_name;

カウンターの使用法:

pc.Increment()

[2009年3月26日に更新]受信したエラーメッセージは次のとおりです。

インスタンス'_lm_w3svc_1_root_myapp'は、プロセスの存続期間とともにすでに存在します。削除されるか、それを使用しているプロセスが終了するまで、再作成または再利用することはできません。プロセスの存続期間ですでに存在します。

パフォーマンスカウンターを初期化し、一時的なAppDomainでそれらの1つに書き込むことにより、コンソールアプリケーションで例外を複製しようとしました。次に、AppDomainをアンロードし、2番目のAppdomainで再度実行します(同じプロセス)。どちらも成功します。これの原因が正確にわからないので、ASP.NETでのAppDomainのリサイクルに関する私の仮定は間違っているようです。

4

6 に答える 6

5

上記のエラーは、プロセスベースのWCFパフォーマンスカウンターを使用している場合にも、アプリケーションログで発生する可能性があります。この症状は、アプリケーションイベントログの3つのエラーのブロックです。

パフォーマンスカウンターがロードされませんでした。
カテゴリ名:ServiceModelService 3.0.0.0
カウンター名:呼び出し
Exception:System.InvalidOperationException:インスタンス'abc@def|service.svc'は、プロセスの存続期間中にすでに存在します。削除されるか、それを使用しているプロセスが終了するまで、再作成または再利用することはできません。

これは常に、システムイベントログの次の情報メッセージの直後に発生します。

プロセスIDが「nnnn」でアプリケーションプール「MyAppPool」にサービスを提供しているワーカープロセスが、許可された処理時間制限に達したため、リサイクルを要求しました。

これにより、このサービスのパフォーマンスモニターカウンターが、明らかに数時間使用できなくなります。

ServiceModelService 3.0.0.0バージョン番号は、使用している.NETのバージョンによって異なります(これは.NET 3.5を使用してテストされています)。

バックグラウンド

障害は、ワーカープロセスが処理時間制限に達することによってトリガーされ、その時点でリサイクルする必要があります。これは、IISアプリケーションプールのリサイクル設定(IIS 6.0以降、つまりWindows Server 2003以降)で設定されます。ワーカープロセスをリサイクルすると、新しいプロセスベースのパフォーマンスカウンター名が古いものと競合し、エラーが発生します。これは、IISが重複リサイクルを使用しているためです。この場合、終了するワーカープロセスは、新しいワーカープロセスが開始されるまで実行され続けます。

再生

(Windows Server 2003 = IIS 6.0でテスト済み)

  • WCFサービスを作成します。
  • セクションのに以下を追加します。web.config<system.serviceModel>
    <diagnostics performanceCounters="All" />
  • [プロパティ]→[リサイクル]のサービスの[アプリケーションプール]プロパティで、リサイクルワーカープロセスを1分に設定します。アプリケーションプールを手動でリサイクルしても効果はありません。これは、ワーカープロセスからリサイクルの要求が作成されないためです(イベントビューアのシステムログにW3SVC情報イベントが含まれていることがわかります)。
  • soapUIで、WCF操作のテストスイート/テストケース/テストステップ/テストリクエストを作成します
  • テストケースをsoapUIの負荷テストに追加するか、loadUIを使用て、1秒あたり1回の速度で呼び出しを開始します。
  • 1分ごとに、ワーカープロセスはリサイクルを要求します(システムログに表示されます)。2分ごとに、からのアプリケーションログに3つのエラーのバッチが発生しSystem.ServiceModel 3.0.0.0ます。
  • そのサービスのパフォーマンスカウンターは、ワーカープロセスが再度リサイクルされるまで使用できなくなります。(注:この時点でリサイクル期間をより高い値に設定して、パフォーマンスカウンターが使用できない期間を確認すると、実際にプロセスがリサイクルされ、カウンターが再び使用可能になります。)

可能な解決策

解決策1-赤いニシン

ホットフィックスKB981574は、ホットフィックスKB971601に取って代わります。後者の修正プログラムは問題を説明しています。

修正:アプリケーションを監視するパフォーマンスカウンターは、アプリケーションが終了して再起動すると応答を停止し、.NETFramework2.0を実行しているコンピューターでSystem.InvalidOperationException例外を受け取ります。

以前の修正プログラムを適用しても、問題は解決しません。後者の修正プログラムを適用すると、アプリプールエラーが発生しました。

ソリューション2-実用的なソリューション

カスタムサービスホストを公開するサービスホストファクトリを作成することができます。

using System;
using System.Diagnostics;
using System.ServiceModel;
using System.ServiceModel.Activation;

namespace MyNamespace
{
    public class WebFarmServiceHostFactory : ServiceHostFactory
    {
        protected override ServiceHost CreateServiceHost(
                   Type serviceType, Uri[] baseAddresses)
        {
            return new WebFarmServiceHost(serviceType, baseAddresses);
        }
    }

    public class WebFarmServiceHost : ServiceHost
    {
        public WebFarmServiceHost(
            Type serviceType, params Uri[] baseAddresses)
            : base(serviceType, baseAddresses) { }

        protected override void ApplyConfiguration()
        {
            base.ApplyConfiguration();

            Description.Name = "W3wp" + Process.GetCurrentProcess().Id +
                               Description.Name;
        }
    }
}

そして、サービスマークアップ.svcファイルでファクトリを参照してください。

<%@ ServiceHost Language="C#" Debug="true" Factory="MyNamespace.WebFarmServiceHostFactory" Service="WcfService1.Service1" CodeBehind="Service1.svc.cs" %>

最終的な調整

残念ながら、これにより問題の発生頻度は大幅に低下しますが、それでも発生します(これについて正確な統計を測定していませんが、概算で約30分の1になります)。

問題を完全に解決するように見える簡単な調整は、直前にスリープコマンドを追加することbase.ApplyConfiguration();です。

Thread.Sleep(1);

これは、ワーカープロセスのリサイクルごとに1回だけ発生するため、サービスのパフォーマンスへの影響はごくわずかです。この値を上げる必要があるかもしれません(構成可能にすることができます)が、最小設定の1msでうまくいきました(このコマンドが実際にどれだけ長くスリープするかについての議論)。

解決策3-最も簡単な修正

IISには、DisallowOverlappingRotationメタベースプロパティがあります。これは次のように設定できますMyAppPoolアプリケーションプールの例)。

cscript %SYSTEMDRIVE%\inetpub\adminscripts\adsutil.vbs SET w3svc/AppPools/MyAppPool/DisallowOverlappingRotation TRUE

ソリューションの比較

解決策3では、IISの重複したリサイクルがないために、ワーカープロセスがリサイクルされると、サイトがより長くダウンします。

5スレッドで毎秒100以上のトランザクションを使用する基本的なWebサービスのsoapUI負荷テストでは、ワーカープロセスがリサイクルされるたびに、新しいトランザクションがブロックされる「フリーズ」が数秒間明らかになりました。より複雑なWebサービスをテストすると、このフリーズはさらに長くなりました(8秒以上)。

ソリューション#2は、そのようなブロッキングを生成せず、リサイクル中の応答の流れがスムーズで、perfmon競合エラーを生成しませんでした。

結論

低遅延が要件ではないWebサービスの場合、ソリューション#3を使用できます。負荷分散と1日の静かな時刻がわかっている場合は、リサイクルを設定した時刻に毎日行うように設定することもできます(これは、IISの同じタブで実行できます)。Webファームが使用された場合、これはずらされる可能性さえあります。

このような遅延を許容できないWebサービスの場合、ソリューション#2が最善の方法であると思われます。

于 2012-10-22T09:06:27.477 に答える
0

私はカスタム カウンターの専門家ではありませんが、提供された情報に基づいて、ドメインの追加がリサイクルされようとしているときに一部のコードがカウンターを使用しようとする可能性を考えると、試してみる価値があると思います。破棄またはデストラクタに関連するものでカウンターの使用を探します。

于 2009-03-26T23:32:28.083 に答える
0

同様の問題がありました: マルチインスタンス、プロセス LifeTime カウンターは Visual Studio 内で複数回作成できませんでしたが、PerfMon を開いたことが原因でした!

それに気付くのに少し時間がかかりました。

于 2009-11-05T15:21:17.007 に答える
0

パフォーマンス カウンターを遅延して作成している場合は、スレッドの問題である可能性があります。プロセスのリサイクル後、2 つのページ ヒットが同時に発生した場合 (特に驚くことではありません)、パフォーマンス作成呼び出しが複数回実行される可能性があります。一方では、このエラーを安全に無視できます。しかし、それを排除したい場合は、パフォーマンス カウンターのコード生成を次のようなロック ステートメントでラップすることをお勧めします。

lock (this.lockObject)
{
 //Create performance counter
}
于 2009-03-30T18:37:16.077 に答える