Azure Service Bus客户端连接持久性

时间:2013-07-11 08:27:26

标签: c# azure client azureservicebus

我有一个围绕Azure Service Bus代码的基本包装器,我们将在一个辅助角色中使用它。每次运行辅助角色时,都会实例化ServiceBusClient;然后用来访问队列,直到没有剩余的项目进行枚举。

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

1 个答案:

答案 0 :(得分:11)

QueueClient class使用由用于创建它的MessagingFactory对象管理的连接。建议为多个请求重用相同的客户端对象。如Best Practices for Performance Improvements Using Service Bus Brokered Messaging中所述:

  

Service Bus使客户端能够通过两个发送和接收消息   协议:Service Bus客户端协议和HTTP。服务总线   客户端协议更有效,因为它维护连接   只要消息工厂存在,就可以使用Service Bus服务。它   还实现了批处理和预取。服务总线客户端   协议适用于使用.NET托管的.NET应用程序   API。   (......)   Service Bus客户端对象,例如QueueClient或MessageSender   通过MessagingFactory对象创建,该对象也提供   连接的内部管理。你不应该关闭消息   发送后的工厂或队列,主题和订阅客户端   消息,然后在发送下一条消息时重新创建它们。   关闭消息传递工厂会删除与Service Bus的连接   服务,并在重新创建时建立新连接   厂。建立连接是一项昂贵的操作   通过重复使用相同的工厂和客户端对象来避免   多个操作。   (......)   除了接收者之外的所有客户端(发送者除了接收者)   同一工厂共享一个TCP连接。

关于瞬态错误处理,QueueClient有一个RetryPolicy property,用于确定是否应重试请求。还有Transient Fault Handling Application Block,它取代了瞬态故障处理框架。

关于消息接收循环,Implementing Reliable Message Receive Loops中有指导。微软已经认识到很难实现一个写得很好,有弹性的消息接收循环,所以他们引入了Event-Driven Message Programing Model作为替代。