2012-08-19 12 views
10
ConnectionFactory factory = new ConnectionFactory {HostName = "localhost"}; 

using (IConnection connection = factory.CreateConnection()) 
using (IModel channel = connection.CreateModel()) 
{ 
    channel.QueueDeclare("hello", false, false, false, null); 
    for (int i = 0; i < 100000; i++) 
    { 
     MemoryStream stream = new MemoryStream(); 

     var user = new User 
         { 
          Id = i 
         }; 

     Serializer.Serialize(stream, user); 


     channel.BasicPublish("", "hello", null, stream.ToArray()); 

    } 

} 

私は上記のコードを持っていますが、スレッドの安全性が不思議です。C#RabbitMQクライアントスレッドの安全性

わかりませんが、ConnectionFactoryはスレッドセーフであると思います。しかし、その後、IConnectionがスレッドセーフであるかどうかわかりませんか?要求ごとに接続を作成する必要がありますか?むしろ単一の永続的な接続ですか?そして、IChannelはどうですか?

また、私はThreadLocalとして接続を保存する必要がありますか?または、リクエストごとに接続を作成する必要がありますか?

+1

この質問への私の答えを見るhttp://stackoverflow.com/questions/10407760/is-there-a-performance-difference-between-pooling-connections-or-channels-in-rab/10501593#10501593 – robthewolf

答えて

23

IConnectionはスレッドセーフであり、IModelはそうではありません。一般的に、アプリケーションの存続期間中は接続をオープンに保つように努めなければなりません。これは、メッセージを受信するために開かれた接続が必要なコンシューマがある場合に特に当てはまります。ネットワークやブローカの障害のために、中断された接続を検出して回復することが重要です。私はVidelaとWilliamsの「RabbitMQ in Action」を読むことをお勧めします。特に第6章「失敗を生き延びるコードを書く」をお勧めします。

今、恥知らずのプラグです。私はEasyNetQの著者であり、RabbitMQ用の高水準の.NET APIです。すべての接続管理を行い、ネットワークまたはブローカの停止が発生した場合は、自動的にすべての加入者を再接続して再構築します。また、クラスタとフェールオーバーのサポートを提供します。試してみる。

+11

"非常に注意深い?どんな漠然とした脅威ですか? EasyNetQは完全に適切な提案です。人々がそれに同意しない場合、それはdownvoteボタンのためのものです。彼の作者であることを否定する礼儀をしていないのであれば、その提案はもう一度考えられたとは思えません。私はあなたの馬にその高いところに乗っていることに非常に注意するでしょう。 –