物联网

使用 Windows Azure 服务总线处理 ... 设备!

Clemens Vasters

 

如果您这些天逛逛(或浏览)品类齐全的电器商店,您会发现大量可连接到网络上的“设备”。 不要光想着是手机、平板电脑、笔记本或台式机,也不要以为是电视、蓝光播放器和机顶盒。 它们可能是咖啡机、冰箱和画框。 它们也可能是车库门遥控器、空调和报警系统。 如果您看看工业或商业环境(如您自己的办公楼)中的挡板周围和后面,您就会发现温度和湿度传感器、运动传感器、监视摄像头和很多其他类型的传感器或设备内部控制开关。

其中的很多设备会生成非常有用的数据: 温度读数;煮好的咖啡杯数以及如何设置研磨器;显示没人在会议室并因而可以关灯的红外线图像。 

也可以很容易想象您希望将一些数据上载到“设备”的应用场景,例如,将您的孩子(或宠物)的最新照片推送到奶奶家的餐柜上面的画框,或者想象您希望从远处打开开关以将屋里的温度调高一点的应用场景,即使“远处”仅仅是指通过 3G/4G 移动运营商网络连接的手机。 从网络的角度看,在家里打开开关与度假两周后从机场回家途中在出租车里打开开关相差三个世界的距离,但从用户的角度看,没有明显的差别。

连接的设备所蕴含的商机是非常巨大的。 对于有远见的云开发商来说,为专用设备提供服务蕴含的商业潜力可能确实比针对人际互动量身定制的通用屏幕设备上的应用程序大得多,例如,手机、平板电脑或很多 PC 机型。 当您将此类服务与围绕“大数据”分析出现的新兴云技术相结合时,这种情况尤其如此。

应用场景

为了方便下面的体系结构讨论,让我们想象一下提供的服务是用于空调的软件即服务 (SaaS)。 虽然应用场景以及所有数字都是虚构的,但模式和规模与 Windows Azure 团队同合作伙伴和客户讨论的实际情况非常接近。

从商业角度看,对空调来说的好消息是人们的健康需求,并且全球气候变化趋势表明它们不会很快过时。 对空调来说不太好的消息是,它们消耗大量的电能,并且炎热地区的电网可能会发生过载,从而导致采取轮流限电措施。

我简要说明了 SaaS 解决方案的体系结构,该解决方案针对的是电力公司,他们希望深入分析空调使用情况以进行容量管理,并找出一种机制以使他们能够在电网处于崩溃边缘时对挂在电网上的空调系统进行大范围的紧急调整。

毫无疑问,公用事业客户宁愿自己的房间温度被迫上调到略热一点但还算舒适的 80° F/27° C,而不是切断电网而使他们无法抵御室外温度高达 100° F/38° C 的炎炎烈日。

让我们进一步假设,SaaS 将与一些空调制造商的产品搭配使用以集成所需的硬件和协议。 在安装设备并将其连接到服务后,您有机会通过移动应用程序商店销售电力公司或制造商品牌的配套应用程序,从而允许客户通过其手机或平板电脑监视和控制空调。 图 1 显示了应用场景概况。

Overview of the Software as a Service Solution
图 1 软件即服务解决方案概况

当您构建解决方案时,您需要考虑到消息通信的两大方向。 入站(从云的角度看),您需要从设备收集指标和事件,聚合数据以及将其传输到分析系统。 出站;您需要能够向设备发送控制命令。

每个空调设备应该能够发送湿度、温度和设备状态读数,根据需要,从每小时发送一次到每 10 分钟发送一次不等。 设备状态变化也会导致引发和发送事件。 控制命令罕见得多,每个设备每天可能不超过一个或两个事件。

对于初始扩容阶段,请将第一年的目标规模设置为 25 万个设备,并在第三年后提升为每年 250 万个设备。 在该规模,您可以预计第一年每小时有 25-150 万个事件,而第三年每小时约有 250-1500 万个事件。

构建解决方案

您需要解决体系结构中的三大关注领域: 配置、事件扇入和命令扇出。

