《Windows Azure Platform 系列文章目录》
我们在基于Windows Azure进行云端开发的时候,云端的软件通常都需要与其他软件进行交互。这些其他软件可能包括其他Internet上的软件,或者内网的软件。
对于内网的软件来说,Azure提供Site-to-Site(S2S) VPN 和Point-to-Site(P2S) VPN的方式来打通Azure和内网应用程序之间的VPN连接。但是如果内网的应用程序使用了网络地址转换(NAT),S2S和P2S是无法支持在NAT背后的VPN Device。
Obtain an externally facing IPv4 IP for your VPN device. This IP address is required for a site-to-site configuration and is used for your VPN device, which cannot be located behind a NAT.
在这种情况下,Windows Azure 提供的Service Bus功能可以帮助用户解决以上的问题。
Service Bus基础
Service Bus是一种多租户的云服务,这意味着该服务可以由多个用户共享。每个用户(如应用程序开发人员)创建一个命名空间,然后定义用户在该命名空间内需要的通信机制。
Service Bus运行的架构图如下:
在命名空间内,用户可以使用三种不同通信机制的一个或者多个实例,每种机制使用不同方式连接应用程序。分别为:
-队列(Queue)。允许单向通信,每个队列均充当一个中介(有时称为代理),可存储发送的消息,直到它们被接收为止。
-主题(Topic)。使用订阅 提供单向通信。主题与队列一样可充当代理,但主题仅允许每个订阅查看符合特定条件的消息。
-中继(Relay)。提供双向通信。与队列和主题不同,中继不存储传送中的消息,它不是代理。相反,中继只是将消息传递到目标应用程序。
当您创建队列、主题或中继时,请对其进行命名。结合您对命名空间的任何命名,此名称可创建对象的唯一标识符。应用程序可将此名称提供给 Service Bus,然后使用队列、主题或中继相互通信。
若要使用任意这些对象,Windows 应用程序可使用 Windows Communication Foundation (WCF)。对于队列和主题,Windows 应用程序还可使用 Service Bus 定义的消息传递 API。也可通过 HTTP 访问队列和主题,并且为了更轻松地通过非 Windows 应用程序使用它们,Microsoft 提供了 Java、Node.js 和其他语言的 SDK。
即使 Service Bus 本身在云(即 Microsoft Windows Azure 数据中心)中运行,使用它的应用程序也能随处运行,了解这一点很重要。您可以使用 Service Bus 连接在 Windows Azure 上运行的应用程序或在您自己的数据中心内运行的应用程序。您也可以使用 Service Bus 通过本地应用程序或通过平板电脑和手机来连接在 Windows Azure 或其他云平台上运行的应用程序。甚至可以将家用电器、传感器和其他设备连接到*应用程序或其他应用程序。Service Bus 是云中的通用通信机制,几乎可从任何位置对其进行访问。使用 Service Bus 的方式取决于应用程序需要执行的操作。
队列
假设您决定使用 Service Bus 队列连接两个应用程序。图 2 说明了此情况。
Service Bus 队列图表
图 2:Service Bus 队列提供单向异步排队方法。
过程很简单:发送方将消息发送至 Service Bus 队列,接收方在随后的某个时间内接收该消息。一个队列只能有一位接收方,如图 2 所示,或者多个应用程序可从同一队列中读取消息。在后一种情况下,每条消息通常仅由一位接收方读取,队列不提供多播服务。
每条消息由两部分组成:每个键/值对一组属性和二进制消息正文。使用的方式取决于应用程序尝试执行的操作。例如,发送近期销售消息的应用程序可能包含属性 Seller="Ava" 和 Amount=10000。消息正文可能包含已签署的销售合同的扫描图像,如果不包含该合同,只需留空。
接收方可采用两种不同方式从 Service Bus 队列中读取消息。第一种方式称作 ReceiveAndDelete,即,从队列中移除消息并立即将其删除。此操作很简单,但如果接收者在完成处理消息之前崩溃,则该消息将丢失。因为消息已从队列中移除,所以接收方无法访问该消息。
第二种方式 PeekLock 旨在帮助解决这个问题。与 ReceiveAndDelete 一样,PeekLock 可从队列中移除消息。不过,它不会删除该消息。相反,它会锁定该消息,使其对其他接收方不可见,然后等待以下三个事件之一:
- 如果接收方成功处理了该消息,将调用“完成”,并且队列将删除该消息。
- 如果接收方判定它无法成功处理该消息,将调用“放弃”。队列即会解除对该消息的锁定,使其可供其他接收方使用。
- 如果接收方在可配置时间段(默认为 60 秒)内没有调用这两个命令,队列将假定接收方失败。在这种情况下,队列的行为就像接收方已调用“放弃”一样,即,使消息可供其他接收方使用。
请注意,可能发生的情况:同一条消息可能被发送两次,即,或许将其发送给两个不同的接收方。使用 Service Bus 队列的应用程序必须为此做好准备。为了更轻松地进行重复检测,每条消息都拥有一个唯一的 MessageID 属性,无论从队列中读取消息多少次,该属性默认情况下始终保持不变。
队列在很多情况下都非常有用。即使两个应用程序没有同时运行,队列也可使这两个应用程序之间相互通信,这对于批处理和移动应用程序尤为方便。当所发送的消息传播给多个接收方时,具有这些接收方的队列还提供自动负载平衡。
主题
队列虽然在一些情况下有用,但并非总是正确的解决方案。有时,Service Bus 主题更好。图 3 说明了这一点。
Service Bus 主题和订阅图表
图 3:根据订阅应用程序指定的筛选器,它可接收发送至 Service Bus 主题的部分或全部消息。
主题在很多方面与队列类似。发送方将消息提交至主题的方式与将消息提交至队列的方式相同,这些消息与使用队列的消息看起来一样。最大的区别是主题让每个接收应用程序通过定义筛选器 创建其自己的订阅。然后,订户将只能看到与该筛选器匹配的消息。例如,图 3 显示一个发送方以及一个具有三个订户的主题,每个订户都拥有自己的筛选器:
- 订户 1 仅接收包含 Seller="Ava" 属性的消息。
- 订户 2 接收包含 Seller="Ruby" 属性和/或值大于 100,000 的 Amount 属性的消息。Ruby 或许是销售经理,因此她希望查看她自己的销售以及其他人做的所有大单销售。
- 订户 3 将其筛选器设置为 True,这意味着它将接收所有消息。例如,此应用程序可能负责维护和审核记录,因此它需要查看全部内容。
与队列一样,某主题的订户可使用 ReceiveAndDelete 或 PeekLock 读取消息。不过与队列不同的是,发送至主题的单个消息可由多个订户接收。此方法通常称作发布和订阅,在当多个应用程序对相同消息感兴趣时非常有用。通过定义适当的筛选器,每位订户可以只访问需要查看的消息流部分。
中继
队列和主题均通过代理提供单向异步通信。流量只按一个方向流动,发送方和接收方之间没有直接连接。但如果您不希望这样,该怎么办?假设您的应用程序需要同时发送和接收消息,或者可能您希望应用程序之间进行直接链接,而不需要在某个位置来存储两者之间的消息。为解决此类问题,Service Bus 提供了中继,如图 4 所示。
Service Bus 中继图表
图 4:Service Bus 中继提供应用程序之间的同步双向通信。
关于中继明显要问的问题是:为何我要使用中继?即使我不需要队列,那么为什么要通过云服务进行应用程序通信,而非直接交互?答案是直接对话比您想象的更艰难。
假设您希望连接两个本地应用程序,这两个应用程序均在企业数据中心中运行。每个应用程序都位于防火墙之后,并且每个数据中心很可能使用网络地址转换 (NAT)。防火墙阻止几乎所有端口上的传入数据,并且 NAT 意味着运行每个应用程序的计算机很可能没有固定 IP 地址。如果不借助一些额外的帮助,那么通过公共 Internet 连接这些应用程序会产生问题。
Service Bus 中继可提供此帮助。若要通过中继进行双向通信,每个应用程序需使用 Service Bus 建立出站 TCP 连接,然后一直保持打开状态。将通过这些连接传输两个应用程序之间的全部通信。由于每个连接均从数据中心内部建立,因此,防火墙将允许到每个应用程序的传入流量(即通过中继发送的数据),而无需打开新端口。此方法还能解决 NAT 问题,因为每个应用程序在整个通信中的终结点是一致的。通过中继交换数据,应用程序可以避免导致通信困难的问题。
为使用 Service Bus 中继,应用程序依赖 Windows Communication Foundation (WCF)。Service Bus 提供 WCF 绑定,可使 Windows 应用程序通过中继进行交互变得更加简单。已使用 WCF 的应用程序通常只需指定其中一个绑定,即可通过中继进行交互。不过与队列和主题不同,从非 Windows 应用程序使用中继(如有可能)需要一些编程工作;没有标准库提供。
与队列和主题不同,应用程序不会显式创建中继。相反,当希望接收消息的应用程序与 Service Bus 建立 TCP 连接时,会自动创建中继。当该连接中断时,将删除该中继。为了让应用程序能够找到由特定侦听程序创建的中继,Service Bus 提供了允许按名称定位特定中继的注册表。
当您需要直接通信时,中继是正确的解决方案。例如,在本地数据中心中运行的航空订票系统,可从值机柜台、移动设备和其他计算机*问该系统。在所有这些系统上运行的应用程序都可能依赖云中的 Service Bus 中继进行通信,无论它们在哪里运行。
连接应用程序始终属于构建完整解决方案的一部分,很难看到此问题永远消失。通过提供可实现此目的的基于云的技术(即队列、主题和中继),Service Bus 旨在让此基本功能更加简单且使用范围更加广泛。
参考资料:http://www.windowsazure.cn/zh-cn/develop/net/fundamentals/hybrid-solutions/#Fig2