0%

从零构建物联网平台-需求规划、技术选型和系统设计


从零构建物联网平台系列文章:

  1. 从零构建物联网平台-给个理由先
  2. 从零构建物联网平台-平台架构
  3. 从零构建物联网平台-需求规划、技术选型和系统设计
  4. 从零构建物联网平台-环境构建
  5. 从零构建物联网平台-MQTT消息代理(Message Broker)
  6. 从零构建物联网平台-构建关键组件
  7. 从零构建物联网平台-实现WebSocket通信

有了前面的需求规格分析后可以马上开始我们的平台构建了,但是提前定义和细化需求肯定会帮助我们更快、更高效地创建平台。

本篇我们对以下内容进行展开。

  • 设备如何与平台实时连接
  • 平台如何存储数据
  • 平台构建的API类型
  • 平台构建的微服务

实时连接平台

WEB应用系统面临的挑战之一是实时通信的能力。同步通信很常见,我们可以通过HTTP请求来实现,但是使用相同的技术来实现异步通信很困难的。物联网平台的实时连接和通信是物联网解决方案和应用的关键需求。这就是我们需要使用消息代理并实现类似发布/订阅机制的地方。消息代理通常是中间件系统,通过发布/订阅机制为所有连接的应用和设备提供异步通信能力。

发布/订阅机制是一个有趣的模式,因为它不要求任何一方必须同时在线。此外,它还支持任何一方都可以发起数据传输,而不管另一方是否准备好。这与HTTP完全相反,在HTTP中,客户端必须向服务器发起请求。服务器不能主动和客户端通信。当我们通过消息代理将服务器和客户端与发布/订阅机制连接起来时,它们中的任何一个都可以发送数据。

我们选择的消息代理必须满足一定的基本条件。以下两个标准很重要:易于配置和维护;对于生产环境足够稳定。

使用MQTT作为消息代理

虽然可能有多种消息代理技术,但我们选择使用MQTT标准,因为这几乎是物联网应用和解决方案的实际标准协议。

MQTT全称是MQ Telemetry Transport,MQ遥测传输。它是一个发布订阅、极其简单和轻量级的消息传递协议,专为受限设备和低带宽、高延迟或不可靠的网络设计。设计原则是尽量减少网络带宽和设备资源需求,同时努力确保可靠性和交付保证。这些原则使该协议成为机器对机器(M2M)或物联网设备世界的理想选择,也成为带宽和电池电量都很高的移动应用的理想选择。

MQTT有许多商用和开源实现。Mosquitto是Eclipse家族一个流行的开源MQTT实现,我们使用它来构建我们的消息代理。

如何存储数据

消息代理不是数据库。它们更像是一个消息传递管道,消息或数据通过它传递。这些数据可以短暂在管道内保留,如果不存储,长时间后就查询不到了。

从平台的角度来看,我们需要这种存储和查询机制,以便以后能够检索数据。我们选择MySQL作为存储引擎。虽然MySQL并不是真正的时序型数据库,但为了快速搭建平台,也考虑到大多开发者的技术栈,我们还是选用MySQL来模拟时序数据库进行数据存储。

关键问题是如何存储数据。我们采集的数据是通过消息代理和消息总线通信管理模块传递的遥测数据。该数据可以只有几个字段用于后续数据处理。

在MQTT通信中,数据包在每条消息中都有两个字段:topic(主题)和payload(有效负载)。topic通常用作数据的键,而payload是实际的数据或内容。因为MQTT是一个消息传递协议,不一定指定payload的格式,所以我们可以灵活使用它。但是,为了在整个平台上保持可伸缩性和统一的格式,我们在整个平台上使用JSON作为payload。这不仅有助于我们保持一致性,还会使我们的平台具有可扩展性,并易于适应新的变化。

数据库设计

JSON数据本质上是一个ASCII字符串。MQTT还支持二进制数据包,这些数据包也可以包含非ascii字符。我们可以通过消息代理轻松地传输二进制文件和数据,在设计平台时应该注意这一点。

除了存储主题和相关的数据有效负载,我们还需要为每个消息分配一个唯一ID。由于这是一个时序数据库,我们需要为每个消息存储时间戳。除了这些字段,现阶段我们暂时不需要在物联网平台存储任何其他信息。考虑到这些因素,我们的数据库表结构如下图所示。

下面简要解释每一列:

  • ID:自增主键。我们使用MySQL的自增列功能。
  • Topic:声明为varchar,允许在此字段中存储可变长度的数据。主题的长度可以是任意的,并且根据应用的不同而不同。我们对长度进行1KB的限制,这对于主题名称长度是足够。
  • Payload:数据包可以是任意长度(因此是可变类型)。但我们将有效负载包存储限制为2KB。我们可以在不影响以前存储的数据的情况下增加大小和限制;但当减小长度时,以前的数据可能会被截断。这可以根据需求决定。
  • Timestamp:它是用整数格式表示的UNIX风格的日期时间戳。epoch(或UNIX时间、POSIX时间或UNIX时间戳)是自1970年1月1日以后经过的秒数(不包括闰秒)。

基于此表结构,我们在Payload列中存储接收到的每个数据包,并将主题存储在topic列中;两者都以原格式存储。时间戳使用平台的系统时间,ID自增。这能够在需要时按存储数据的相同顺序查询数据。

通过API访问平台资源

Mosquitto MQTT代理和MySQL存储引擎已确定,我们的平台能够采集数据和通过MQTT进行通信。这种通信(通过MQTT)将基于数据流,如果没有平台的其余部分,这就是一个最简版的物联网平台。

