设备中心项目

乐云一
  • 业务
  • 业务
About 2590 wordsAbout 9 min

为防止颅内退化,自己做过的事被遗忘;

将自己做过的项目经验记录下来变得非常有必要,本篇将记录的是,云平台,设备中心的项目经验

首先从项目的技术说起,和主流互联网项目技术一致,springboot一套,redis缓存,数据库mysql,mongdb。

技术

纯后台中心应用,使用了目前互联网主流体系的技术与框架

开发框架SpringBoot一套MyBatis-pluseasy-ruleDubbo

中间件redismqttrabbitmqkaffkanacosXXL-JOB

数据库MysqlMongdbInfluxDB

工具极光推送阿里云OSS阿里云短信

这是什么

设备中心,顾名思义,聚合设备的中心。

由三部分组成:

  1. 设备管理
  2. 设备网关
  3. 设备连接桶

设备管理: 包括但不限于设备的基本信息管理,设备消息的发送上游、设备远程云端功能的实现、设备登录、创建、烧录等操作的入口等等

设备网关:包括但不限于设备连接设备中心的中驱,设备消息的接收上游与实际发送消息者,设备消息的处理与分发、设备权限与路由的分配管理等等

设备连接桶:设备与设备中心进行业务级连接的地方

用白话文解释设备中心存在 的意义:

设备通过设备连接桶,登记自己的连接信息并且拿到对应的设备中心网关地址;

连接成功后,将自己的功能运行状态或者当前的属性状态\属性状态的变更,下发给设备网关,网关通过路由的负载均衡分配给设备中心。

设备中心将记录设备上报的属性状态,并且更新这台设备在设备中心的快照模型。

功能的运行,比如设备开、关、改变模式、属性变更等等,通过规则引擎下发给该设备配置的对应应用

有什么用

设备成功接入到设备中心之后,用户可以通过设备中心进行如下操作:

  1. 操作设备
  2. 获得设备当前信息和属性
  3. 同步设备
  4. 为设备进行云端功能赋值,比如云呼叫、云视听、OTA升级、设备配对等等...
  5. 设备黑名单,功能权限,信息修改等等管理功能
  6. 智能语音云平台、产商云平台等等云对云协议的接入
  7. ...

操作设备,获取信息等基础功能不说,拿云端功能赋值说说:

假设一台设备A,在生产的设计中只有开关功能。

生产之后客户想要一个语音对讲的功能如何实现?

按照正常的流程,需要将设备重新设计,进行硬件级的开发。

但是假如公司有云平台-设备中心的存在,为一个设备赋予语音对讲的功能就变的很简单了:

  1. 在设备中添加语音对讲标准模型的硬件
  2. 连接网络,接入设备中心
  3. 下载我司有语音对讲功能的APP,配对设备,使用其功能

这就是直接可以以最低成本为一个设备进行功能上的额外赋能

除此之外,设备端也可以通过接入设备中心用来为后续的功能扩展、软件升级、信息修改等云端远程功能预留入口

并且作为设备中心,是所有设备发送消息与接收消息的中轴。

以此为中心,可以通过mq转发的形式向下拓展无数个子级应用

怎么做的

设备连接通过与设备中心拟定的协议,通过mqtt建立长连接;

建立连接的过程类似用户登录,流程如下:

  1. 从连接桶拿到网关的请求地址和授权token
  2. 连接网关,通过授权码获得唯一登录的设备id和登录token
  3. 后续发送消息通过设备id+登录token鉴权

设备登录后就可以与设备中心进行请求-响应的消息交互;

消息交互流程如下:

  1. 开启线程池,拒绝策略为抛弃任务
  2. 根据约定好的协议,解析设备消息体
  3. 构建责任链的头链,并且开启链路,链路目前有如下:
    1. 异常消息体处理
    2. 响应消息处理
    3. 请求消息处理
    4. 限流处理
    5. 设备消息处理
  4. 设备消息处理为核心处理器,在这里将消息给到了消息解析器进行操作。
  5. 消息下发给规则引擎,通过mq转发给子级应用

技术难点

数据模型

