李甲蔚

你创想,云实现

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

什么是Service Bus Queues

Service Bus Queue提供了"Brokered"消息通信模式。当使用Queues的时候,分布式应用的组件之间并不是直接通信,而是通过作为中介角色的Queue来交换消息。消息生产者将消息发送至Queue,而消息消费者从Queue中获取消息并处理。生产者可以连续不断地发送消息,并不需要等待消费者的返回响应信息,发送方和接收方完全是异步模式。并且和传统的队列一样,Service Bus Queue遵循先进先出的规则。

如图所示,Service Bus Queues位于云端,而生产者和消费者可以位于任何地方,可以位于云端,可以在企业数据中心内部,可以位于个人PC,也可以是移动的,部署在移动设备上,而这些终端通过Queue建立彼此之间的联系。

为什么使用Service Bus Queues

在涉及代码之前我们来看一看Service Bus Queues有哪些优势,为什么或者是在什么情况下我们需要使用Service Bus Queues。

Temporal decoupling(时间解耦?)

Temporal decoupling意思就是消息生产者和消费者没有必要同时在线,发送的消息将被存储在Service Bus中,消费者在需要的时候上线获取消息就行。

Loose Coupling(松耦合)

生产者与消费者不会互相干预,完全是独立的应用,一方出现问题并不影响另一方的执行,体现了各组件之间松耦合的设计模式。

平衡负载量

为什么会涉及负载的相关功能?我们来做个对比。假设使用Web service部署服务,两端的通讯通过调用web服务来完成,则在高峰期,web服务所在机器会因访问过多而造成非常大的负载,而在闲散时间负载水平又非常低,所以这时负载情况如下图中的曲线所示。而如果使用Service Bus Queue来实现两端的数据通信,消费者从Queue中不断获取消息并处理,如果处理能力强,则单位时间内处理的消息多,否则较少,所以消费者所在机器不会出现峰值的情况,而是一条直线,既能保证业务正常处理,又能充分利用服务器的资源,所以可以说实现了均衡负载量的功能。

负载均衡

接着上面说,一个消费者处理能力有限,我们完全可以增加多个消费者来从Queue中读取消息并进行处理,多个消费者可以并行处理,并且保证每个消息只处理一次。这个模式完全是负载均衡的模式,而且自动实现了负载均衡,并不需要任何的路由策略。

 

如何使用Service Bus Queues

如需使用Service Bus Queue,首先需要在项目中引用Service Bus程序集,可通过Manage NuGet Packages搜索Service Bus的最新版本并添加引用。添加引用之后,将自动为项目Config文件添加Service Bus终结点配置:

   1: <appSettings>
   2:     <!-- Service Bus specific app setings for messaging connections -->
   3:     <add key="Microsoft.ServiceBus.ConnectionString" value="Endpoint=sb://[yourdomain].servicebus.windows.net/;SharedSecretIssuer=owner;SharedSecretValue=[yourkey]" />
   4:  </appSettings>

在进行Queue操作时,将自动根据这个配置连接位于云端的Service Bus,当然我们也可以在运行时通过代码设定配置。

创建Service Bus Queue

   1: string queueName = "MyQueue";
   2: NamespaceManager namespaceClient = NamespaceManager.Create();
   3: QueueDescription myQueue = null;
   4: if (!namespaceClient.QueueExists(queueName))
   5: {
   6:     myQueue = namespaceClient.CreateQueue(queueName);
   7: }
   8: else
   9: {
  10:     myQueue = namespaceClient.GetQueue(queueName);
  11: }

发送消息

首先创建QueueClient对象

   1: MessagingFactory factory = MessagingFactory.Create();
   2: QueueClient myQueueClient = factory.CreateQueueClient("MyQueue");

然后创建消息对象BrokeredMessage,在消息传输中,所有消息内容都需要封装成BrokeredMessage对象

   1: BrokeredMessage message = new BrokeredMessage();
   2: message.Label = "SalesReport";
   3: message.Properties.Add("Name", "Steven");
   4: message.Properties.Add("Email", "Steven@hotmail.com");
   5: message.Properties.Add("ProductCode", "P476534");
   6: message.Properties.Add("Count", 1);

最后发送消息

   1: myQueueClient.Send(message);

接收消息

首先创建QueueClient对象

   1: string queueName = "MyQueue";
   2: MessagingFactory factory = MessagingFactory.Create();
   3: QueueClient myQueueClient = factory.CreateQueueClient(queueName, ReceiveMode.PeekLock);

我们注意到在创建客户端时,使用了一个参数:ReceiveMode,这个参数决定了消息的接收方式,ReceiveMode枚举定义如下:

   1: public enum ReceiveMode
   2: {
   3:     PeekLock,
   4:     ReceiveAndDelete
   5: }

ReceiveAndDelete,顾名思义,当客户端接收完消息以后,该消息即从队列中移除,其他客户端无法获取该消息。在这种模式下,消息最多被处理一次,但是处理过程中可能出现异常导致处理失败,所以这种模式适合应用可以容忍消息处理失败的情景中。

PeerLock,ReceiveMode的默认值,当客户端接收消息以后,并不移除,而是给消息上锁,此时其他客户端无法获取该消息。锁的过期时间默认为1分钟,可以自定义设置,最大可以设置为5分钟。如果处理成功,可以将消息从队列中移除(Complete),如果失败,可以将锁移除(Abandon),使得消息可以被其他客户端接收并处理。当应用无法容忍消息处理失败时,使用这种模式更为安全。

接收消息

   1: BrokeredMessage message = myQueueClient.Receive();
   2: if (message != null)
   3: {
   4:     try
   5:     {
   6:         ProcessMessage(message);
   7:  
   8:         message.Complete();
   9:     }
  10:     catch
  11:     {
  12:         message.Abandon();
  13:     }
  14: }

在具体例子中使用了两个Winform客户端程序来分别模拟发送方和接收方,点击 这里 下载源码。

posted on 2013-01-21 13:48  李甲蔚  阅读(1738)  评论(0编辑  收藏  举报