连接到流的设备或应用能够实时访问数据。但是没有请求数据的机制。这就是我们的API将发挥重要作用的地方。

在计算机编程领域,API是指应用程序编程接口,它一些预先定义的函数,或指软件系统不同组成部分衔接的约定。目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问原码,或理解内部工作机制的细节。

我们将API分为四种不同的类型。帮助我们保持开发的模块化和可插拔性。

  • Data Access APIs:这些API帮助我们访问物联网平台中的时序数据,并以有限的方式对其进行操作。此外,此API有助于在实时数据流(基于MQTT)和非实时数据流(基于HTTP)之间创建链接。
  • Utility APIs:对于许多系统需要一些工具类接口。一个典型例子是以某种格式进行的数据转换。如果系统或设备需要对数据进行编码或加密,或者需要针对特定条件对其进行转换,那么它可以利用其中的一些API。本质上,它们是由平台内外的多个资源共享的函数。
  • Microservice APIs:基于功能或服务于特定目的的端点。这些是典型的应用服务,如发送电子邮件等。

Data Accessing APIs

为了安全恰当地访问时序数据,我们设计一组API来满足各种场景和需求。一般来说,我们至少需要七个端点。


我们为每个需求设置上编号,这样可以在后续文章中方便引用它们。数据需求以D开头,微服务和工具类需求以M开头。


  • D1:获取单条数据记录。允许应用系统和设备根据指定的主题从数据库中查询单条数据记录。
  • D2:获取多条数据记录。允许应用系统和设备根据指定的主题查询多条数据记录。
  • D3:根据特定条件获取一条或多条记录。使应用系统能够根据指定的条件(针对主题或负载,或同时针对两者)查询一个或多个数据记录。条件可以是主题或负载,也可以是与时间戳相关的,比如某个时间段内的数据。
  • D4:存储通过API发送的数据记录(未通过MQTT流发送)。除了从时间序列存储中查询数据外,我们还希望应用系统和设备以调用API的方式将数据存储到数据库中。这对于无法通过实时MQTT数据流进行通信的设备和应用非常有用。
  • D5:删除单条数据记录。允许应用系统或设备根据指定的主题删除单条数据记录。
  • D6:按时序删除多条数据记录。根据主题从数据批量删除一组数据记录。它有利于我们保持数据库的存储容量。典型场景是只保留1个月内的数据,可以将数据从平台存储中取出,存储在某个地方,以用于审计或其他目的。
  • D7:根据某些条件删除一个或多个记录。就像根据指定的条件查询一个或多个数据记录一样,我们可能需要从数据库中删除它们。虽然这是一个有用的功能,但它需要一个内置的安全策略。

Microservice和Utilities

  • M1:发布当前时间戳。对于分布式应用系统强烈推荐使用此服务。通常由于时区差异和系统时钟限制,系统间存在差异。我们可以在时间广播服务的帮助下克服这个问题。另一种方法是使用NTP(网络时间协议),但是并不是所有的应用系统或设备都可以访问NTP服务器,这限制了它们对同步操作进行计时的能力。我们使用此服务从物联网平台发布/广播时间值,以便所有系统和平台同步。可以将平台与NTP服务器单独同步,在我们的平台中一定要有一个稳定的参考源。
  • M2:获取当前时间戳。这是发布当前时间戳函数的轮询服务。当设备或应用系统想要轮询并想要知道当前时间戳(如果它错过了之前的广播并且不能等到下一次广播)时,或者在用户或业务规则强制设备或应用系统进行同步的情况下,此服务非常有用。
  • M3:获取唯一或随机数/字符串。对于随机字符串和数字的生成和使用,这是一个非常有用的服务。我们可以使用随机生成的数字和字符串来创建唯一的键或数字。还可以将它们用作随机密码或令牌。
  • M4:获取UUID。UUID(通用唯一标识符)类似于随机数或字符串生成服务,但更结构化且通用惟一。
  • M5:发送邮件。由多个应用系统和平台提供的通用且经常使用的服务。我们需要一个自动化、报警、用户检查和验证、密码重置、密钥通信等的邮件服务。这是物联网平台的必备服务。
  • M6:发短信。我们可以使用短信代替邮件。此外,我们可以使用它来做身份验证。设备指令下发也会用到短信功能。
  • M7:MQTT回调注册。由于MQTT数据是实时的,对于依赖于仅限HTTP机制的应用系统,除非应用系统连续或频繁地轮询,否则无法获得最新可用数据的通知。为了避免这种情况,我们开发一个服务,它本质上是创建一个webhook,每当平台接收到与给定主题或负载相匹配的数据包时就调用它。这样,使用HTTP的应用系统可以使用REST API(如D4中所示)发布或传输数据包,并使用此服务实时接收数据(被通知)。我们可能必须使用规则引擎来编写此服务。这只适用于上层的WEB应用系统,硬件设备不太可能使用此服务。

消息路由和过滤

消息路由和过滤是通用架构中的高级特性,在第一阶段暂时不需要实现。

更新物联网平台架构

我们列出的所有需求都不是硬性的。其中许多可以之后再构建,或者干脆跳过。到目前为止,我们已经为平台的四个主要模块定义了基本需求和技术栈选型。

使用敏捷方式构建平台能够在这些模块中逐渐添加更多的特性和功能。通过这种方式,可以先启动并构建物联网平台最核心的功能,然后持续不断地扩展它。更新后的物联网平台架构如下所示。

总结

在本篇中,我们做出了一些与数据库和实时连接相关的关键决策和选型。还定义了API、微服务和工具类的需求细节。准备工作都已就绪,下一篇我们正式开始构建平台。

坚持原创技术分享,您的支持将鼓励我继续创作!