我们在Windows Azure上以Web角色托管了一个API,其中有2个实例接收请求,验证它们然后将它们添加到Azure Service Bus队列。
最近我们开始加载测试,发现我们当前的代码抛出以下异常:
无法将命令添加到命令队列 例外: Microsoft.ServiceBus.Messaging.QuotaExceededException: 已达到或超过Queue的最大连接数 活动连接数: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是否在内部处理已关闭的连接?
答案 0 :(得分:10)
从连接管理的角度来看,以下内容可能会有所帮助:
1)为MessagingFactory实例创建单个连接
2)您可以从单个MessagingFactory创建尽可能多的QueueClient实例,但它们都将使用相同的实际底层TCP连接,因此请考虑吞吐量和可用性,因为更多连接可以提供帮助
3)我们将重新连接MessagingFactory的基础连接,以防它被删除
4)从QueueClient角度来看,您正在创建与特定队列的连接,请考虑这些链接(其中一些链接可以存在于单个MessagingFactory连接上)。再次,如果连接被删除,它将被重新创建,因此将是队列的链接,您不需要重新创建对象
5)每个队列强加100个并发连接的配额,所以基本上你最多可以有100个链接到一个队列
6)这些不受您通过
创建这些链接的MessagingFactory实例数的影响7)如果你在MessagingFactory上调用close / dispose,那么该连接上的所有链接也将被关闭,不会重新连接