2013-07-11 22 views
9

以下に、作業者ロール内で使用するAzure Service Busコードの基本ラッパーを示します。このServiceBusClientは、ワーカーロールが実行されるたびにインスタンス化されます。次に列挙する残りの項目がなくなるまで待ち行列にアクセスするために使用されます。Azureサービスバスクライアント接続の永続性

public class ServiceBusClient : IDisposable, IServiceBusClient 
{ 
    private const int DEFAULT_WAIT_TIME_IN_SECONDS = 120; 

    private const string SERVICE_BUS_CONNECTION_STRING_KEY = "service.bus.connection.string"; 

    private readonly MessagingFactory _messagingFactory; 

    private readonly NamespaceManager _namespaceManager; 

    private readonly QueueClient _queueClient; 

    private readonly ISettingsManager _settingsManager; 

    public ServiceBusClient(ISettingsManager settingsManager, string queueName) 
    { 
     _settingsManager = settingsManager; 

     var connectionString = _settingsManager.GetSetting<string>(SERVICE_BUS_CONNECTION_STRING_KEY); 

     _namespaceManager = NamespaceManager.CreateFromConnectionString(connectionString); 
     _messagingFactory = MessagingFactory.CreateFromConnectionString(connectionString); 

     _queueClient = GetOrCreateQueue(queueName); 
    } 

    public void Dispose() 
    { 
     _messagingFactory.Close(); 
    } 

    public BrokeredMessage ReceiveTopMessage() 
    { 
     return _queueClient.Receive(TimeSpan.FromSeconds(DEFAULT_WAIT_TIME_IN_SECONDS)); 
    } 

    public void SendMessage(object bodyObject) 
    { 
     var message = new BrokeredMessage(bodyObject); 

     _queueClient.Send(message); 
    } 

    private QueueClient GetOrCreateQueue(string queueName) 
    { 
     var queue = !_namespaceManager.QueueExists(queueName) 
         ? _namespaceManager.CreateQueue(queueName) 
         : _namespaceManager.GetQueue(queueName); 

     return _messagingFactory.CreateQueueClient(queue.Path, ReceiveMode.PeekLock); 
    } 

} 

あなたは、私は、コンストラクタ内部NamespaceManagerMessagingFactoryQueueClientを初期化見ることができるように:接続Dispose()メソッドを使用して閉じてSendMessage()ReceiveTopMessage()を呼び出すとき、彼らはその後、再利用されます。

私の質問は、私が使用しているアプローチは安全であるかどうかです。 Workerロールは、キュー上のすべてのメッセージを介して列挙しながら、過渡問題なく一貫して動作、または(ReceiveTopMessage()への呼び出しの間に長い待ち時間でかなり長い間オープン接続を保つことができるプロセス)オープンQueueClientの単一のインスタンスを維持します毎回接続を開いたり閉じたりするのは賢明ですか?

脇に; Microsoftサービスバスコードでは、一時的なフォールト処理はどのように行われますか?デフォルトで実行されていますか、またはTransient Fault Handling Frameworkを実装する必要がありますか? QueueClient class

答えて

9

は、それを作成するために使用MessagingFactoryオブジェクトによって管理されている接続を使用しています。複数の要求に対して同じクライアントオブジェクトを再利用することをお勧めします。 Best Practices for Performance Improvements Using Service Bus Brokered Messagingに記載されているように:Service Busのクライアントプロトコル、およびHTTP:

Service Busは2つの プロトコルを介してメッセージを送受信するためにクライアントを可能にします。メッセージ・ファクトリが存在する限り、サービス・バス・サービスへの接続は を維持するため、サービス・バス クライアント・プロトコルはより効率的です。 は、バッチ処理とプリフェッチも実装しています。サービスバスクライアントの プロトコルは、.NET管理の APIを使用して.NETアプリケーションで使用できます。例えばQueueClient若しくはするmessageSenderとして (...) Service Busのクライアントオブジェクトは、また、接続の 内部管理を提供MessagingFactoryオブジェクトによって作成 あります。 メッセージを送信した後に、メッセージ ファクトリまたはキュー、トピック、およびサブスクリプションクライアントを閉じずに、次のメッセージを送信するときに再作成しないでください。 メッセージング工場を閉じると、サービスバス サービスへの接続を削除し、 工場を再作成するときに、新しい接続が確立されています。接続を確立するには、 の複数の操作で同じファクトリとクライアントオブジェクトを再利用することで、 を避けることができます。 (...) 同じ工場で作成されたすべてのクライアント(受信者に加えて送信者)は、1つのTCP接続を共有します。過渡障害処理について

QueueClientはその要求を再試行する必要があるかどうかを決定することをRetryPolicy propertyを持っています。また、Transient Fault Handling Application Blockもあり、一時的なフォルト処理フレームワークに取って代わります。メッセージについて

はガイダンスがImplementing Reliable Message Receive Loopsであり、ループを受けます。マイクロソフトでは、よく書かれた、復元力のあるメッセージ受信ループを実装することは難しいと認識しており、代わりにEvent-Driven Message Programing Modelを導入しました。

+1

優れたリンクありがとうございます。私はラッパーで[信頼できるメッセージ受信ループを実装する](http://msdn.microsoft.com/en-us/library/windowsazure/hh851750.aspx)を使用します。 'QueueClient'クラスが接続をオープンしない場合、 '.Receive()'のようなメソッドが呼び出されたときに自動的に処理されますか? –

+1

私は、推奨される使用パターンとTCP接続を扱うオブジェクトについての追加のドキュメントで答えを明確にしました。 –

+0

私の質問は、あなたが一見することができます場合は、この質問には感謝しています:http://stackoverflow.com/questions/33512803/service-bus-singleton-connection-class @フェルナンドコーリア – Ron