2012-07-03 47 views
13

私はnetNamedPipeBindingバインディングでコンソールにWCFサービスをホストしています。サービスは、ただ1つの空のメソッドにありSend(DataTable bulk)MSMQがWCF QueueServiceより高速なのはなぜですか?

[ServiceContract] 
public interface IWcfQueueService 
{ 
    [OperationContract] 
    void Send(DataTable bulk);  
} 
public class WcfQueueService : IWcfQueueService 
{ 
    public void Send(DataTable bulk) 
    {   
     // Here would be something like _bulks.Add(bulk); 
     // BUT, for now it is empty method and still it's slower than MSMQ 
    }  
} 

私のクライアントは、DBから200Kの入力を取得し、私たちのBoundedThreadPoolでそれを処理(言ってみましょう、だけで作成し、20スレッド)。各入力は異なるスレッドで処理されます。各スレッドはMyMethodを実行し、MyMethodの末尾には結果がbulkManagerに追加されます。

public void MyMethod(string input) 
{    
    var res = ProcessInput(input); 
    bulkManager.Add(res); 
} 

bulkManagerは、N個のアイテム(=バルク)を蓄積それはないすべては、2つの方法のいずれかでそのバルクエンキューであることを他のスレッドにバルクを渡す:WCFが有効な場合

  1. wcfQueueService.Send(bulk);
  2. 他MSMQが有効になっている場合:new MessageQueue(@".\private$\q").Send(new Message {Body = bulk});

すべての二つの方法が動作しますが、MSMQは、はるかに高速に動作します。 MSMQクライアントは20秒で約80Kのバルクを処理し、wcfは20K〜30Kのバルクのみを処理します。 なぜそれが起こるのか分かりません。私のWCFはMSMQのように異なるプロセスで動作します。また、WCFには何も格納されていませんが、空のメソッドがあります。ではなぜMSMQがWCFに勝ったのですか? leppieは私が.NetRemotingを試してみまし示唆したように

を更新しました。 NetRemotingは確かにスピードを改善しました。クライアントは60Kを処理しました。しかし、

  1. 私は.NETリモート処理を読んでそれはまだMSMQ
  2. より遅いのですがWCFによって廃止されており、WCFはthisによる.NETリモート処理よりも高速でなければなりませんので、私は私のWCFが遅くなることを取得する理由は?多分私の縛りは間違っていますか?
+0

リモート処理はMSMQ(名前付きパイプが与えられていますが、ローカルマシン上ではIPCとみなされます)よりもはるかに高速です。 – leppie

+0

@leppie、.Net遠隔操作は実際に速度を改善しました。クライアントは60Kを処理しました。しかし、1 - それはまだMSMQと2よりも遅いです.Net RemotingはWCFによって廃止され、WCFはhttp://msdn.microsoft.com/en-us/library/bb310550に従って.Net Remotingより速くなければなりません.aspx#wcfperform_topic3d、なぜ私のwcfが遅くなるのですか? – theateist

+0

@theateist:サービス上の 'InstanceContextMode'を' Single'に、ConcurrencyMode'を 'Multiple'に変更できますか?次に、別のテストを行います。また、(サービス動作の)スロットル設定を調整しようとしました。 –

答えて

4

あなたはlikeと似ていません。

最も顕著な違いは、WCFのケースでは、サービス側チャネルスタック全体の実行と操作呼び出しが含まれているのに対し、ダイレクトMSMQの場合はクライアント側のペイロードをエンキューする時間だけを測定することです。 WCFのサービス側の処理には、DataTableオブジェクトの逆シリアル化が含まれていることに注意してください。これは、大きな要素Nが大きい場合はおそらくかなり高価です。

サービスインスタンスとスロットルノブをどのように設定したかによって、クライアントからの要求がサービスが処理するよりも速く行われている可能性があります。サービス側。

また、バインディングを設定する方法によっては、セキュリティなどの他の重要な相違点があります。ちなみに、NetMsmqBindingではなくNetNamedPipeBindingを本当に使ったのですか?その場合は、デフォルトのバインド設定を使用して、totally unnecessaryのバルクメッセージの暗号化と署名が行われます。これはダイレクトMSMQのケースでは起こりません。大きなメッセージに対するこれらの暗号操作は、比較的高価なものになります。

より良い比較は、OneWayとして定義されたWCF操作を使用する場合です。

+0

'完全に不要な'リンクが死んでいる場合は、エントリーのコピーを持っている可能性はありますか?本当にそれを読むことに興味があり、ありがとう – zaitsman

0

私はWCF操作で何が起こるのか、要求を受け入れるときにMSMQが何をするのかという違いがあると思います。

MSMQを使用してメッセージをエンキューするときに実行されるメソッドは、メッセージとそれ以外のものを受け入れることが期待されます。いくつかのバックエンドの作業者は重い持ち上げをします。

操作では、要求ハンドラの1つのインスタンスに要求を渡す必要があります。要求ハンドラインスタンスは、サービスが「スピンアップ」されているときにインスタンス化する必要があります。

.NET 4のタスク並列ライブラリを使用して要求を並列化することで、パフォーマンスが向上する場合もあります。

1

表示されている動作を示すサンプルコードを提供できますか?

私は送信する20,000のメッセージを生成して私自身のテストを行いました。私は両方とも、直接MSMQで20,000、MSMQエンドポイントを抽象化したWCFで2万を試しました。

直接MSMQを使用した20,000人がCPU時間の64.75%を使用し、20,000メッセージを送信するWCFバージョンがCPU時間の34.16%を使用しました(Visual Studio Ultimateの分析機能を使用して計測)。

私の最後にエラーが発生していない限り、WCFのバージョンはハードコードされたMSMQ相当の2倍の速さでした。

関連する問題