从 0 开始搭建 IoT 平台
文章平均质量分 93
本专栏结合物联网应用开发常用的设计模式以及作者多年的开发经验,带你从 0 开始搭建一个物联网平台,希望本专栏所体现的架构和思路能够帮助你少走弯路、少踩坑。
优惠券已抵扣
余额抵扣
还需支付
¥69.00
¥99.00
购买须知?
本专栏为图文内容,最终完结不会低于15篇文章。
订阅专栏,享有专栏所有文章阅读权限。
本专栏为虚拟商品,基于网络商品和虚拟商品的性质和特征,专栏一经购买无正当理由不予退款,不支持升级,敬请谅解。
sufish
这个作者很懒,什么都没留下…
展开
-
开篇词:开发物联网应用,光会 MQTT 还不够
导读大家好,我是付强,我现在是一家物联网 Startup 的联合创始人兼 CTO,在自己创业之前,我曾经在趋势科技和诺基亚工作过。从 2011 年我在硅谷参与的第一个物联网项目开始算起,到 2015 年开始在物联网方向创业并运营到现在,从 0 到 1,1 到盈利,我在物联网这个行业已经摸爬滚打快 8 年了。我的上一门课程《MQTT 协议快速入门》详细讲解了 MQTT 协议及其各种特性。在课程的...原创 2020-10-28 16:07:02 · 525 阅读 · 0 评论 -
附录: 如何运行 Maque IotHub
安装依赖软件首先确保你的电脑已安装并运行以下软件MongoDBRedisInfluxDBRabbitMQ以上软件可以使用默认配置运行。安装运行 EMQ X编译和安装请按照 5-6 节中的步骤编译和安装带有 emqx_rabbitmq_hook 的插件的 EMQ X。配置 EMQ X以下是需要配置的 EMQ X 配置项:<EMQ X 安装目录>/etc/emq...原创 2020-10-28 16:07:02 · 716 阅读 · 0 评论 -
第 1-1 课:准备工作台
在本课中,我们将安装开发物联网平台时使用到的组件,并把物联网平台的开发环境搭建起来。安装组件首先在开发机上面安装开发需要的组件。MongoDBMongDB 是一个基于分布式文件存储的数据库,我们会把 MongoDB 作为物联网平台主要的数据存储工具。可以在这里找到 MongoDB 的安装文档,根据文档在对应的系统上安装和运行 MongoDB。RedisRedis 是一个高效的内存数据...原创 2020-10-28 16:07:03 · 622 阅读 · 0 评论 -
第 1-2 课:设备注册(一)
在本节中,我们将设计 IotHub 的设备认证机制。设备三元组EMQ X 在默认的情况是允许匿名连接的,所以在上一节课程中,IotDevice类在连接 MQTT Broker 的时候没有指定 username 和 password 也能成功。当然,我们肯定不希望任意一个设备都能连接到 Maque IotHub。首先我们需要到 Maque IotHub 注册一个设备,然后设备再通过由 Maqu...原创 2020-10-28 16:07:04 · 1495 阅读 · 0 评论 -
第 1-3 课:设备注册(二)
在本节课中,我们将设计和实现从设备注册到接入 IotHub 的主要流程。首先我们定义一下设备注册到接入 IotHub 的流程。注册流程业务系统调用 Maque IotHub Server API 的设备注册 API,提供要注册设备的 ProductName。Maque IotHub Server 根据业务系统提供的参数生成一个三元组(ProductName, DeviceName, Se...原创 2020-10-28 16:07:05 · 680 阅读 · 0 评论 -
第 1-4 课:设备注册(三)
这一节,我们将对设备注册接入的细节进行完善。添加数据库索引我们需要对 Devices 的 product_name 和 device_name 做一个索引,因为在后面会经常通过这两个字段对 devices 进行查询,在 MongoDB shell 里面输入:use iothubdb.devices.createIndex({ "production_name" : 1, "...原创 2020-10-28 16:07:05 · 442 阅读 · 0 评论 -
第 1-5 课:设备在线状态管理(一)
在本节中,我们将设计 IotHub 的设备在线状态管理功能。如何得知一个设备是在线或离线,是大家经常问到的问题,也是在实际生产中非常必要的一个功能。Poor man's SolutionMQTT 协议并没有在协议级别约定如何对 Client 的在线状态进行管理,在《MQTT 协议快速入门》里我介绍过一个解决思路:Client 在连接成功时向 TopicA 发送一个消息,指明 Client...原创 2020-10-28 16:07:06 · 1495 阅读 · 0 评论 -
第 1-6 课:设备在线状态管理(二)
在这一节中,我们会按照上一节的设计,编写代码来实现 IotHub 的设备在线状态管理功能。首先来设计一下设备状态管理功能。设备不保存在线与否这个 boolean 值,而是保存一个 connection 的列表,包含了所有用这个设备的三元组接入的 connection,connection 的信息由 WebHook 捕获的 client_connected 事件提供。当 client_con...原创 2020-10-28 16:07:06 · 893 阅读 · 0 评论 -
第 1-7 课:设备禁用与删除
在这一节中,我们来设计和实现设备生命周期管理中的禁用和删除功能。设备禁用设备禁用的逻辑很简单,业务系统可以通过一个接口暂停设备的接入认证,被禁用的设备无法接入 IotHub;业务系统也可以通过一个接口恢复设备的接入认证,使设备可以重新接入 IotHub,这里还暗含着另外一个操作,在禁用设备的时候,如果这个设备已经接入 IotHub,且是在线状态,那么需要将这个设备踢下线。接下来我们来一步一步实...原创 2020-10-28 16:07:07 · 627 阅读 · 0 评论 -
第 1-8 课:设备权限管理
在这一节,我们讨论一下设备的权限管理。什么是设备权限管理设备权限管理是指对一个设备的 Publish 和 Subscribe 权限进行控制,设备只能 Publish 到它有 Publish 权限的主题上,同时它也只能 Subscribe 有 Subscribe 权限的主题。为什么要控制 Publish 和 Subscribe场景1 ClientA 订阅主题 command/ClientA...原创 2020-10-28 16:07:07 · 1324 阅读 · 0 评论 -
第 1-9 课:加一点扩展性
在前面我们讨论了对设备接入的抽象和生命周期的管理,在继续深入之前,我们先讨论一下 Maque IotHub 的扩展性问题,毕竟作为一个物联网平台,能够负载大量的设备接入,是非常重要的,我想这也是大家非常关心的问题。在这里我把问题稍微改一下,从 IotHub 能容纳多少设备接入,改成 IotHub 能不能随着业务扩容来满足业务需求,也就是说,IotHub 是否具有可扩展性?现在 IotHub 的...原创 2020-10-28 16:07:08 · 197 阅读 · 0 评论 -
第 2-1 课:选择一个可扩展的上行数据处理方案
接下来的的几节课,我们会来设计和实现 Maque IotHub 的上行数据处理和存储的功能。接收上行数据在《MQTT 协议快速入门》的讨论群里,问的一个比较多的一个问题就是:"服务端怎么接收客户端发送的数据呢?"这里我想先做一个说明,在 MQTT 协议的架构里面,是没有"服务端"和"客户端"的概念的,只有"Broker"和"Client",所以 EMQ X 说自己是一个 MQTT Broke...原创 2020-10-28 16:07:09 · 313 阅读 · 0 评论 -
第 2-2 课:功能设计
本节课,我们开始设计 IotHub 的上行数据处理功能。功能设计IotHub 的上行数据处理有以下一些功能。存储上行数据: IotHub 接收设备端上传的数据,并将数据来源(设备的 ProductName 和 DeviceName)、消息 ID、消息类型、Payload 进行存储。通知业务系统:当有新的上行数据到达时,IotHub 通知并将上行数据发送给业务系统,业务系统可以自行处理这些...原创 2020-10-28 16:07:09 · 283 阅读 · 0 评论 -
第 2-3 课:实现(一)
从这一节开始,我们来实现 IotHub 的上行数据处理功能:包括设备端和服务端的实现。在设备端我们会实现数据上传的接口,在服务端我们会实现元数据提取、消息去重、存储等功能。DeviceSDK 端实现DeviceSDK 端的实现比较简单,实现 uploadData 接口,按照上一节约定的主题名发布消息就可以了。在发布数据时,DeviceSDK 负责为消息生成唯一的 MessageID,生成的算法...原创 2020-10-28 16:07:10 · 229 阅读 · 0 评论 -
第 2-4 课:实现(二)
这一节我们来实现 IotHub 上行数据处理剩下的一下功能:通知业务系统以及 Server API 消息查询接口。然后完善一些细节。通知业务系统当上行数据到达 IotHub 时,IotHub 可以通过 RabbitMQ 来通知并发送新的上行数据给业务系统。这里我们做一个约定,当有新的上行数据达到时,IotHub 会向 RabbitMQ 名为"iothub.events.upload_data"...原创 2020-10-28 16:07:10 · 165 阅读 · 0 评论 -
第 2-5 课:设备状态上报
这一节我们来讨论另外一种设备上行数据,即设备状态。设备状态数据上一节,我们完成了对设备上行数据的处理,假设说我们有一台装有温度传感器的设备,那么它可以使用这个功能将每个时刻统计到的温度数据上报到 IotHub,IotHub 会记录每一条温度数据并通知业务系统,业务系统可以自行存储温度数据也可以使用 IotHub 提供的接口来查询不同时刻的温度数据。 除了温度读数,设备可能还会需要上报一些其他...原创 2020-10-28 16:07:11 · 628 阅读 · 0 评论 -
第 2-6 课:时序数据库
在前面的课程中,我们完成了 IotHub 上行数据处理的功能。截止目前,IotHub 使用 MongoDB 作为数据存储,这很好,不过在物联网的应用中,在某些情况下,我们可能还会用到别的存储方案,比如说时序数据库,那么这一节我们就来聊聊时序数据库。时序数据首先让我们来看一下什么是时序数据。时序数据是一类按照时间维度进行索引的数据,它记录了某个被测量的实体在一定时间范围内,每个时间点上的一组测试...原创 2020-10-28 16:07:11 · 407 阅读 · 0 评论 -
第 3-1 课:选择下行数据处理方案
接下来的几节课,我们会来设计和实现 Maque IotHub 的下行数据处理功能。定义下行数据在物联网应用中,下行数据一般有两种,第一种是需要同步的数据,比如平台需要把训练好的模型部署到前端的摄像头上,那平台下发给设备的消息里面就包含模型数据的信息;第二种是指令,平台下发给设备,要求设备完成某种操作,比如共享单车的服务端下发给单车开锁的指令。在 Maque IotHub 里,我们会把这两种下...原创 2020-10-28 16:07:12 · 449 阅读 · 0 评论 -
第 3-2 课:功能设计
这一节我们来设计 IotHub 的下行数据处理功能。功能设计Maque IotHub 的指令下发系统有以下一些功能。业务系统可以通过 IotHub Server API 提供的接口向指定的设备发送指令,指令可以包含任意格式的数据,比如字符串和二进制数据。指令可设置过期时间,过期的指令将不会被执行。业务系统可在设备离线时下发指令,设备在上线以后可以接收到离线时由业务系统下发的指令。设备...原创 2020-10-28 16:07:12 · 203 阅读 · 0 评论 -
第 3-3 课:设备端实现
这一节我们开始实现 IotHub 指令下发的 DeviceSDK 端的功能。首先进行消息去重, 接着使用正则表达式提取出元数据, 然后通过事件的方式将指令的数据传递给设备应用代码, 最后提供一个接口供设备对指令进行回复。消息去重在本课程里面我们会使用 node-persist 来存储已收到指令的 RequestID。 首先初始化存储://IotHub_Device/sdk/iot_devi...原创 2020-10-28 16:07:13 · 209 阅读 · 0 评论 -
第 3-4 课:服务端实现(一)
这一节我们开始实现 IotHub 指令下发的 IotHub Server 端的实现。这一节里面我们会实现使用 EMQ X 的 API 来发布消息,并实现指令下发接口供业务系统调用,最后使用 EMQ X 的服务器订阅功能,来实现设备的自动订阅。添加 ACL 列表设备端需要在回复指令的时候 Publish 到:cmd_resp/:ProductName/:DeviceName/:CommandN...原创 2020-10-28 16:07:13 · 228 阅读 · 0 评论 -
第 3-5 课:服务端实现(二)
这一节课,我们来完成指令下发剩余部分的功能, 当设备对指令进行回复以后,IotHub 会通过 RabbitMQ 将设备的回复通知到业务系统,最后我们将 IotHub Server 端的代码和 DeviceSDK 的代码进行联调。通知业务系统指令处理的最后一步就是将设备对指令的回复再转发到业务服务器,具体流程:IotHub Server 通过 WebHook 获取设备对指令的回复消息;I...原创 2020-10-28 16:07:14 · 162 阅读 · 0 评论 -
第 4-1 课:RPC 式调用(一)
从这一部分开始,我们设计和实现一些 MaqueIotHub 更高维度抽象的功能,这一节我们来设计和实现 IotHub 的 RPC 式调用的服务端功能。什么是 RPC 式调用?在第三部分的课程里,我们实现了 IotHub 的指令下发功能。我们曾经把指令下发比作是一次函数调用 y = f(x),在目前的实现里,f(x) 的返回结果 y 是通过异步的方式告知调用者(业务系统)的,即业务系统调用下发指...原创 2020-10-28 16:07:14 · 271 阅读 · 0 评论 -
第 4-2 课:RPC 式调用(二)
这一节我们来实现 RPC 式调用的设备端代码,首先会使用 EMQ X 的服务端订阅功能自动订阅对应的主题,然后在 DeviceSDK 中修改用于匹配主题名的正则表达式,从 RPC 式调用的主题中提取指令的元数据,最后将服务端和设备端连在一起进行测试。添加ACL列表由于设备端需要将回复发布到:rpc_resp/:productName/:deviceName/:commandName/:req...原创 2020-10-28 16:07:15 · 155 阅读 · 0 评论 -
第 4-3 课:设备数据请求
到目前为止,如果要把数据从服务端发送到设备端,只能使用指令下发的方式,这种方式相当于是"Push"的模式,服务端主动推数据到设备端。这一课,我们来实现服务端到设备数据传输的另一种方式——"Pull"模式:设备数据请求。设备数据请求想较于之前的 Push 模式,数据的传输是由服务端触发的,Pull 模式是指由设备端主动向服务端请求数据(这个服务端包括业务系统和 IotHub)。我在这里举一个很...原创 2020-10-28 16:07:15 · 206 阅读 · 0 评论 -
第 4-4 课:NTP 服务
在这一节我们来设计和实现 IotHub 的 NTP 服务。NTP什么是 NTP?这个我想大家都不陌生,NTP 是同步网络中各个计算机时间的一种协议。在 IotHub 中,保证设备和服务端的时间同步是非常重要的,比如指令的有效期设置就非常依赖于设备和服务器间的时间同步,如果设备时间不准确,就有可能导致过期的指令仍然被执行。通常情况下,设备上都应该运行一个 NTP 的服务,定时地和 NTP 服务...原创 2020-10-28 16:07:15 · 1365 阅读 · 0 评论 -
第 4-5 课:设备分组——功能设计
到目前为止, IotHub 一次只能对一个设备下发指令,假如业务系统需要对多台设备同时下发指令,应该怎么做呢?我们可以将设备进行分组,业务系统可以通过指定指令的设备组,来实现指令的批量下发。设备分组来看一下这个场景,业务系统要关闭二楼所有的 10 个传感器,在目前的 IotHub 功能设计下,业务系统需要调用 10 次下发指令接口,这显然是不合理的。 以 MQTT 的解决方案来说,这 10 个...原创 2020-10-28 16:07:16 · 848 阅读 · 0 评论 -
第 4-6 课:设备分组——服务端实现
这一课,我们来实现 IotHub 设备分组功能的服务端实现。服务端需要在设备标签发生变化时,将标签信息重新下发到设备;在设备发起标签数据请求时,服务端又要响应这个请求,将设备的标签信息下发到设备。 同时,服务端需要提供接口,供业务系统修改设备的标签,并通过标签批量下发指令。 添加 tags 字段在 Device 模型中,我们添加字段保存 tags 和 tags_version。//Iot...原创 2020-10-28 16:07:16 · 210 阅读 · 0 评论 -
第 4-7 课:设备分组——设备端实现
在这一节我们来实现设备分组的设备端实现,设备在连接到 IotHub 时,需要主动请求标签数据,在收到来自服务端的标签数据时,需要对比本地存储的标签数据,然后 subscribe 或者 unsubscribe 对应的主题。最后我们会把代码连在一起进行测试。设备端的持久性存储由于需要和服务端的标签进行对比,设备需要在本地使用持久性的存储来保存已订阅的标签。一般来说,DeviceSDK 需要根据自身...原创 2020-10-28 16:07:17 · 322 阅读 · 0 评论 -
第 4-8 课:设备间通信
这一节我们来设计和实现 IotHub 设备间通信功能。设备间通信到目前为止,我们在 MQTT 协议上抽象出了服务端和设备端,数据的流向是从服务端(业务系统,IotHub)到设备端,或者从设备到服务端。在某些场景下,接入 IotHub 的设备可能还需要和其他接入的设备进行通信,例如管理终端通过 P2P 的方式查看监控终端的实时视频,在建立 P2P 的连接之前,需要管理终端和监控终端进行通信,交换...原创 2020-10-28 16:07:17 · 451 阅读 · 0 评论 -
第 4-9 课:OTA 升级——功能设计
这一节开始我们来设计 OTA 升级功能。设备 OTA 升级OTA(Over-the-Air Technology),一般叫做空中下载技术,在物联网应用里,设备一般都是通过 OTA 技术进行软件升级的,毕竟人工升级一台台设备的成本太高了。设备应用升级的类型可能会包括设备应用程序、固件、OS 等,具体如何在设备上执行这些升级程序,各个设备都不同,本课程不在这方面进行论述。这里 IotHub 会对...原创 2020-10-28 16:07:18 · 921 阅读 · 0 评论 -
第 4-10 课:OTA 升级——服务端实现
这一节我们开始实现 OTA 升级的服务端功能。在服务端我们会规划OTA相关的主题名,并存储设备上报的升级进度;服务端还需要提供接口,供业务系统下发OTA升级指令和查询升级进度。主题规划升级指令的下发使用已有的指令下发功能就好,但是我们需要增加一个主题名供设备上报升级进度,这里约定, 设备将使用主题: update\_ota\_status/:ProductName/:DeviceName/:m...原创 2020-10-28 16:07:19 · 1146 阅读 · 0 评论 -
第 4-11 课:OTA 升级——设备端实现
在这一节我们开始来实现 OTA 升级的设备端功能。上报升级进度首先我们使用一个类来封装上报升级进度的操作://IotHub_Device/sdk/ota_progress.jsconst ObjectId = require('bson').ObjectID;class OTAProgress { constructor({productName, deviceName, mqt...原创 2020-10-28 16:07:20 · 598 阅读 · 0 评论 -
第 4-12 课:设备影子概览
从这一节课开始,我们来设计和实现设备影子。什么是设备影子我最早是在 AWS IoT 上面看到设备影子功能的,后来国内主流云服务上的 IoT 套件中都包含了设备影子的功能。设备影子已经是 IoT 平台的标配功能了,所以 Maque IotHub 也需要实现设备影子功能。 首先让我们来看一下各个平台对设备影子的描述。阿里云 物联网平台提供设备影子功能,用于缓存设备状态。设备在线时,可以直...原创 2020-10-28 16:07:20 · 1681 阅读 · 0 评论 -
第 4-13 课:设备影子——服务端实现
这一节我们来设计和实现 IotHub 设备影子服务端的功能。服务端需要对设备影子进行存储,在业务系统修改设备影子时,需要将设备影子同步到设备端,同时还需要处理来自于设备的设备影子同步消息来将设备端的数据同步到数据库中。最后服务端还要提供接口供业务系统查询和修改设备影子。存储设备影子我们在 Device 模型里新增一个字段shadow来保存设备的影子,一个空的设备影子应该是:{ "...原创 2020-10-28 16:07:21 · 1672 阅读 · 0 评论 -
第 4-14 课:设备影子——设备端实现
这一节我们开始实现设备影子的设备端功能,设备端需要处理来自服务的影子设备同步,同时在本地的设备影子发送变化时,向服务端发送相应的数据,最后我们会对IotHub的设备影子功能进行验证。主动请求设备影子数据在设备连接到 IotHub 时,需要主动发起一个数据请求,请求设备影子的数据://IotHub_Devicethis.client.on("connect", function () { ...原创 2020-10-28 16:07:21 · 915 阅读 · 0 评论 -
第 4-15 课:IotHub 状态监控
这一课,让我们来看一个与指令、数据、同步无关的话题:IotHub 的状态监控。状态监控作为一个服务多个产品的物联网平台,目前我们还缺少一个功能。如何来监控当前物联网平台的运行情况呢?这里要讨论的不是监控内存、硬盘I/O、网络等,也不是监控 Web Server、MongoDB 的运行状态,因为这些监控都已经有非常成熟的方案了。这里我们要讨论是,如何监控 EMQ X Broker 的运行状态,...原创 2020-10-28 16:07:22 · 306 阅读 · 0 评论 -
第 5-1 课:EMQ X 的插件系统
这一部分的课程,我们将学习如何通过编写 EMQ X 插件的方式来扩展 EMQ X 的功能。Webhook 的局限性在 IotHub 中我们使用了 EMQ X 的自带的 Webhook 插件,IotHub Server 通过使用 Webhook 插件来获取设备的上下线事件和 Publish 的数据,从开发和演示的功能的角度,这个插件是OK的,但是如果我们在生产环境中使用,你应该要注意到以下问题。...原创 2020-10-28 16:07:22 · 355 阅读 · 0 评论 -
第 5-2 课:我们会用到的 Erlang 特性
在这一小节我们将学习一部分Erlang的语言特性,目的是为了让你能够更好的理解在后面编写的插件的代码。Erlang简介Erlang 诞生于 1987 年,由爱立信的 CS-Lab 开发。 Erlang 是一种动态类型的、函数式的语言,主要是为了处理并行,分布式应用而设计的,所以 Erlang 内建了轻量级的进程模型,让编写并发应用变得非常容易。 运行 Erlang 程序需要有一个类似 JVM...原创 2020-10-28 16:07:23 · 234 阅读 · 0 评论 -
第 5-3 课:搭建开发和编译环境
这一课,我们开始搭建 EMQ X 插件开发的环境。下载和编译 EMQ XEMQ X 的插件需要调用 EMQ X 内部的一些函数,所以实际上是没有办法单独编译 EMQ X 插件的,而是需要将插件的代码放到 EMQ X 源码中一起编译。所以首先要搭建 EMQ X 的编译环境。EMQ X 的代码需要从 EMQ X 的 Release Project 下载,因为本课程是基于 EMQ X 3.1.2 开...原创 2020-10-28 16:07:24 · 201 阅读 · 0 评论