配置与设置新设备、在系统中为它们分配唯一标识以及为每个设备提供一种身份验证方法有关。 再者,设备必须与系统中的特定资源相关联,并且必须接收包含所有这些信息的配置文档。

事件扇入涉及设计系统,以使其可以处理事件摄入所需的吞吐量。 每小时 1500 万个事件转换为(大致四舍五入)大约每秒 4200 个事件,这说明确实应该好好想想如何划分系统。 如果这些事件来自 4200 个不同的来源并远程连接每个客户端,情况尤其如此,建立全新的会话可能会产生很大的网络延迟。

由于来自每个特定住宅的事件和结果统计数据不仅在宏观级别至关重要,而且对购买移动应用程序并希望准确绘制趋势图的居民也至关重要,因此,您不仅需要传输汇总的数据以进行分析,而且还要弄清楚如何每天保留 3.60 亿个事件。

命令扇出涉及将命令传输到设备。 命令可能会指示设备更改其配置,或者它们可能是指示设备发出状态事件的状态查询。 如果电力公司需要进行全盘调整以减轻电网压力,他们可能希望尽快向所有设备同时发送一个命令。 如果使用的是手机,当居民希望调整到舒适的温度时,可以将命令发送到住宅中的特定设备或所有设备。

事件扇入

图 2 说明了空调应用场景的扇入模型的总体布局。

The Fan-in Model
图 2 扇入模型

体系结构的首要也是最明显的特征是存在分区。 并非将数百万个连接的设备群体作为一个整体,您可以将设备群体细分为小得多的群体,因而划分成每个包含几千个设备的更易于管理的分区。 但易于管理并不是引入分区的唯一原因。

首先,分布式系统中的每个资源都有吞吐量和存储容量上限。 因此,您希望限制与任何单一服务总线主题相关的设备数量,以使设备发送的事件不会超过主题的吞吐量容量,并且暂时产生的任何消息积压不会超过主题的存储容量。 其次,您希望分配相应的计算资源,并且您也不希望进行过多的写入操作而使存储后端负担过重。 因此,您应该将相对较小的资源集(具有合理的已知性能特性)捆绑成一个最孤立的自治“标度单元”。

每个标度单元支持最大数量的设备,这在限制可扩展性扩容方面是非常重要的。 引入标度单元的一个较好的附带效果是,它们大大降低了发生全系统中断的风险。 如果系统依赖于单一数据存储,而该存储存在可用性问题,则整个系统都会受到影响。 但如果系统包含 10 个标度单元,每个单元保留单独的存储,则一个存储出现的短暂中断只影响 10% 的系统。

图 2 所示的体系结构决策是,设备将所有事件放入 Windows Azure 服务总线主题,而不是放入解决方案直接提供的服务边缘。 Windows Azure 服务总线已提供一个横向扩展安全网络服务网关以进行消息传送,这对尽可能充分利用该功能是非常有意义的。

对于这种特定的情况,您假定设备可以支持 HTTPS,因此可以通过其现有的协议支持直接与 Windows Azure 服务总线进行通信。 然而,随着设备变得越来越便宜、越来越小并使用只有几 KB 内存和速度较慢的处理器,支持 SSL(因而支持 HTTPS)可能成为一个很大的难题,甚至 HTTP 也可能开始变得特别繁重。 在某些情况下,最好使用自定义或垂直行业协议构建和运行自定义网关(参见 2 最右侧)。

每个摄入主题配置了三个订阅。 第一个订阅用于存储写入器,它将接收到的事件写入到事件存储中;第二个订阅用于聚合组件,它汇总事件并将其转发到全局统计系统;第三个订阅用于将消息传送到设备控制系统。

作为每个主题的吞吐量上限,假设实体级别为平均每秒 100 个消息。 鉴于您为每个提交的事件创建和传送三个副本,您最多可以每秒将 33 个消息摄入到每个主题中。 这显然是一个(相当)保守的数字。 之所以说比较谨慎是因为,您采用的是每小时发送消息的分布式设备,而假定任何给定小时完全随机分配提交的事件未免太天真了。 如果您假设最坏的情况,即,事件间隔为 10 分钟,并且每个设备每小时发送一个额外的控制交互反馈消息,您可以预计每个设备每小时传送 7 个消息,因此,您可以在每个主题上连接大约 50,000 个设备(向下舍入)。

