簡體   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