私の会社では、Azure Service Bus Relay を使用して、機密データの概要を Azure でホストされるアプリケーションに集約しています。運用前のサーバーで、最初のいくつかのリクエストが処理された後、ServiceHost インスタンスをホストするプロセスによる CPU 使用率が 70 ~ 90% に跳ね上がり、そこにとどまることに気付きました。通常、ServiceHost は Windows サービスで自己ホストされますが、さまざまなセットアップおよびテスト シナリオで実行する WPF アプリもあり、両方でこの動作を再現できます。弊社の開発環境では、この動作を再現できていません。
コードを確認し、MSDN のサンプルと比較しましたが、同等に見えます。要約版は次のとおりです。
ServiceBusEnvironment.SystemConnectivity.Mode = ConnectivityMode.AutoDetect;
this.serviceBusUri = ...;
TransportClientEndpointBehavior sharedSecretServiceBusCredential = new TransportClientEndpointBehavior();
sharedSecretServiceBusCredential.TokenProvider = TokenProvider.CreateSharedSecretTokenProvider(...,...);
ContractDescription contractDescription = ContractDescription.GetContract(typeof(IOurServiceProxy), typeof(OurServiceProxy));
NetTcpRelayBinding binding = new NetTcpRelayBinding(EndToEndSecurityMode.Transport, RelayClientAuthenticationType.RelayAccessToken, true);
binding.ConnectionMode = TcpRelayConnectionMode.Relayed;
this.serviceEndpoint = new ServiceEndpoint(contractDescription);
this.serviceEndpoint.Address = new EndpointAddress(this.serviceBusUri);
this.serviceEndpoint.Binding = binding;
this.serviceEndpoint.Behaviors.Add(sharedSecretServiceBusCredential);
this.host = new ServiceHost(typeof(OurServiceProxy), this.serviceBusUri);
this.host.Description.Endpoints.Add(this.serviceEndpoint);
this.host.Open();
this.host.Faulted += OnFaulted;
イベント ハンドラーがトリガーされることはなくOnFaulted
、CPU がジャンプした後もリクエストが処理され続けます。ホスト アプリの WPF バージョンには、 への呼び出しを介してサービス バスへの接続を切断できるボタンがあり、this.host.Close()
切断されると、CPU はすぐにアイドル状態に戻ります。
トレース リスナーを実行しましたが、起動SystemConnectivity.Mode
時の自動検出に関連するメッセージのみが表示されます。ServiceHost
スタック内のフォルトの場所は、 への呼び出しの子孫ですMicrosoft.ServiceBus.NetworkDetector.DetectInternalConnectivityModeForAutoDetect(Uri uri)
。障害自体は Microsoft.ServicBus レイヤーによって捕捉され、私の会社のコードにバブルアップすることはありません。トレースによってキャプチャされた特定の例外メッセージは
net.tcp://[name_redacted].servicebus.windows.net:9350/ に接続できませんでした。接続の試行は、00:00:01.1856021 の期間継続しました。TCP エラー コード 10061: ターゲット マシンがアクティブに拒否したため、接続できませんでした [ip_redacted]:9350。
トレースに使用した設定は次のとおりです。
<system.diagnostics>
<sources>
<source name="System.ServiceModel"
switchValue="Warning, Error, Critical"
propagateActivity="true">
<listeners>
<add name="traceListener"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData= "C:\Temp\Traces.svclog" />
</listeners>
</source>
</sources>
</system.diagnostics>
次に、CPU をすべて消費しているスレッドを分析してみました。プロセスのメモリ ダンプから始めましたが、単一のスナップショットでは、時間の経過と共に何が起こっているかについて十分な情報を得ることができないと判断したため、本番 .Net アプリケーションの CPU 分析に関する Sam Saffron のブログ投稿を見つけました。cpu-analyzer のソースの最新バージョンを取得し、問題のサーバーで実行しました。最も高価なスタックはすべてSystem.Threading._IOCompletionCallback.PerformIOCompletionCallback
、ベースに の署名がありました。私の理解では、キャプチャ中にプロセスへの Service Bus 呼び出しはなかったので、このスレッドが何をしていたのかわかりません。
次のステップでは、サーバー上で perfmon キャプチャを実行し、その結果を調べて、明らかな何かが表示されるかどうかを確認します。サーバーに直接アクセスできないため、ハンズオン分析を行うためにシステム管理者と時間をスケジュールする必要があります。
この隠れた CPU スパイクの原因について考えている人はいますか? Azure Service Bus Relay または WCF でこの動作を行うことが知られているものはありますか? どんな提案でも大歓迎です。