服务总线 - 单例连接 Class?
Service Bus - Singleton Connection Class?
我试图弄清楚从 Web 使用服务总线的最佳实践是什么-API。
我了解到重新创建 QueueClient、SubscriptionClient 等对象是错误的方法,因此我需要重用工厂和客户端。
Service Bus client objects, such as Microsoft.ServiceBus.Messaging.QueueClient or Microsoft.ServiceBus.Messaging.MessageSender, are created through a MessagingFactory object, which also provides internal management of connections. You should not close messaging factories or queue, topic, and subscription clients after you send a message, and then re-create them when you send the next message. Closing a messaging factory deletes the connection to the Service Bus service, and a new connection is established when recreating the factory. Establishing a connection is an expensive operation that can be avoided by re-using the same factory and client objects for multiple operations.
我需要实现一个特殊的 class 来保持与服务总线的连接,我正在考虑一个 Singleton class 来保持特定的操作(功能如 EnqueueJobToArchiveQueue(Job job)
构造函数将初始化 "specific operation function".
将使用的 QueueClient、MessageFactory 等。
我的问题是我需要关闭对象(QueueClient.Close()
),什么时候需要关闭对象?
到目前为止,这是我的 class:
public class ServiceBusHelper
{
private static readonly ServiceBusHelper instance = new ServiceBusHelper();
private static MessagingFactory msgFactory;
private static NamespaceManager namespaceManager;
private const string jobQueueName = "job";
private const string responseTopicName = "jobResult";
private const string archiveQueueName = "jobArchive";
private static QueueClient archiveQueue;
private static QueueClient jobQueue;
private static TopicClient responseTopic;
private ServiceBusHelper()
{
}
static ServiceBusHelper()
{
msgFactory = MessagingFactory.CreateFromConnectionString(ConfigurationManager.AppSettings["ServiceBusCS"]);
namespaceManager = NamespaceManager.CreateFromConnectionString(ConfigurationManager.AppSettings["ServiceBusCS"]);
if (!namespaceManager.QueueExists(jobQueueName))
{
namespaceManager.CreateQueue(jobQueueName);
}
filteringQueue = QueueClient.CreateFromConnectionString(ConfigurationManager.AppSettings["ServiceBusCS"], jobQueueName);
if (!namespaceManager.QueueExists(archiveQueueName))
{
namespaceManager.CreateQueue(archiveQueueName);
}
archiveQueue = QueueClient.CreateFromConnectionString(ConfigurationManager.AppSettings["ServiceBusCS"], archiveQueueName);
if (!namespaceManager.TopicExists(responseTopicName))
{
namespaceManager.TopicExists(responseTopicName);
}
responseTopic = TopicClient.CreateFromConnectionString(ConfigurationManager.AppSettings["ServiceBusCS"],responseTopicName);
}
public static ServiceBusHelper Instance
{
get
{
return instance;
}
}
public void EnququeJobToDo(Job job, string corrId)
{
// Compose the message
BrokeredMessage msg = new BrokeredMessage(job);
msg.CorrelationId = corrId;
// Send the message
filteringQueue.Send(msg);
}
}
如您所见,我没有关闭连接(QueueClient.Close()
),我应该在哪里关闭连接?使用 Dispose() ?
实现 IDisposable
如果有更好的方法,请与我分享。
此代码来自具有良好工作负载的 Web-API(Azure 云服务)。
更新
我已经用 Dispose()
更新了我的 class 如下:
public void Dispose()
{
if (msgFactory != null)
{
msgFactory.Close();
}
}
服务总线 SDK 使用的默认基础协议是专有的 SBMP(服务总线消息传递协议),它在关闭工厂时关闭的 TCP/IP 连接之上工作。
如果您选择使用 TransportType=Amqp(在连接字符串中),您可以切换到 AMQP 协议。在这种情况下,工厂处理与总线的唯一 TCP 连接,并且 QueueClient、TopicClient 类(从工厂创建)在上述 TCP 连接中实例化会话和 link。 Session 和 link 是两个 AMQP 概念,用于在单个 TCP 连接上进行多路复用。
如果仅关闭 QueueClient 和 TopicClient,则关闭操作仅关闭相关会话和 link 而不会关闭关闭工厂对象时关闭的 TCP 连接。
当然我不知道 SBMP 内部是如何工作的,因为它是一个专有协议。
但是,在处置中,您可以关闭工厂和相关的 queue/topic 对象。
你有什么问题?
我试图弄清楚从 Web 使用服务总线的最佳实践是什么-API。
我了解到重新创建 QueueClient、SubscriptionClient 等对象是错误的方法,因此我需要重用工厂和客户端。
Service Bus client objects, such as Microsoft.ServiceBus.Messaging.QueueClient or Microsoft.ServiceBus.Messaging.MessageSender, are created through a MessagingFactory object, which also provides internal management of connections. You should not close messaging factories or queue, topic, and subscription clients after you send a message, and then re-create them when you send the next message. Closing a messaging factory deletes the connection to the Service Bus service, and a new connection is established when recreating the factory. Establishing a connection is an expensive operation that can be avoided by re-using the same factory and client objects for multiple operations.
我需要实现一个特殊的 class 来保持与服务总线的连接,我正在考虑一个 Singleton class 来保持特定的操作(功能如 EnqueueJobToArchiveQueue(Job job)
构造函数将初始化 "specific operation function".
我的问题是我需要关闭对象(QueueClient.Close()
),什么时候需要关闭对象?
到目前为止,这是我的 class:
public class ServiceBusHelper
{
private static readonly ServiceBusHelper instance = new ServiceBusHelper();
private static MessagingFactory msgFactory;
private static NamespaceManager namespaceManager;
private const string jobQueueName = "job";
private const string responseTopicName = "jobResult";
private const string archiveQueueName = "jobArchive";
private static QueueClient archiveQueue;
private static QueueClient jobQueue;
private static TopicClient responseTopic;
private ServiceBusHelper()
{
}
static ServiceBusHelper()
{
msgFactory = MessagingFactory.CreateFromConnectionString(ConfigurationManager.AppSettings["ServiceBusCS"]);
namespaceManager = NamespaceManager.CreateFromConnectionString(ConfigurationManager.AppSettings["ServiceBusCS"]);
if (!namespaceManager.QueueExists(jobQueueName))
{
namespaceManager.CreateQueue(jobQueueName);
}
filteringQueue = QueueClient.CreateFromConnectionString(ConfigurationManager.AppSettings["ServiceBusCS"], jobQueueName);
if (!namespaceManager.QueueExists(archiveQueueName))
{
namespaceManager.CreateQueue(archiveQueueName);
}
archiveQueue = QueueClient.CreateFromConnectionString(ConfigurationManager.AppSettings["ServiceBusCS"], archiveQueueName);
if (!namespaceManager.TopicExists(responseTopicName))
{
namespaceManager.TopicExists(responseTopicName);
}
responseTopic = TopicClient.CreateFromConnectionString(ConfigurationManager.AppSettings["ServiceBusCS"],responseTopicName);
}
public static ServiceBusHelper Instance
{
get
{
return instance;
}
}
public void EnququeJobToDo(Job job, string corrId)
{
// Compose the message
BrokeredMessage msg = new BrokeredMessage(job);
msg.CorrelationId = corrId;
// Send the message
filteringQueue.Send(msg);
}
}
如您所见,我没有关闭连接(QueueClient.Close()
),我应该在哪里关闭连接?使用 Dispose() ?
如果有更好的方法,请与我分享。
此代码来自具有良好工作负载的 Web-API(Azure 云服务)。
更新
我已经用 Dispose()
更新了我的 class 如下:
public void Dispose()
{
if (msgFactory != null)
{
msgFactory.Close();
}
}
服务总线 SDK 使用的默认基础协议是专有的 SBMP(服务总线消息传递协议),它在关闭工厂时关闭的 TCP/IP 连接之上工作。 如果您选择使用 TransportType=Amqp(在连接字符串中),您可以切换到 AMQP 协议。在这种情况下,工厂处理与总线的唯一 TCP 连接,并且 QueueClient、TopicClient 类(从工厂创建)在上述 TCP 连接中实例化会话和 link。 Session 和 link 是两个 AMQP 概念,用于在单个 TCP 连接上进行多路复用。 如果仅关闭 QueueClient 和 TopicClient,则关闭操作仅关闭相关会话和 link 而不会关闭关闭工厂对象时关闭的 TCP 连接。 当然我不知道 SBMP 内部是如何工作的,因为它是一个专有协议。 但是,在处置中,您可以关闭工厂和相关的 queue/topic 对象。 你有什么问题?