繁体   English   中英

重用Azure Service Bus中的连接

[英]Reusing Connections in Azure Service Bus

我们在Windows Azure上以Web角色托管了一个API,其中有2个实例接收请求,验证它们然后将它们添加到Azure Service Bus队列。

最近我们开始加载测试,发现我们当前的代码抛出以下异常:

无法向命令队列添加命令异常:Microsoft.ServiceBus.Messaging.QuotaExceededException:已达到或超过队列的最大连接数。活动连接数:100,允许的最大连接数:100。

假设我们维护了一个类的实例,下面的客户端代码是否会保持单个连接打开? 我试图确定问题是与ServiceBusClient代码或我们的依赖注册是否为每个请求初始化一个新客户端。

public class ServiceBusClient : IDisposable
{
    #region Constants and Fields

    protected readonly NamespaceManager NamespaceManager;

    private const int DEFAULT_LOCK_DURATION_IN_SECONDS = 300; // 5 minutes 

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

    private readonly IMessageBodySerializer _messageBodySerializer;

    private readonly MessagingFactory _messagingFactory;

    private readonly QueueClient _queueClient;

    private readonly string _queueName;

    private readonly ISettingsManager _settingsManager;

    #endregion

    #region Constructors and Destructors

    public ServiceBusClient(
        ISettingsManager settingsManager, 
        IMessageBodySerializer messageBodySerializer, s
        tring queueName)
    {
        _settingsManager = settingsManager;
        _messageBodySerializer = messageBodySerializer;

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

        NamespaceManager = 
            NamespaceManager.CreateFromConnectionString(connectionString);

        _messagingFactory = 
            MessagingFactory.CreateFromConnectionString(connectionString);

        _queueName = queueName;
        _queueClient = GetOrCreateQueue();
    }

    #endregion

    #region Public Methods and Operators

    public virtual void SendMessage(object bodyObject)
    {
        var brokeredMessage = 
            _messageBodySerializer.SerializeMessageBody(bodyObject);

        _queueClient.Send(brokeredMessage);
    }

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

    #endregion

    #region Methods

    private QueueClient GetOrCreateQueue()
    {
        QueueDescription queue;

        if (!NamespaceManager.QueueExists(_queueName))
        {
            var queueToCreate = new QueueDescription(_queueName)
            {
                LockDuration = TimeSpan.FromSeconds(
                    DEFAULT_LOCK_DURATION_IN_SECONDS)
            };

            queue = NamespaceManager.CreateQueue(queueToCreate);
        }
        else
        {
            queue = NamespaceManager.GetQueue(_queueName);
        }

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

    #endregion
}

作为对此的延伸; 如果上面的代码确实保持活动连接打开; 将使用单例模式为每个API实例存储ServiceBusClient的实例是危险的吗? 或者Azure SDK是否在内部处理封闭连接?

从连接管理的角度来看,以下可能会有所帮助:

1)为MessagingFactory实例创建单个连接

2)您可以从单个MessagingFactory创建尽可能多的QueueClient实例,但它们都将使用相同的实际底层TCP连接,因此请考虑吞吐量和可用性,因为更多连接可以帮助

3)我们将重新连接MessagingFactory的底层连接,以防它被删除

4)从QueueClient角度来看,您正在创建与特定队列的连接,请考虑这些链接(其中一些链接可以存在于单个MessagingFactory连接上)。 再次,如果连接被删除,它将被重新创建,因此将是队列的链接,您不需要重新创建对象

5)每个队列强加100个并发连接的配额,所以基本上你可以有多达100个链接到一个队列

6)这些不受您创建这些链接的MessagingFactory实例的影响

7)如果你在MessagingFactory上调用close / dispose,那么该连接上的所有链接也将被关闭,不会重新连接

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM