服务总线 - 辛格尔顿连接类? [英] Service Bus - Singleton Connection Class?

查看:139
本文介绍了服务总线 - 辛格尔顿连接类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图弄清楚什么是使用服务总线从Web-API的最佳做法。

I'm trying to figure out what is the best practice for using Service Bus from a Web-API.

我读过,重新创造一个像QueueClient,SubscriptionClient等对象'是错误的做法,所以我需要重用的工厂和客户。

I've read that re-creating objects like QueueClient, SubscriptionClient and etc' is the wrong approach, so I need to reusing factories and clients.

服务总线客户对象,如Microsoft.ServiceBus.Messaging.QueueClient或Microsoft.ServiceBus.Messaging.MessageSender,通过一个MessagingFactory对象,它也提供了连接的内部管理创建。你不应该在关闭工厂的消息或队列,主题和订阅的客户端发送消息,然后当你发送一个消息重新创建它们。关闭工厂的消息删除到服务总线服务的连接,并重新出厂的时候建立一个新的连接。建立连接是可以通过重复使用相同的工厂和客户对象为多个操作可避免昂贵的操作

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.

参考

我需要实现一个特殊的类,将坚持服务总线的连接,我在想这会持有特定操作(功能如 EnqueueJobToArchiveQueue(工作职位)一个Singleton类和构造函数将初始化将由具体操作的功能。

I need to implement a special class that will hold the connection to the Service Bus, I was thinking about a Singleton class that will holds specific operation (function like EnqueueJobToArchiveQueue(Job job) and the Constructor will initialize the QueueClient, MessageFactory and etc' which will be used by the "specific operation function".

我的问题是,我需要关闭的对象( QueueClient.Close()),什么时候需要关闭对象?

My problem is that I need to close the objects (QueueClient.Close()), When do I need to close the object ?

下面是我班至今:

 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()),我应该在哪里关闭连接?实现与处置的IDisposable接口()?

如果有,如果你能与我分享一个更好的方法,我AP preciate。

If there is a better approach I appreciate if you could share it with me.

这code是一个Web的API(Azure的云服务),一个体面的工作负载。

This code is from a Web-API (Azure Cloud Service) with a decent workload.

更新

我已经更新我的类的Dispose()如下:

I've update my class with Dispose() as follow:

     public void Dispose()
     {
         if (msgFactory != null)
         {
             msgFactory.Close();
         }

     } 


推荐答案

默认底层协议由服务总线SDK中使用的是,在该关闭的TCP / IP连接的顶部工作专有SBMP(服务总线消息协议)当您关闭了工厂。
如果您选择使用TransportType = AMQP(在连接字符串中),你可以切换到AMQP协议。在这种情况下,工厂处理唯一的TCP连接到总线和QueueClient,TopicClient类(从工厂创建的)实例的会话和上述TCP连接内的链接。会话和链路是用于复用单一的TCP连接上的两个AMQP概念。
如果您只关闭QueueClient和TopicClient,合闸操作仅关闭相关会议,并链接,但不是当你关闭工厂对象被关闭TCP连接。
当然,我不知道SBMP的内部工作原理,因为它是一个专有协议。
然而,在脱手,你可以关闭工厂和相关的队列/主题的对象。
什么是你的问题?

The default underlying protocol used by the Service Bus SDK is the proprietary SBMP (Service Bus Messaging Protocol) that works on top of a TCP/IP connection that is closed when you close the factory. If you choose to use TransportType=Amqp (in the connection string) you can switch to the AMQP protocol. In that case, the factory handles the unique TCP connection to the bus and the QueueClient, TopicClient classes (created from the factory) instantiate a session and a link inside the above TCP connection. Session and link are two AMQP concepts used to multiplex on the single TCP connection. If you close only QueueClient and TopicClient, the closing operation closes only related session and link but not the TCP connection that is closed when you close the factory object. Of course I don't know how SBMP works internally because it's a proprietary protocol. However, in a dispose you could close factory and related queue/topic objects. What's your problem ?

这篇关于服务总线 - 辛格尔顿连接类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