2013-07-11 3 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); 
    } 

} 

당신은 내가 생성자 내부의 NamespaceManager, MessagingFactoryQueueClient를 초기화 볼 수 있듯이 : 연결이 Dispose() 방법을 사용하여 폐쇄와 SendMessage()ReceiveTopMessage()를 호출 할 때 그들은 다음 재사용된다.

내 질문은 내가 사용하고있는 접근 방식이 안전인지 여부입니다.; 의 단일 인스턴스를 열어 놓고 작업자 역할은 대기열에있는 모든 메시지를 열거합니다 (잠시 기다리면서 연결을 잠시 동안 열어 둘 수있는 프로세스 인 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 연결을 공유합니다.

QueueClientRetryPolicy property이며 요청을 다시 시도해야하는지 여부를 결정합니다. Transient Fault Handling Framework를 대체하는 Transient Fault Handling Application Block도 있습니다.

메시지 수신 루프에 대해서는 Implementing Reliable Message Receive Loops에 지침이 있습니다.Microsoft는 잘 작성되고 탄력적 인 메시지 수신 루프를 구현하기가 어렵다는 것을 알고 있으므로 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