質問者
ServiceClientからWCF公開メソッド呼出し時に、Win7でレスポンスが遅い

質問
-
こんにちは
WASで公開されているWCFサービスをクライアント側から利用する際に、レスポンスが遅い端末があります。
サービス公開サーバ
・Win2k8+IIS7
社内の、いくつかの端末で確認した結果、現在のところ下記のような漠然とした違いしか判りません。
・Win7系(Vistaを含む)クライアントで使用した場合に遅い。
テスト端末内訳(Win7(32bit)×4、Vista×1、WinXP(32bit)×3)
WinXPだと、クライアント側のServiceReafarenceのメソッド呼出しから、レスポンス受信までに0.2sec程度
同様のものをWin7で実行するとServiceReafarenceのメソッド呼出しから、レスポンス受信までに1sec程度
Wiresharkなどで、パケットのキャプチャを採ってきると、メソッド呼出しから実際IISサーバにリクエストが発行されるまでに時間が掛かっている様子。
(上記のことから、IIS側に渡ってからの処理というより、クライアント側でのA→B→C処理が遅い?)
クライアント側で使用するServiceClientは、app.configからは読込ませず、コードでインスタンスを生成しています。
バインディングはwsHttpBindingを使用し、エンコーディングはMTOM
UseDefaultWebProxy = Falseとしています。(クライアントから繰り返し処理要求しても、毎回症状は変わらないので無関係だと思いますが...)
そもそもの各クライアントでの名前解決の問題はないと思います。(DNS・WINSともにIISサーバのホスト情報は登録されている為)
すべての返信
-
こんにちは、RNC-COM さん。
MSDN フォーラムのご利用ありがとうございます。オペレーターの山本です。
ざっと検索してみたところでは、以下のような情報がありました。該当してないかもしれないですが、念のため。。。
Slow wcf calls on windows 7
http://social.msdn.microsoft.com/Forums/en-NZ/wcf/thread/dc4a2ee7-fa3b-4ea5-9bf6-1bd6e141954f
すでにいろいろ試されているように、サーバー側なのか、ネットワークの問題なのか、それともクライアント側の処理での問題なのかなど、どこで何が遅いのかなどを切り分けていく必要があるかと思います。
遅いだけで正常なのか、どこかでエラーなどが発生していないのかも気になります。
ネットワーク パケットのキャプチャ、WCF のトレースやプロセスの動作状況などについて、正常と思われるほうと、レスポンスが遅いと思われるほうの両方を取得して比較してみると、もうちょっと何かわかるかもしれませんね。
トレース
http://msdn.microsoft.com/ja-jp/library/ms730342.aspx
[T2-302 follow-up (2)] WCF トレースの見方
http://blogs.msdn.com/b/tsmatsuz/archive/2008/08/27/t2-302-follow-up-2-wcf.aspx
この問題について何か情報をお持ちの方がいらっしゃいましたら、是非投稿をお願いいたします。
マイクロソフト株式会社 フォーラム オペレーター 山本 春海 -
こんにちは
先週末、レスしたつもりが...
今朝、覗いてみて、がっくりでした....投稿が完了しないままでブラウザを閉じていたようです
気を取り直してもう一度書きます。
まず、TraceViewerを使って、サーバ側で結果を比べてみました。
Traceの見方が誤っていなければというか、見比べてみた結果、ほぼ処理時間的には誤差の範囲で同じでした。
やはり、問題はクライアント側でのWin7とWinXPの違いによる問題であることまでは絞れたのかと思います。
ただ、今回クライアント側のアプリの構成において、WCFのクライアントの処理(サービスクライアントインスタンスの作成など)は
DLL化されたモジュール内で構成していることもあり、WCFクライアント生成に関わる構成情報はapp.configからの読込みではなく
DLLのソース内で、コーディングにより生成しています。
コーディングでクライアントを生成するために、BindingとEndpointアドレスオブジェクトを生成し、クライアントを作成し
BehaviorのMaxItemsInObjectGraphなどはコードで設定できているのですが
app.configで記述すれば簡単な、<system.diagnostics>パートおよび<system.serviceModel>パート内の
<diagnostics>の記述がコードで出来てません
そのためにクライアント側でトレースデータが今のところ取得できていないのが現状です。
<sharedListeners>の作成までは出来ているのですが、実際に<source>の"System.ServiceModel"
と"System.ServiceModel.MessageLogging"に割り付けられていないというか...
同じく<diagnostics>用のインスタンスは作成できているのですが、<system.serviceModel>の適用できていない感じです。
可能であれば、詳細なパラメータまでコードでクライアントを生成しているソースサンプルを開示している場所などがあれば
ご教示願いたいのですが、よろしくお願いします。
そもそも論ですが...
今回のように、WCFクライアントに関わる部分をDLL化させたような場合の構成ファイルの読込みはどのようなアプローチにするのが
スマートなのでしょうか?
やはり、クライアント生成時に、ファイル名を指定して動的に構成ファイルを読み込むというような手段が望ましいのでしょうか?
アプリケーションの配布など、構成ファイルを付けて配布するのが面倒な気がしまして、今回ソース内で全てコーディングする
ようにしたのですが...
またUSのフォーラムで書かれていた内容で、たまたま今回のテスト環境がNOD32を使用していたりしていましたが、
全てのオプションを無効(アンインストールまではまだ実施していない)にしてみましたが結果は変わりませんでしたし
useDefaultWebProxyに関してももともとオフにしておりました。
-
こんばんは、自己レスです。
問題の完全な解決には至っておりませんが...
その後、いろいろと手を変え品を変え、調査してみました。
時系列に対応内容を記述します。
幾分か改善されたため原因はこいつか...とも思ったタイミングがありました。
2).しかしそれでも、複数の要求を連続して出した場合に、時折下記のエクセプションが発生し
データの欠落が発生してしまいました。
[System.ServiceModel.CommunicationException]
セキュリティで保護されていないか正しくセキュリティで保護されていないフォールトを相手側から
受信しました。
フォールトコードおよび詳細については、内部のFaultException を参照してください。
3).当初のコーディングだと、WCFクライアントのインスタンスを、通信の要求のたびに作成していたため、
かなりのリソースの無駄使いである事が判明し、その点を改修しました。
方法は、安易ですが、インスタンスを Shared オブジェクトとして管理し、要求時にインスタンスが
無い場合のみ再度クリエイトするような手法で考えました。
改修項目の2点目として、2).で発生していた、CommunicationExceptionに関してですが、
WCFクライアントおよびServer側のサービスの構成情報のBinding情報内のセキュリティ
モードの設定を"Message" → "None"に変更する事で、Exceptionは発生しなくなりました。
※3).の2点目の改修項目に関しては、今後通信のセキュア化を実施する場合問題になりそうですが
対応は優先順位としては後回しにしようかと思っています。
また、3)の改修後、NOD32を再度インストールしても、レスポンスの遅延に影響される事はありませんでした。
WinXPとWin7(Vista)でGCの違いがあるのでしょうか????
アプリケーション上で使用していたインスタンスの生成・破棄のタイミングの問題のような気もしてきました...
このスレッドで、「Binding情報内のセキュリティモード」に関しては、調査次第報告しようと思います
-
再度自己レスしたいと思います。
前回の自己レス内で記述しました、項番3).の内容のWCFクライアントのインスタンスの使い回しということで、
Win7の遅延自体の問題は解決したと考えています。
それとは別に、連続したwcf通信を行った場合に、不定期に通信返信時に通信経路の切断または、
通信開始時の認証エラーが発生し通信に失敗する。
というような新たな問題が露呈したものと解釈しています。
そこで、再度wcf通信の両端のバインディングの設定値などを確認してみましたが、やはり問題となりそうな部分は
見つけ出すことは出来ませんでした。
今回wcfのアプローチとしてサービスホスト側はIISのWASを使ってのサービス提供という環境にあるため
公開しているサービス関連の設定値の確認を行っていました。
そこで、公開サービスに割り付けているアプリケーションプールの設定のうち、リサイクルに関わる設定において
当初、問題が露呈している時は、定期的な間隔によるリサイクル処理を行う設定にしておりました。
この部分のチェックボックスを外し、一定周期のリサイクルを行わないように設定変更を行うことにより
連続したwcf通信の途中で通信経路が喪失してしまうという現象が起きなくなりました。
この設定変更による問題回避の理由を説明することは出来ないのですが、結果論として
問題に対する回避が出来ましたので、この設定で、この先運用しようと考えています。
-
またまた、自己レスです。
テストを行っていると、状況が二転三転しまして...
先ずは前回、記述しました、IIS上のアプリケーションプールのリサイクルの件は
やはり、全く根拠もなく、現在はその設定如何では状況の改善にはなりえていません
ですが現在のところ確実に再現性のある事象を記します。
この現象が、妥当なものなのか否か判断に憂慮しております。
WASでWCFホストサービスを公開する場合に物理パスの状態は
仮に[C:\prj\wcfhostService]を公開する場合
C:\prj\wcfhostServiceフォルダにxxxxxxxx.svcファイル
C:\prj\wcfhostService\binフォルダに必要なdllなどのサービスモジュールが
配置されると思います。
ここで、サービスモジュールが格納されているC:\prj\wcfhostService\binフォルダ上に
System.IO.StreamWriterを使ってテキストファイルを作成しようとした際に
初回ファイルをクリエイト(一度目のNew System.IO.StreamWriterでは問題なし)後、
二回目アクセスのため既存のファイルに対してSystem.IO.StreamWriterのインスタンス
を作成した時に、wcfの通信上で「信頼できるセッションが完全に完了する前に、
セキュリティで保護されている基盤となるセッションが途中終了しました。」の
エラーで通信が失敗しまうという現象が発生することがわかりました。
ここで、テキストファイルを作成するパスを以外のパス(作成許可権限のあるパス)で
同様の処理を行うと、二回目以降のSystem.IO.StreamWriterのインスタンス作成時も
通信エラーが発生することはありませんでした。
これも、例えば、wcfサービスホスト側のアプリケーション自体にメモリーリークなどの
問題があり、結果的に今回のような問題が発生しているのかと考え、一切の処理を外し
単に、C:\prj\wcfhostService\binフォルダにファイルを作成し書き込むという処理も
作成してみましたが結果は同じようになりました。
この状況を踏まえ、現在は、ファイルの書き出し先を、公開物理フォルダ以外の
フォルダに書き出すという対策としています。
この対応と、wcfクライアント側のwcfチャネルインスタンスの使い回しを行うことにより
Win7においての速度遅延の問題と、通信時に起こる経路の突然の切断について
状況を回避できております。