2013-07-11 79 views
9

我有一個圍繞Azure服務總線代碼的基本包裝,我們將在一個輔助角色中使用它。這個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在構造函數中:他們是那麼重用調用SendMessage()ReceiveTopMessage()與連接使用Dispose()方法關閉時。

我的問題是我使用的方法是否安全;將保持一個QueueClient的實例處於打開狀態,而工作者角色通過隊列上的所有消息枚舉(可以保持連接打開很長一段時間,在ReceiveTopMessage()的調用之間長時間等待)可以一致地工作,而不會出現瞬時問題,或者每次打開和關閉連接是否審慎?

另外;在Microsoft Service Bus代碼中如何進行瞬態故障處理?它是默認進行還是我們需要執行Transient Fault Handling Framework

回答

9

QueueClient class的使用由用於創建它的MessagingFactory對象管理的連接。建議爲多個請求重複使用相同的客戶端對象。如記錄在Best Practices for Performance Improvements Using Service Bus Brokered Messaging

服務總線使客戶通過兩個 協議來發送和接收消息:服務總線客戶端協議和HTTP。服務總線 客戶端協議更高效,因爲只要消息工廠存在,它就會將服務總線服務的連接 保留。它 也實現批處理和預取。服務總線客戶端 協議適用於使用.NET管理的 API的.NET應用程序。 (...) 服務總線客戶對象,如QueueClient或messageSender,和被 通過MessagingFactory對象,它也提供了連接的 內部管理創建。發送 消息後,您不應關閉工廠或隊列,主題和訂閱客戶端的消息,然後在發送下一條消息時重新創建它們。 關閉一個工廠的消息刪除到服務總線 服務的連接,並重新創建 工廠當建立新的連接。建立連接是一項昂貴的操作,通過爲多個操作重複使用相同的工廠和客戶端對象可以避免 。 (...) 所有的客戶,由 同一工廠共用一個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 @FernandoCorreia – Ron