尽管这种流量不必担心存储吞吐量问题,但需要考虑事件存储的存储容量和可管理性问题。 对于 50,000 个分辨范围为一小时的设备来说,每个设备的事件数据相当于每年约 4.38 亿个事件记录。 即使您非常希望打包这些记录,并且假定每个纪录仅使用 50 字节,则每个标度单元每年的负载数据仍然可能高达 22 GB。 这仍然是可管理的,但这也强调了您在考虑调整标度单元大小时需要注意存储容量和存储增长情况。

根据一年的扩容预测,您需要在第一年增加 5 个标度单元,而在第三年后每年增加 50 个标度单元。

存储、检索和聚合事件

现在,让我们更详细地介绍如何处理和使用传入的事件。 为了说明这一点,我在图 3 中放大了标度单元之一。

A Scale-Unit
图 3 标度单元

来自设备的消息可以分为两大类: 控制响应和事件。 控制响应是按控制系统订阅筛选的。 事件(包含当前设备状态和传感器读数)将通过单独的订阅传送到存储写入器和聚合器。

存储写入器的工作是从订阅接收事件,并将其写入到事件存储中。

要存储事件,Windows Azure 表存储是一个很好的候选对象。 为了支持分区模型,将在系统中的所有分区之间共享存储帐户,并且每个分区有一个表。 表存储要求使用分区键将数据行分配到存储部分,并使用设备的标识符表示该键;当您需要提供历史统计数据以绘制图表时,这会实现较好的查找性能。 对于行键,只需使用采用紧凑 YYYYMMDDHHMMSS 格式的字符串编码的时间戳,这种格式按时间顺序排序并允许范围查询以绘制图表。 此外,在这种情况下,由于各个设备发送事件的时间间隔从不少于一秒,因此,您不必担心潜在的冲突。 时间戳是从消息的 EnqueuedTimeUtc 属性派生的,这是 Windows Azure 服务总线代理自动在每个传入消息上标记的,因此,您不必信任设备的时钟。 如果构建的高吞吐量解决方案可能存在冲突,您可能还需要利用消息的 SequenceNumber 属性,这是代理在每个消息上标记的唯一连续 64 位标识符。

聚合器的工作是接收和汇总传入的事件,以便将它们转发到向分析基础结构提供数据的全系统统计数据主题之一。 这通常是使用以下方法完成的:计算特定时间段的一组事件的平均值或总和,然后仅转发计算的值。 在这种情况下,您可能会对每个小区的能源和温度读数趋势(分辨范围为 15 分钟)感兴趣。 因此,以两个 Web 角色(每个看到大约一半的数据)运行的聚合器将保持设备与住宅和小区之间的映射关系,在设备事件到达时将数据聚合到每个小区的存储段中,并每隔 15 分钟发出具有计算的聚合值的事件。 由于每个聚合器实例只能看到一半的事件,统计数据主题背后的分析后端可能需要对两个事件进行最终汇总以获取小区的全貌。

MSDN 杂志系列文章的第一篇文章“构建物联网”(msdn.microsoft.com/magazine/hh852591) 介绍了如何在设备环境中使用 Microsoft StreamInsight。 该文章很好地说明了汇总阶段;文章中描述的示例可以方便地替代此体系结构中的聚合器。

命令扇出、定位和收集响应

正如图 4 所示,控制系统将命令发送到主题中,设备将从命令扇出订阅接收消息。

The Fan-out Model
图 4 扇出模型

每个设备使用一个订阅的关键参数是可靠性。 在发送命令时,您希望命令最终到达设备,即使关闭了设备或当前未连接设备也是如此。 因此,您需要使用相当于设备邮箱的功能。

