· Zen HuiFer · 从零开始构建企业级物联网平台 · 46 min read
物联网平台架构设计
本文介绍了物联网平台架构设计的关键要素,包括多协议支持、数据处理能力、灵活的告警和通知机制、细粒度的权限管理以及全面的数据安全措施。同时,文章还详细阐述了物联网平台的各个架构层次,如通讯层、数据解析层、数据存储层、用户管理层、数据权限层、数据分析层、通知层和运维层。
物联网平台架构设计
架构设计概述
物联网平台作为连接物理设备与数字世界的桥梁,其架构设计对于实现高效、稳定和安全的设备管理至关重要。一个优秀的物联网平台应该具备以下基础功能,以满足普通开发者的需求:
多协议支持:平台必须能够接收并处理来自不同设备、使用不同通讯协议的数据。这意味着无论设备使用的是MQTT、CoAP、HTTP或其他任何协议,平台都能够兼容并有效接收数据。
数据处理能力:接收到的数据需要被有效解析和转换,以便于存储、查询、统计和分析。平台应该提供强大的数据处理能力,包括实时数据分析和可视化展示,帮助开发者洞察数据背后的故事。
灵活的告警和通知机制:在数据出现异常或达到特定条件时,平台应能够及时发出告警,并通过邮件、短信或其他方式通知相关人员。此外,开发者还应能够根据需要轻松导出数据,进行进一步的分析或报告。
细粒度的权限管理:为了保障数据安全和合规性,物联网平台需要提供细粒度的权限管理功能,包括数据权限管理、用户管理、角色管理和部门管理。这样,开发者可以控制谁能够访问特定的数据或执行特定的操作。
全面的数据安全措施:数据安全是物联网平台的重中之重。平台需要实现包括数据加密、安全存储、定期备份和快速恢复在内的全面数据安全措施,确保数据的安全性和完整性。
在架构层面,物联网平台可以分为以下几个关键层次:
- 通讯层:负责处理设备与平台之间的数据传输,确保数据的实时性和可靠性。
- 数据解析层:将接收到的原始数据转换为结构化数据,为后续处理提供基础。
- 数据存储层:为海量的设备数据提供稳定、高效的存储解决方案。
- 用户管理层:管理用户信息和权限,确保用户能够安全地访问和管理平台。
- 数据权限层:控制不同用户对数据的访问权限,保障数据的安全性。
- 数据分析层:提供数据分析工具,帮助开发者从数据中提取有价值的信息。
- 数据存储层::用于对采集的数据以及系统基本数据进行存储。
- 通知层:负责将告警信息通知给相关人员,包括邮件、短信、电话等。
- 运维层:负责平台的监控、维护和优化,确保平台的稳定运行。
通过这样的架构设计,物联网平台不仅能够满足普通开发者在设备连接、数据处理和用户管理等方面的需求,还能够提供强大的安全保障和灵活的扩展能力,支持开发者构建创新的物联网应用。
通讯层
在物联网开发平台中,通讯层是连接设备与平台的关键层。它负责处理设备与平台之间的数据传输,确保数据的实时性和可靠性。常见的物联网开发平台需要支持以下通讯协议:
- MQTT: 轻量级的发布/订阅消息传输协议,适用于低带宽、不可靠网络环境下的数据传输。
- CoAP: 基于UDP的轻量级协议,适用于资源受限的物联网设备。
- HTTP: 广泛使用的应用层协议,适用于需要可靠传输的场景。
- WebSocket: 提供全双工通信,适用于需要实时数据交互的场景。
- Modbus: 工业自动化领域常用的通信协议,适用于工业控制系统。
- TCP/IP: 提供可靠的数据传输,适用于需要高可靠性的场景。
通讯层-MQTT协议
将MQTT协议集成到物联网项目中时,选择正确的MQTT Broker是关键。以下是一些流行的MQTT Broker选项,以及选择时需要考虑的关键因素:
- EMQ X:一个高性能、可扩展的MQTT Broker,支持多种协议和插件,适用于需要高并发处理的场合。官网:https://www.emqx.io/
- HiveMQ:提供社区版和企业版,支持MQTT 5,具备完整的功能和企业级特性,如数据持久性、集群支持等。官网: https://www.hivemq.com/
- VerneMQ:一个分布式MQTT Broker,专注于可靠性和可扩展性,适用于大规模物联网部署。官网:https://vernemq.com/
- RabbitMQ:虽然RabbitMQ本身不是MQTT Broker,但它通过插件支持MQTT协议,是一个广泛使用的开源消息代理,支持多种消息协议。官网: https://www.rabbitmq.com/
- Mosquitto:一个开源的MQTT Broker,轻量级且易于配置,适合小型到中型的物联网项目。官网:https://mosquitto.org/
Mqtt Broker 对比
特性/Broker | EMQ X | HiveMQ | VerneMQ | RabbitMQ | Mosquitto |
---|---|---|---|---|---|
开源 | 是 | 是 | 是 | 否 | 是 |
支持的协议 | MQTT, CoAP, LwM2M, HTTP等 | MQTT, WebSocket等 | MQTT | AMQP, STOMP, MQTT等 | MQTT |
性能 | 高性能,支持100M+连接 | 高可靠性,企业级性能 | 分布式,高可用性 | 多功能,高吞吐量 | 轻量级,适合中小规模 |
安全特性 | TLS/SSL, 访问控制,数据加密 | TLS/SSL, 客户端认证 | TLS/SSL, 插件支持安全特性 | TLS/SSL, 访问控制, RabbitMQ高级安全插件 | TLS/SSL, 访问控制 |
集群支持 | 支持 | 支持 | 支持 | 社区版不支持,企业版支持 | 基本支持 |
管理界面 | 用户友好的管理UI | 管理控制台和API | CLI工具和集成API | 管理插件和API | 命令行工具和配置文件 |
数据持久性 | 支持 | 支持 | 支持 | 通过插件支持 | 支持 |
社区活跃度 | 高 | 高 | 中 | 高 | 中 |
企业支持 | 提供 | 提供 | 提供 | 不适用 | 有限 |
选择MQTT Broker时的考虑因素:
- 性能和可扩展性:确保Broker能够处理大量并发连接和消息吞吐量。
- 安全性:检查是否支持TLS/SSL加密和身份认证,以保护数据传输的安全。
- 集群支持:评估Broker是否支持分布式部署,以实现负载均衡和高可用性。
- 管理工具:Broker是否提供易于使用的管理界面和监控工具,以简化日常运维。
- 协议支持:确认Broker支持的MQTT协议版本,包括对最新版本MQTT 5.0的兼容性。
企业级物联网平台的建议:
对于寻求高性能、可靠性和专业技术支持的企业级物联网平台,EMQ X或HiveMQ是理想的选择。这些商业MQTT Broker提供了强大的数据处理能力和全面的安全特性,能够满足企业在大规模部署时的需求。
在物联网项目的开发实践中,MQTT协议依赖于一种高效的主题订阅-发布机制来完成数据的交换。这种机制允许设备或应用程序订阅感兴趣的消息主题,从而接收到相关主题下发布的消息。因此,在软件应用的开发过程中,开发者必须构建一个功能完备的MQTT客户端管理模块。
接下来请思考一个问题:一个应用程序是否能够创建无数个MQTT客户端? 这个问题的答案当然是否定的。那么对于MQTT客户端管理模块的实现可以从以下几点进行考虑。
单个应用程序中需要根据一定的外部因素设置MQTT客户端的数量上限。常见的外部因素包括:
- 应用程序的内存大小
- 应用程序的CPU使用情况
- 应用程序的网络带宽使用情况
- 应用程序的线程数量
需要对MQTT客户端进行统一的管理,包括创建、销毁、监控、异常处理等。由于单个应用程序的MQTT客户端数量是有限的,因此还需要考虑多应用程序(多实例)部署问题、多实例负载均衡问题、多实例故障转移问题。
需要考虑在MQTT客户端中具体执行的任务,在数据推送间隔极短的情况下如果让MQTT客户端做一些重型的任务会加剧这个应用程序的资源使用情况,因此建议在MQTT客户端中直接将数据通过消息队列分发消息,做解耦。
接下来将介绍一种基于Redis实现的 MQTT 客户端管理方案。详细操作如下:
- 构建两个 列表数据结构的键,其中一个名为
use
另一个名为no_use
前者表示使用的,后者表示未使用的。这两个键中的数据基础信息如下:- 当前MQTT客户端ID
- MQTT Broker IP 地址
- MQTT Broker 端口
- 认证信息(账号密码或者其他)
- 需要订阅的主题
- 应用程序在启动时通过命令行、配置文件等方式设置最大MQTT客户端数量。
- 外部程序通过调用API与所有启动的应用程序进行交互(可以通过Nginx进行分发),外部程序会根据MQTT客户端ID、MQTT Broker IP 地址、MQTT Broker 端口、认证信息(账号密码或者其他)、需要订阅的主题等构建请求参数。
- 所有启动的应用程序中的任何一个应用程序收到请求后执行如下操作:
- 通过负载均衡算法,这里使用最简单的最小者优先算法,选择一个应用程序进行处理。
- 将请求转发给选中的应用程序,完成MQTT客户端创建。
- 选中的应用程序需要建立映射表来维护应用程序和MQTT客户端之间的关系。
- 将创建成功的MQTT客户端存储在Redis的
use
键中。
上述操作流程对于MQTT客户端的管理是极简的,但是存在一个问题,那就是当应用程序宕机后,所有与该应用程序关联的MQTT客户端都会被转移到no_use
键中,这样会导致MQTT客户端无法正常工作。因此,我们需要实现故障转移机制。以下是一个可行的方案:
- 每个应用程序都应当周期性的向Redis中写入自己还存活的信息,这是一个具备过期时间的键。
- 每个应用程序都应当对第一点中提到的键进行过期监听,当发现过期后则认为当前应用程序已经宕机。宕机后执行流程如下:
- 通过应用程序和MQTT之间的关系键找到宕机应用的关联MQTT客户端,将其转移到
no_use
键中。 - 通过负载均衡算法,这里使用最简单的最小者优先算法,选择一个应用程序进行处理。
- 将宕机应用的关联MQTT客户端转移到选中的应用程序中。
- 选中的应用程序需要建立映射表来维护应用程序和MQTT客户端之间的关系。
- 将创建成功的MQTT客户端存储在Redis的
use
键中。
- 通过应用程序和MQTT之间的关系键找到宕机应用的关联MQTT客户端,将其转移到
有关于MQTT客户端管理方案的设计告一段落,下面需要关注不同语言的MQTT客户端的实现,具体候选内容可以参考:
- Java:
- Eclipse Paho Java Client: https://github.com/eclipse/paho.mqtt.java
- HiveMQ MQTT Client: https://github.com/hivemq/hivemq-mqtt-client
- Python:
- JavaScript/Node.js:
- MQTT.js: https://github.com/mqttjs/MQTT.js
- Paho MQTT JavaScript Client: https://github.com/eclipse/paho.mqtt.javascript
- C#/.NET:
- Go:
- Paho MQTT Go Client: https://github.com/eclipse/paho.mqtt.golang
- gmqtt: https://github.com/DrmagicE/gmqtt
- C/C++:
- Eclipse Paho C Client: https://github.com/eclipse/paho.mqtt.c
- mosquitto-cpp: https://github.com/eclipse/mosquitto
- Ruby:
- ruby-mqtt: https://github.com/njh/ruby-mqtt
- paho-mqtt: https://github.com/RubyDevInc/paho.mqtt.ruby
- PHP:
- phpMQTT: https://github.com/bluerhinos/phpMQTT
- Mosquitto-PHP: https://github.com/mgdm/Mosquitto-PHP
- Rust:
- rumqtt: https://github.com/bytebeamio/rumqtt
- paho-mqtt-rust: https://github.com/eclipse/paho.mqtt.rust
- Swift:
- CocoaMQTT: https://github.com/emqx/CocoaMQTT
- MQTT-Client-Framework: https://github.com/novastone-media/MQTT-Client-Framework
通讯层-CoAP协议
将CoAP(Constrained Application Protocol)协议集成到物联网项目中时,选择合适的CoAP类库实现是关键。以下是一些流行的CoAP类库选项:
- Californium:一个由Eclipse Foundation开发的开源CoAP实现,用Java编写,提供了丰富的功能和良好的可扩展性。适用于需要高性能和可靠性的项目。官网:https://www.eclipse.org/californium/
- Libcoap:一个轻量级的C语言CoAP实现,适用于资源受限的嵌入式设备。它提供了CoAP协议的核心功能,并且易于集成到现有项目中。官网:https://libcoap.net/
- Go-CoAP:用Go语言编写的CoAP库,支持客户端和服务器功能。它提供了简洁的API,适合构建高性能的CoAP应用。 官网:https://github.com/plgd-dev/go-coap
CoAP 服务是一个长时间运行的服务,它即是请求-响应模型也是观察者模型。如果使用请求-响应模型,则可以按照如下方式进行设计:
- 使用开源的CoAP类库实现CoAP服务端。
- 创建多个CoAP服务端配合反向代理工具(Nginx)实现负载均衡,对外统一提供CoAP服务。
- 设备端通过CoAP客户端发送数据。
如果使用观察者模式,它的具体实现方式可以参考MQTT客户端的管理方案。
通讯层-HTTP协议
尽管HTTP(超文本传输协议)最初设计用于Web应用,但它在物联网项目中也有广泛应用,特别是在资源不那么受限的设备中。选择合适的HTTP服务器对于构建高效的物联网应用至关重要。 有关于Web应用开发可以使用到的开发框架有:
Django:基于Python的高级Web框架,提供了完整的开发栈。其”电池包含”的理念和强大的ORM使其非常适合快速开发复杂的物联网后端系统。 官网:https://www.djangoproject.com/
Flask:轻量级的Python Web框架,灵活性高,适合构建小型到中型的物联网应用。其简洁的API和丰富的扩展生态系统使得开发过程更加高效。 官网:https://flask.palletsprojects.com/
Express.js:基于Node.js的Web应用框架,以其简洁和灵活著称。它特别适合构建快速、轻量级的API,非常适合物联网项目中的数据处理和设备通信。 官网:https://expressjs.com/
Spring Boot:基于Java的强大框架,提供了快速构建独立的、生产级别的Spring应用的能力。它的自动配置特性和丰富的生态系统使其成为构建物联网后端服务的理想选择。 官网:https://spring.io/projects/spring-boot
Gin:用Go语言编写的Web框架,以其高性能和轻量级著称。Gin的速度快、内存占用低,非常适合构建高并发的物联网API服务。 官网:https://gin-gonic.com/
Web应用是一个长时间运行的服务,它是请求-响应模型,可以按照如下方式进行设计:
- 使用开源的Web应用开发库实现Web应用服务。
- 创建多个Web应用服务配合反向代理工具(Nginx)实现负载均衡,对外统一提供Web服务。
- 设备端通过HTTP客户端发送数据。
通讯层-WebSocket协议
WebSocket是一种在单个TCP连接上提供全双工通信的协议,特别适合需要实时数据交换的物联网应用。与HTTP的请求-响应模型不同,WebSocket允许服务器主动向客户端推送数据,这在物联网场景中非常有用。以下是一些流行的WebSocket库和框架:
- Socket.IO:一个强大的JavaScript库,支持实时、双向和基于事件的通信。它在WebSocket不可用时可以自动降级到其他传输方式。 官网:https://socket.io/
- ws:一个简单易用、高效的纯WebSocket实现,适用于Node.js环境。它是许多其他WebSocket库的基础。 官网:https://github.com/websockets/ws
- Spring WebSocket:Spring Framework的一部分,为Java应用程序提供WebSocket支持,与Spring的其他组件无缝集成。 官网:https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#websocket
WebSocket应用的具体实现可以参考以下流程:
- 使用选定的WebSocket库实现WebSocket服务。
- 创建多个WebSocket服务实例,配合负载均衡器(如HAProxy)实现负载均衡。
- 实现简单的连接管理:
- 定期执行清理任务,移除长时间不活跃的连接。
- 实现基本的心跳机制,但不需要复杂的连接池管理。
- 设计消息处理流程,包括消息解析、验证和路由。
- 实现安全认证机制,确保只有授权设备能够建立WebSocket连接。
通讯层-Modbus协议
Modbus是一种广泛应用于工业自动化和控制系统的通信协议。在物联网平台中集成Modbus协议支持,可以使平台与大量工业设备和传感器进行通信。常见的基于Modbus协议开发的SDK有:
- libmodbus:一个跨平台的Modbus库,支持RTU和TCP。官网:https://libmodbus.org/
- pymodbus:Python实现的Modbus库。官网:https://github.com/riptideio/pymodbus
- jamod:Java实现的Modbus库。官网:http://jamod.sourceforge.net/
除了对于开源库的选择以外还需要考虑Modbus的变种支持,常见的Modbus变种有:
- Modbus RTU:适用于串行通信
- Modbus TCP:适用于以太网通信
- Modbus ASCII:适用于某些特定设备
在Modbus变种支持中作为软件开发者(服务端开发)会更加倾向实现 Modbus TCP 协议,因为 Modbus RTU 协议需要使用串口进行通信,而串口在服务器上比较少的存在。
通讯层-TCP/IP协议
TCP/IP是互联网的基础协议,在物联网平台中也扮演着重要角色。虽然许多高层协议(如HTTP、MQTT)都基于TCP/IP,但有时我们也需要直接使用TCP/IP进行通信。常见的TCP/IP开发SDK有:
- Boost.Asio:一个跨平台的C++库,提供了对TCP/IP协议的支持。官网:https://www.boost.org/doc/libs/release/libs/asio/
- Netty:一个基于Java的异步事件驱动网络应用框架,支持TCP/IP协议。官网:https://netty.io/
- lwIP:一个轻量级的开源TCP/IP协议栈,适用于嵌入式系统。官网:https://savannah.nongnu.org/projects/lwip/
- libuv:一个跨平台的异步I/O库,支持TCP/IP协议,常用于Node.js。官网:https://libuv.org/
在物联网平台中直接使用TCP/IP协议进行通信时,需要注意以下几点:
- 连接管理:实现连接的建立、维护和关闭,确保连接的稳定性和可靠性。
- 数据传输:设计高效的数据传输机制,确保数据的完整性和及时性。
- 安全性:实现数据加密和身份认证,防止数据泄露和未经授权的访问。
- 兼容性:确保与不同设备和操作系统的兼容性,支持多种网络环境。
- TCP/IP 作为一种底层协议,对开发人员的技术要求较高,需要具备较强的网络编程能力。
通过合理使用TCP/IP协议,可以实现高效、可靠的物联网通信,满足各种应用场景的需求。
通讯层-安全认证
前面对通讯层中使用到的协议做了相关介绍,这里将着重讨论通讯层中的安全认证。在MQTT协议中,安全认证的实现方式有:
- 用户名和密码认证:通过为每个设备分配唯一的用户名和密码,在连接建立时进行认证。认证通过后,设备即可进行数据传输,否则连接将被断开。
- 证书认证:使用SSL/TLS证书进行双向认证,确保数据传输的安全性和完整性。设备和服务器都需要持有有效的证书,连接建立时进行相互认证。
对于其他协议,如CoAP、HTTP、WebSocket等,开发者需要自行实现认证模块。常见的认证模式包括:
- 账号密码认证:为每个设备分配账号和密码,在连接建立后进行认证。认证通过后,允许数据传输,否则断开连接。
- Token认证:设备在首次连接时通过账号密码获取Token,后续连接时使用Token进行认证。Token具有时效性,定期更新以确保安全。
- OAuth认证:使用OAuth协议进行认证,设备通过OAuth服务器获取访问令牌,使用令牌进行数据传输。适用于需要第三方认证的场景。这个场景更多的时候是用于Web应用的认证,在物联网平台中使用较少。
通过合理设计和实现安全认证机制,可以有效保障物联网平台的数据安全和设备通信的可靠性。
数据解析层
数据解析层的主要功能是对通过各种通讯协议传输的数据进行解析和转换,使其成为人类可读的格式或符合系统设计的格式。在数据解析过程中,通常可以使用JavaScript、Lua、Python等脚本语言来完成。为了确保解析过程的高效性和一致性,从程序设计角度出发,主要考虑以下设计:
- 统一设计返回结果:确保所有解析器返回的数据格式一致,便于后续处理和分析。
- 抽象设计不同脚本语言的执行器:提供一个通用的接口,支持多种脚本语言的解析器,方便扩展和维护。
下面提出一个统一的数据返回结果。
type DataRowList struct {
Time int64 `json:"time"`
DeviceUid string `json:"device_uid"`
IdentificationCode string `json:"identification_code"`
DataRows []DataRow `json:"data"`
Nc string `json:"nc"`
}
type DataRow struct {
Name string `json:"name"` // 信号键
Value string `json:"value"` // 信号数值
}
上面的程序定义了一个名为 DataRowList
的结构体和一个名为 DataRow
的结构体,用于统一数据解析层的返回结果。
DataRowList
结构体包含以下字段:Time
:秒级时间戳,表示数据的时间。DeviceUid
:设备唯一编码,这个是站在软件服务端的唯一标识。IdentificationCode
:物理设备标识码,用于进一步标识设备。这个数据在MQTT客户端订阅通配符的情况下需要着重使用。DataRows
:一个DataRow
结构体的切片,包含多个数据行。Nc
:一个字符串字段,表示原始数据,即需要解析的数据。
DataRow
结构体包含以下字段:Name
:信号键,表示数据的名称。Value
:信号数值,表示数据的具体值。
通过定义这两个结构体,可以确保所有解析器返回的数据格式一致,便于后续处理和分析。同时,抽象设计不同脚本语言的执行器,提供一个通用的接口,支持多种脚本语言的解析器,方便扩展和维护。
数据链路流程:
- 设备端通过通讯协议传输原始数据到物联网平台
- 物联网平台通过解析器解析原始数据
- 将解析后的数据进行存储
- 返回确认收到的响应
用户管理层
用户管理层是任何一个企业级系统都需要具备的模块,其主要功能包括:
- 用户管理:提供用户的创建、删除、修改和查询功能,确保用户信息的准确性和完整性。
- 角色管理:定义和管理系统中的角色,分配不同角色的权限,确保用户能够根据其角色执行相应的操作。
- 权限管理:细粒度地控制用户对系统资源的访问权限,确保数据的安全性和合规性。
- 组织架构管理:管理企业的组织架构,包括部门、团队等,支持复杂的组织层级关系,便于权限的分配和管理。
- 审计日志:记录用户的操作行为,提供审计和追踪功能,确保系统的透明性和可追溯性。
- 单点登录(SSO):集成单点登录功能,简化用户的登录流程,提高用户体验。
- 多因素认证(MFA):提供多因素认证机制,增强系统的安全性,防止未经授权的访问。
- 用户活动监控:实时监控用户的活动,及时发现和处理异常行为,保障系统的安全运行。
对这块内容的实现,可以参考开源的RBAC权限管理框架,如Casbin。Casbin是一个强大且高效的开源访问控制库,支持多种访问控制模型,如ACL、RBAC、ABAC等。更多信息请访问官网:https://casbin.org/
数据分析层
数据分析层在物联网平台中是一个关键的模块,它负责对平台中的数据进行分析和处理,以支持业务决策和数据驱动的决策。常见的分析功能包括:
- 数据区间预警:通过设定数据的正常区间范围,当数据超出或低于该范围时,系统会自动发出预警通知。
- 多维度数据联合预警:结合多个数据维度进行综合分析,设定复杂的预警条件,当满足特定条件时触发预警。
- 统计分析:对历史数据进行统计分析,生成各种统计报表和图表,帮助用户了解数据的分布和趋势。
- 数据可视化:通过图表、仪表盘等形式直观展示数据,帮助用户快速理解数据背后的信息。
预警设计
在设计数据分析层时,需要避免重复部署的问题,应尽可能采用可视化的配置方式处理。即使需要执行一些复杂逻辑,也应尝试使用脚本语言完成。基本设计关系如下:
- 信号需要具备多个区间的报警阈值,实现分级报警的能力。
- 信号数据需要能够进行最大N条的暂留,实现多维度数据联合分析的能力。
- 针对多维度数据联合预警做出脚本管理,并要与信号进行关联从而实现实现多维度数据联合分析的能力。
数据区间预警场景下的数据执行链路:
- 原始数据经过解析脚本解析,得到需要分析的数据。
- 数据进入区间报警消息队列,判断是否处于报警范围内,如果是则进行消息通知。
- 将第一步中的数据放入暂存区。
多维度数据联合预警的数据执行链路:
- 原始数据经过解析脚本解析,得到需要分析的数据。
- 找到信号对应的联合报警条件,判断是否满足条件。
- 如果满足条件则进行消息通知。
统计设计
接下来对统计相关内容进行设计,常见的统计是基于定时任务触发的,一般定时任务的执行逻辑如下:
- 定时任务触发
- 根据时间范围查询需要统计的信号值
- 编写具体的统计计算规则
- 将统计结果进行存储
根据上述逻辑提取一些核心参数:
- 定时任务执行时间(CRON表达式):定时任务的执行时间是时间范围的结束时间
- 前移时间:通过定时任务执行时间减去前移时间得到时间范围的开始时间
- 计算脚本:通过脚本语言编写具体的统计计算规则
在这个设计中,定时任务的执行时间由CRON表达式确定,用于设定统计任务的执行时间。通过消息队列的过期消息来实现定时任务,而不采用XXL-JOB等分布式定时任务框架,是为了追求轻量化部署。
可视化设计
前面的种种设计已经完成了对数据的积累,接下来需要给用户看到相关的数据内容。可以选择开源的组件进行可视化表达,具体可以使用的有:
- 数据大屏:推荐使用开源的ECharts组件进行数据大屏的展示。ECharts是一个强大的数据可视化库,支持多种图表类型和交互功能,适用于构建复杂的数据大屏。官网:https://echarts.apache.org/
- 数据看板:推荐使用开源的Grafana组件进行数据看板的展示。Grafana是一款开源的监控工具,支持多种数据源和丰富的可视化插件,适用于实时数据监控和分析。官网:https://grafana.com/
- 数据报表:推荐使用开源的JasperReports组件进行数据报表的展示。JasperReports是一个功能强大的报表生成工具,支持多种数据源和复杂的报表设计,适用于生成各种格式的报表。官网:https://community.jaspersoft.com/
- 自定义大屏:推荐使用开源的DataV组件进行自定义大屏的展示。DataV是一个数据可视化平台,提供丰富的可视化组件和灵活的配置选项,适用于构建个性化的数据大屏。官网:https://datav.aliyun.com/
数据存储层
本节将对数据存储层的内容进行相关分析。
- 常规关系型数据存储:选择MySQL或者其他关系型数据库。关系型数据库适用于存储结构化数据,提供强大的查询和事务处理能力,适合存储用户信息、设备信息等常规数据。
- 信号点位数据存储:选择InfluxDB,也可以选择其他时序数据库。时序数据库专为处理时间序列数据设计,适合存储设备的传感器数据、日志数据等,提供高效的写入和查询性能。
- 报警历史数据存储:选择MongoDB进行存储。MongoDB是一种NoSQL数据库,适合存储非结构化数据和半结构化数据,支持灵活的文档模型,适合存储报警历史记录等数据。
- 统计数据存储:选择MongoDB进行存储。MongoDB的灵活性和扩展性使其适合存储各种统计数据,支持复杂的查询和聚合操作,便于进行数据分析和报表生成。
在进行数据存储层设计时,分库分表是一个重要的考虑因素。以InfluxDB为例,如果是一个面向企业的项目,可以利用InfluxDB中的组织概念。为每一个客户创建一个组织,并在组织下创建不同的bucket进行数据隔离。通常,bucket可以根据设备数量进行分片,以提高数据管理的效率。
对于MongoDB,由于其不具备组织的概念,开发者需要自行实现类似的组织管理机制。通常可以通过以下方式实现数据隔离:
- 使用不同的数据库(库)来代表不同的组织。
- 在每个数据库中使用不同的集合来存储同类数据。
这种设计方法可以有效地实现数据隔离,确保不同客户的数据不会混淆,同时也便于管理和扩展。
通知层
本节将对通知层进行详细分析。平台的通知通常分为两类:系统内通知(站内信)和系统外通知。 在通知层最重要组成部分如下:
- 消息模板,一般会采用
${}
这种形式进行变量替换。 - 消息通道,是用飞书、钉钉、微信、短信、邮件等进行消息通知。
消息模板
消息模板是通知系统的核心部分,它定义了通知的格式和内容。通过使用占位符(如 ${}
),可以在发送通知时动态替换具体的内容。常见的消息模板包括:
- 告警通知模板:用于发送设备异常或数据超出阈值的告警信息。
- 系统通知模板:用于发送系统更新、维护等信息。
- 用户通知模板:用于发送用户注册、密码重置等信息。
示例模板:
告警通知:
设备 ${device_name} 在 ${timestamp} 发生了 ${alert_type} 告警,当前值为 ${current_value}。
系统通知:
尊敬的用户,系统将在 ${maintenance_time} 进行维护,期间可能会影响您的使用,请提前做好准备。
用户通知:
您好,您的账号 ${username} 已成功注册。请点击以下链接激活您的账号:${activation_link}
消息通道
消息通道是通知系统的传输媒介,不同的消息通道适用于不同的通知场景。常见的消息通道包括:
- 飞书:适用于企业内部的即时通讯和通知。
- 钉钉:适用于企业内部的即时通讯和通知。
- 微信:适用于广泛的用户群体,支持个人和企业通知。
- 短信:适用于重要的紧急通知,确保用户能够及时收到。
- 邮件:适用于正式的通知和长文本内容。
运维层
运维层是物联网平台中不可或缺的一部分,主要负责平台的监控、管理和维护工作。运维层的设计需要考虑系统的高可用性、可扩展性和安全性。以下是运维层的几个关键组成部分:
- 监控系统
- 备份与恢复
监控系统
监控系统是运维层的核心,负责实时监控平台的运行状态,及时发现和处理异常情况。常见的监控系统包括:
- Prometheus:一个开源的系统监控和报警工具,适用于监控各种指标数据。官网:https://prometheus.io/
- Grafana:一个开源的可视化工具,可以与Prometheus等监控系统集成,提供丰富的图表和仪表盘。官网:https://grafana.com/
注意:Prometheus 的监控需要在应用程序中进行相关设置,否则将无法进行监控。
备份与恢复
备份与恢复是运维层的重要保障措施,确保在发生故障时能够快速恢复系统。常见的备份与恢复策略包括:
- 全量备份:定期对系统进行全量备份,确保数据的完整性。
- 增量备份:对变化的数据进行增量备份,提高备份效率。
- 灾难恢复:制定灾难恢复计划,确保在发生重大故障时能够快速恢复系统。
注意:所有的备份方案需要通过程序侧进行处理,可能需要进行额外开发。