设备会将自身的所有属性上报给设备中心,并且这个动作非常非常频繁。

比方说传感器,每秒上报自己的传感数据。

因此如果需要做到设备快照数据的时效性,就必须去考虑缓存设计以及部分更新的原则;

先判断读多还是写多,然后再思考数据一致性的强度,最后综合考虑性能成本;

  • 数据存redis中,存redis的问题是属性进行修改时耗费很大,需要使用lua脚本而且是针对整个模型。假如模型数据过多,会很慢。

    但是使用redis的原因也很明显,读取性能更高。

  • 数据存mongdb中,基于文档型存储的方式保存性能更高,但是频繁读取性能弱于redis

因此会将设备的上报种类分为369等,经常读的会存在redis中,读的少的则会使用模型文件冷处理,生成文档对象存储在mongdb中。

针对数据一致性问题,分两种情况。

一是查询设备中心的设备数据,二是消费设备中心mq转发过来的设备数据。

比方说设备得上下线状态,在设备中心中,因为设备消息通过线程,队列,更新缓存原因会出现短时间内在线状态不一致的问题。

而通过消息中心转发的设备数据,则可能因为消息堆积,消费速率等影响,影响数据的实效性。

因此数据一致性,不单单只是缓存与数据库中内容一致性问题;还有应用APP上看到的和设备上展示的数据一致的问题;

前者考虑到的是最终一致性,可以接收短时间内数据库数据不一致,但是模型缓存一定会最先更新。

后者则是需要平衡整个链路的时间,从拿到设备中心转发过来的数据到具体使用的业务时间

设备数据存储

除了设备的数据模型外,设备中心还会记录一项非常重要的数据:设备日志

包括但不限于:上下线记录,上报数据记录,交互记录等等

最初考量一个数据库Mysql是能吞下,但是随着设备量的增大,表数据不可控的提升,最终会出现什么情况是可以预见的;

讨论的方案有两种:

  1. 水平,垂直分表,依然使用Mysql存储
  2. 数据库分摊压力,采用InfluxDB记录日志型数据

后者更适合此数据的存储场景

不同地区连接当地设备中心

cdn

设备中心本地化部署

边缘网关的设计

转发规则引擎

规则引擎使用

本地测试问题

因为设备不能像网页测试那样自由的进行环境切换,因此在烧录注册到设备中心的时候,一般使用的是设备中心测试环境,

国内外设备中心数据同步

项目实际生产Bug

nginx占用长连接

有一批设备,提供给的连接地址是通过nginx转发后的路由;

nginx针对http连接的处理是,转发结束就断开。

但是设备占用通过nginx去连接mqtt占用的是一个http长连接,而http长连接会在服务器上固定一个port;且nginx对此连接数有限制, 默认为2000.

所以通过时间推移,数据量变大,恰好并发产生将nginxhttp连接全部占满;

解决方式很简单,直接使用域名映射,不适用nginx

同时间戳重复消息

有一段时间,设备反应设备中心响应混乱,比方说设备一条发送请求,收到了多条响应请求,并且响应的报文是一样的;

线程池不够用

有一批设备的OTA升级流程会存在多次请求-响应的交互过程,因为设备对ota业务的调整会导致业务中时间过长;

由于是批量,并且一个设备是单独占据一个消息线程的。

在测试中,因为设备与设备中心都是在内网或者外网较近的环境下,因此每一天消息都会处理很快。

但是当设备迁移到偏远地区,比如国外服务器部署在德国,设备在俄罗斯,会存在毫秒级的网络阻塞问题;

最终定时任务+消息线程+规则引擎,将线程池直接占满。

导致这批设备批量进行ota升级时,有几台会进入重试状态;

解决:

虽然设备功能依然会因为重试机制正常运行,但是对调试人员来说体验很不好。

最终优化是:线程池不够,在大小不能扩容的前提下,进行跨线程的扩容。即设置一个项目体积非常小的mini设备中心,仅分担需要用到线程池进行简单交互:

比如mq转发、设备交互、回执等等的动作;

Last update:
Contributors: LeYunone
Comments
  • Latest
  • Oldest
  • Hottest
Powered by Waline v2.14.7