额外的可靠性和灵活性的代价是复杂性有所提高。 我讨论的每个实体的吞吐量上限还体现在 Windows Azure 服务总线允许每个主题的订阅数量;目前,每个主题的系统配额限制为 2,000 个订阅。 对于扇出情况,您实际为每个主题分配的订阅数量取决于所需的流量。 与为订阅筛选和选择消息相关的开销可以看作是复制操作。 因此,如果您假设每个实体的吞吐量为每秒 1,000 个消息,则具有 1,000 个订阅的主题将产生每秒一个消息的流量。

对于紧急命令,您需要以广播方式将一个命令发送到所有连接的设备。 对于有针对性的命令,例如,用户通过 3G 上连接的应用程序调节特定设备或特定住宅的温度,应在几秒钟内完成调整。

为了弄清楚每秒一个消息是否适合有针对性的命令,假定居民很少调整或要求提供其空调系统的当前状态。 您可以预计大多数命令是在出现重大天气事件时发生的。 悲观地假设每天调整一次每个设备,并且调整一般是在上午 7 时至下午 7 时之间 进行的。 如果您假设在广播情况下主题的限制为 1,000 个订阅,这些命令将导致每分钟需要发送 1.4 个消息。 即使每个人在一个小时内都打开了空调,每分钟发送约 16 个消息也是可接受的。 由于这些规模和吞吐量方面的考虑因素,应将每个输出主题限制为 1,000 个订阅,这意味着每个标度单元需要 50 个扇出主题。

您可以将消息发送到特定的设备或住宅,或使用订阅筛选器将广播消息发送到所有设备。 图 5 显示了一个简单的筛选器,它允许消息中包含具有特定 DeviceId 或特定 HousingUnit 的属性,或者将自定义 Broadcast 属性设置为 true。 如果满足其中的任何条件,则为订阅选择消息。 因此,控制系统可以对广播消息和有针对性的消息使用完全相同的主题,并通过在消息中设置相应的传送属性来选择目标。

Targeting Messages
图 5 定位消息

控制系统也可以通过其订阅在扇入端获取命令的响应,而命令响应包含以类似方式处理的特殊筛选器属性。

命名空间结构、配置和设备标识

Windows Azure 服务总线使用命名空间概念组织资源和控制对这些资源的访问。 命名空间是通过 Windows Azure 门户创建的,它与特定的数据中心区域有关。 如果您的解决方案跨越多个大型地理区域,您可以创建多个命名空间,然后将资源和客户限定到明显具有较短网络路由优势的特定 Windows Azure 数据中心。 对于此解决方案,我可能会在美国中北部地区创建一个命名空间 (clemensv-ac-ncus-prod.servicebus.windows. net),而在美国中南部地区 创建一个命名空间 (clemensv-ac-scus-prod);或者我可能为公用事业客户创建一个命名空间 (clemensv-ac-myenergy-prod)。 “prod”后缀将生产命名空间与可能的并行测试或暂存命名空间区分开来。

为了使标度单元设置和管理变得更加容易,请利用命名空间的层次结构。 标度单元名称(构成标度单元内的所有实体的基本路径)可能只是一个数字,也可能与特定的客户关联 (/myenergy-3)。 由于您具有单个摄入主题,您可以将其直接放在下方 (/myenergy-3/fan-in),然后通过将主题编号以将扇出主题放在单独的段下面 (/myenergy-3/fan-out/01)。 各个设备的扇出订阅将设备标识符作为订阅名称以遵循该结构 (/myenergy-3/fan-out/01/subscriptions/0123456)。

创建新的标度单元实际上是一个创建这种形式的新结构的管理脚本(使用 Windows Azure 服务总线 API)。 设备订阅和筛选规则是在设备配置过程中创建的。 当然啦,您还需要创建、部署和配置匹配的存储和计算资源。 正如前面所述,对于事件存储,将为每个标度单元设置一个新表。

