2013-07-11 10 views
9

mam poniżej podstawowego owinięcia wokół kodu Azure Service Bus, że będziemy z użyciem w roli pracownika. Ta ServiceBusClient zostanie utworzona za każdym razem, gdy uruchomiona zostanie rola robocza; następnie używany do uzyskania dostępu do kolejki, dopóki nie pozostały żadne pozostałe elementy do wyliczenia.Azure Service Bus Connection Client Trwałość

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); 
    } 

} 

Jak widać ja zainicjalizować NamespaceManager, MessagingFactory i QueueClient wewnątrz konstruktora: są następnie ponownie wykorzystywane podczas wywoływania SendMessage() i ReceiveTopMessage() z połączeniem zamknięte stosując metodę Dispose().

Moje pytanie brzmi, czy podejście, które stosuję, to bezpieczne; będzie utrzymanie pojedynczą instancję QueueClient otwarte podczas roli pracownika wylicza poprzez wszystkie wiadomości w kolejce (proces, który mógłby utrzymać połączenie otwarte przez dłuższy czas z długim oczekiwaniu pomiędzy wywołaniami ReceiveTopMessage()) działają konsekwentnie bez przejściowych problemów, lub czy rozsądne jest każdorazowe otwieranie i zamykanie połączenia?

Jak z boku; w jaki sposób przebiega obsługa błędów przejściowych w kodzie usługi Microsoft Service Bus? Czy jest przeprowadzane domyślnie, czy też musimy wdrożyć Transient Fault Handling Framework?

Odpowiedz

9

QueueClient class wykorzystuje połączenie, które jest zarządzane przez MessagingFactory obiektu użytego do jego utworzenia. Zaleca się ponowne użycie tego samego obiektu klienta dla wielu żądań. Jak udokumentowano w Best Practices for Performance Improvements Using Service Bus Brokered Messaging:

Service Bus pozwala klientom na wysyłanie i odbieranie wiadomości za pośrednictwem dwóch protokoły: Protokół klienta Service Bus i HTTP. Protokół klienta usługi Bus Service jest bardziej wydajny, ponieważ utrzymuje połączenie z usługą Service Bus, o ile istnieje fabryka wiadomości. To również implementuje grupowanie i prefetchowanie. Protokół klienta magistrali usług jest dostępny dla aplikacji .NET przy użyciu interfejsu API zarządzanego .NET .NET. (...) Obiekty klienta usługi Bus Bus, takie jak QueueClient lub MessageSender, są utworzone za pomocą obiektu MessagingFactory, który zapewnia również wewnętrzne zarządzanie połączeniami. Po wysłaniu wiadomości nie powinieneś zamykać komunikatów o wiadomościach ani klientów oczekujących na kolejkę, temat i subskrypcję, a następnie ponownie je tworzyć po wysłaniu następnej wiadomości. Zamknięcie fabryki wiadomości kasuje połączenie z Autobus Service, a nowe połączenie zostanie nawiązane, gdy odtwarzając fabrykę . Nawiązanie połączenia jest kosztowną operacją, której można uniknąć, unikając ponownego użycia tych samych obiektów fabrycznych i klientów dla wielu operacji. (...) Wszyscy klienci (nadawcy oprócz odbiorców), którzy są tworzeni przez tę samą fabrykę, mają jedno połączenie TCP.

chodzi nieustalonych obsługi błędów, QueueClient ma RetryPolicy property że określa, czy żądanie powinno zostać ponowione. Istnieje również Transient Fault Handling Application Block, który zastępuje Strukturę Obniżania Uszkodzeń.

chodzi otrzymać wiadomość pętle, jest poradnictwo w Implementing Reliable Message Receive Loops.Microsoft uznał, że trudno jest wdrożyć dobrze napisaną, elastyczną pętlę odbierania komunikatów, więc wprowadzili jako alternatywę Event-Driven Message Programing Model.

+1

Doskonałe linki dziękuję; Będę używał [Implement Reliable Message Receive Loops] (http://msdn.microsoft.com/en-us/library/windowsazure/hh851750.aspx) w naszym opakowaniu. Jeśli klasa 'QueueClient' nie otworzy połączenia; czy jest to obsługiwane automatycznie, gdy wywoływana jest metoda taka jak '.Receive()'? –

+1

Wyjaśniłem moją odpowiedź z dodatkową dokumentacją dotyczącą zalecanego wzorca użytkowania i który obiekt obsługuje połączenie TCP. –

+0

Moje pytanie jest związane z tym pytaniem, nie doceniam, jeśli możesz rzucić okiem: http://stackoverflow.com/questions/33512803/service-bus-singleton-connection-class @FernandoCorreia – Ron