配置是指,在住宅中安装出厂的新设备后将其加入网络。 在本文中,我将跳过细节(如设备停用),而仅讨论在工厂为设备设置唯一设备 ID 的配置模型。 替代模型是采用完全未初始化的出厂设备,并通过服务(如 Netflix、Hulu 或 Twitter)实施与您可能知道的类似方案,全新的设备将联系 Web 服务以获取一个代码,然后显示该代码,用户可通过输入该代码登录到激活站点。

图 6 显示了配置以前分配了标识符的设备的流程。 没有显示设置设备的第一步,该步骤用于将设备联网,可以通过有线以太网、Wi-Fi 或一些无线运营商网络实现。

The Provisioning Model
图 6 配置模型

对于配置,系统将运行一个特殊 Web 服务以负责设置和管理设备标识和配置。 分区分配器跟踪激活了多少个设备,以及将哪些设备分配给哪些标度单元。 在将设备与标度单元关联后,设备将被调配到标度单元中。

在步骤 1 中,设备通过提供其设备标识符来建立到配置服务的连接。 在此模型中,所有颁发的设备标识符位于允许列表(步骤 2)中以允许激活一次设备。 在验证设备适合激活后,配置服务将调用访问控制服务 (ACS) 以便为设备创建新的服务标识和密钥(步骤 3),还会为摄入主题创建“发送”权限规则并为在步骤 4 中随后创建的扇出订阅创建“侦听”规则。 在创建这些内容后,设备的帐户恰好具有与系统交互所需的权限,并且仅具有这些权限。 在步骤 4 后,您将具有与设备交互的所有资源 URI 集合,以及设备可用于在 ACS 中进行身份验证以获得令牌的帐户和密钥。 所有这些信息将放置到设备的激活调用响应中,并且设备将其写入到永久配置存储中。

值得注意的是,虽然本文介绍了一些横向扩展分区内容,但此处给出的示例没有对访问控制标识进行分区。

为了减轻 ACS 上的压力,您可以直接让客户获取较少的令牌。 Windows Azure 服务总线的 ACS 信赖方定义的默认令牌到期时间为 1,200 秒(即 20 分钟)。 您可以将时间拨到 24 小时(即 86,400 秒),并让设备的高速缓存获取这么长时间的令牌。 在这种情况下,设备每天必须获取一次全新的令牌。 唯一的缺点是,如果截获有效期这样长的令牌,则不能撤销对令牌持有者的访问权限,但对于限制发送或侦听特定实体的令牌,这似乎是容许的风险。

在云中

将“设备”连接到云或通过云连接“设备”是 Windows Azure 服务总线团队未来几年重点关注的一个领域。 本文简要说明的体系结构提供了一个良好的开端,并且它确实(例如,在标度单元概念中)包含通过构建 Windows Azure 服务总线本身获得的宝贵最佳实践。 在消息流、聚合和分配方面还有很大的优化空间,不仅在容量方面,而且在简化编程和配置模型方面都是如此。

在未来几个月里,您将会开始看到在 Windows Azure 服务总线中进行的一些优化(如自动转发),我们的团队将利用这些新功能创建更好的抽象,以使类似此处描述的横向扩展应用场景更易于管理。 及时将事件分配给数百万个设备始终需要使用大量不同的系统资源,但您可以添加一些抽象技巧以减少可见的移动部件数量。

为了使应用场景变得更实实在在且更加有趣,此系列文章的下一篇文章将帮助您构建由 Microsoft .NET Micro Framework 支持的简单空调(不错,说的就是硬件!)。 这个小巧的自制空调将通过 Windows Azure 服务总线(将采用此处介绍的一般体系结构)与后端服务进行通信。 再会!

Clemens Vasters是 Windows Azure 服务总线团队的首席技术主管。 Vasters 从最早的策划阶段就在服务总线团队工作,并参与编制 Windows Azure 服务总线技术功能路线图,其中包括 Web 和设备的推送通知和高级信令。 他还经常在会议上演讲,并且是体系结构课件作者。 有关他的情况,请访问 Twitter twitter.com/clemensv

衷心感谢以下技术专家对本文的审阅: Elio DamaggioAbhishek LalColin MillerTodd Holmquist-Sutherland