基于mosquitto快速构建支撑海量设备的物联网接入平台

本文对应的论文已经发表,对应专利已经授权!参考或使用请与作者沟通;转载请附带本文原始链接。

       该方案采用组件化(服务化)设计与开发,上、下行通道分离,各服务可自由组合、支持设备端根据业务场景进行多种方式上报数据,下行通道主要用于和终端设备之间保持长连接,让消息能够快速、必达设备端。

       为什么要采用上下行分离的方式?最主要原因是上下行的使用场景不同,对传输通道的要求不同。一般下行用于下发控制指令,要求数据能及时送达终端,并且要保证消息不丢,因此下行系统需要与设备端保持长连接,它必须具备承载及处理大量连接的能力;而上行通道用于上报数据,由于设备类型千差万别,上报的数据的类型方式各不相同,数据上行系统需要根据上报数据的性质提供不同的数据上报方式

       下面的内容中,第1部分主要介绍消息的下行,用于处理大并发连接,并给在线终端设备发送消息;第2部分介绍消息缓存,它与第1部分结合不仅能给在线设备发送消息,也可以给离线设备发送消息,并且可以确保消息必达设备。第3部分主要介绍三种数据上行的实现思路。第4部分主要是综述这些服务(组件)的自由组合方式。

一、下行通道

下行通道主要指部署在云端的后台程序给终端设备下发数据,这种下发数据的方式可简单分为两种:

  • 设备主动拉取,这种方式实现起来非常简单,例如设备定期休眠结束之后,直接向后端发送http(s)请求并获取所需要的数据。
  • 后端主动推送,这种方式能保证消息实时送达,也是最常用的方式,所以下面主要针对这种方式进行介绍。

1.1 通知推送服务(NPS)

通知推送服务采用开源+自研方式,开源软件采用Mosquitto,Mosquitto是最早的、专门针对MQTT协议的开源Broker之一(它也支持websocket),成熟、稳定、小巧,而且性能非常好,单个Mosquitto进程预计能承载5~20万连接(优化之后性能还可以翻倍),例如采用MQTT协议时单进程支持50万连接(每秒发送数据的速度约2万条/秒)。

架构示意图

       在上图中,MosqProxy完成Mosquitto集群的管理、负载均衡,以及接入设备的管理,MosqProxy所连接的Redis中记录了哪个设备连接到哪个Mosquitto上?

1.2下行通道主要功能

  • 维持与终端设备的大量长连接,生产环境最小化集群(2个nps+2个Mosuqitto)也可支持5(通道加密)~50(通道不加密)万连接;
  • 支持应用层加密和通道加密(TLS);
  • 通讯协议为:HTTP(s)、MQTT、MQTT+TLS、WEBSOCKET、WEBSOCKET+TLS;
  • 确保通知及时下发到终端设备(注意:这里只给在线设备发送消息);
  • 设备的在线状态感知;
  • 支持Mosquito动态负载均衡以及Mosquitto故障时自动切换;

1.3设备接入过程

(1)设备首先通过HTTP(S)向后台请求Mosquitto连接地址,MosqProxy最终收到请求后根据每个Mosquitto的负载情况,为当前终端/边缘设备分配一个负载最轻的Mosquitto地址;这种在设备接入时动态获取Mosquitto地址的方式同时也实现了Mosquitto的动态负载均衡。

(2)设备接收到Mosquitto地址之后,与Mosquitto之间建立长连接;

(3)当有应用服务通知要发送给终端/边缘设备时,将消息封装成JSON格式字符串交给MosqProxy,MosqProxy首先查询目标设备在哪个Mosquitto上,然后通过该Mosquitto将消息下发给终端设备。

1.4终端/边缘设备在Mosquitto服务端故障时的自动切换策略

(1)终端设备在连接断开之后,第一次随机一个n(例如n=10)秒的时间休眠,休眠之后尝试重连;

(2)第一次重连失败,则进行指数退避;最多退避到一个固定值(例如300秒)之后还连不上,则再次向后端请求分配新的Mosquitto地址进行连接。

二、消息管理服务(MMS)

消息管理服务(MMS)结合通知推送服务(NPS)可从应用层面确保消息必达设备终端;其实质是对发往终端设备的消息进行服务端缓存。

部署在云端的服务程序与终端传递消息的方式一般有三种:

(1)推模式,服务程序把数据直接通过长连接推送给终端,只要服务程序把数据成功交给本地操作系统的socket发送缓存就认为消息推送成功,不管底层网络是否把消息传递到对方操作系统,对方操作系统是否传递到应用程序;这种方式只能给在线终端发送,简单、快速,但是容易造成消息丢失。

(2)拉模式,这种方式无论在线还是离线方式都能发送成功;其思路为:消息先发往服务端进行缓存,然后通过长连接给终端应用发送一条新消息到达的通知(注意:只推了通知没有推送消息的内容),终端应用收到通知之后拉取消息,并进行消息处理,处理完毕之后再删除;当终端离线之后重新上线时需要无条件拉取并处理自己的离线消息。这种方式的缺点是效率低,优点是实现相对简单,不易出错。

(3)推拉混合模式,该模式结合推、拉两种模式,即能给在线设备发送消息,也能给离线设备发送消息;其思想是:消息先发往服务端缓存,然后将消息内容发送给终端应用,应用如果在线,则直接处理消息,处理完毕之后再去删除服务端缓存的消息,与拉模式相比,省去了拉取消息内容的动作;在终端设备离线情况下,与拉模式处理方式相同。

       在上面介绍的三种消息发送模式中,第2、3中都需要服务端临时缓存消息,本节介绍的消息管理服务(MMS)就是一种部署在云端的、为每个终端设备提供消息缓存队列功能的服务,它完成基于设备ID的消息存放、拉取、删除操作,MMS可基于Redis集群构建,对外提供REST接口(接口包括:存储消息、拉取消息、删除消息等);其工作方式为:

(1)在Redis集群中为每个设备提供一个消息队列;

(2)消息发送时先将消息插入到接受设备的队列中,然后通过NPS给设备发送新消息到来的通知;

(3)接收设备收到通知后从自己的消息队列中拉取所有未处理消息,然后进行处理,处理之后,自行删除;

(4)接受设备在断线重连之后需要无条件从自己的消息队列中拉取离线消息,并且完成消息处理之后,要将处理过的消息进行删除以防止消息的重复处理;

其架构如下所示:

 消息管理服务

三、数据上行

数据上行是指设备向服务端上传各种应用数据,在物联网应用中,数据上报类型多种多样,在项目实施过程中也应该依据数据类型不同,为之部署不同的数据接收服务,本节介绍三种常见的数据上报方式(视频也是另外一种数据上报方式,后续可专门进行讨论和沟通):

(1)低频小数据量(例如一次上报的数据大小在K级别),短连接,http(s)上传;这种方式,设备无需为上报功能再维持一个长连接。针对这种数据,可开发一个基于Rest风格的数据接收服务,数据接收之后,转只MQ即可;该服务功能简单可水平扩展,很容易应对设备量大时聚集起来的高并发(虽然每个设备上报的频率很低,但是设备的数量很大时,一样可以为后端造成高并发压力)。

低频小报文数据上报系统

        自研的数据接收服务必须能高效接收上报的数据,可采用java开发,其实质是结合存储数据,采用支持并发的队列,让收与发之间异步完成,对外提供高并发的数据接收服务,内部逻辑如下图所示:

 数据接收服务内部逻辑示意图

(2)低频大数据量(例如:上报一个M级别大小的日志文件)一般通过文件上传,分为两步:

  • 直接上传到后端独立的分布式文件系统上;分布式文件系统可基于FastDFS(用它最快)、HDFS、TFS等搭建;如果在公网可直接上传至阿里云的oss等;
  • 发送消息到低频小报文上报系统,消息内包含:什么设备在什么时间上传了什么文件(文件地址)等信息,信息内容可由应用自己定义。

应用系统获取到设备上报的消息之后,通过消息体内容获取上传文件的地址,然后再下载文件并进行处理,其过程如下图所示。

低频大数据上报系统

(3)高频小数据量(一次上报的数据在K级别),长连接,MQTT协议上传,其集群方式如下图所示

 高频小报文数据上报系统

其中,NPS只负责为终端设备分配Mosquitto,无需中转下行消息,其负载均衡方式与下行一样。注意:与下行的NPS相比,这里的Mosquitto同时承载的连接量要适当缩小,因为其tcp通道上的消息发送速度大于下行的命令下发速度。

       IOT系统与视频服务的对接;系统间的融合一般可简单划分为:数据融合、系统融合、应用展示融合;由于视频传输的特殊性,一般都是独立的流媒体服务完成视频流的转发、存储、点播,只需要做到对外展示功能的融合即可,因此在视频服务选型中只要视频服务能对IOT系统提供如下api接口即可:

  • 摄像头控制;
  • 实时视频查看;
  • 视频点播、下载等;

四、总结

        本文思路中很重要的一点是尽最大程度利用目前开源、成熟的业务组件,减少业务开发量,加快开发进度,同时能做到服务复用(一次开发,多次/多个项目重复使用)、灵活组装,以满足不同的业务场景,适应目前和未来各种项目的要求;对于自由组装,例如在电力领域的传感器中,很多场景或项目不需要对设备发送指令,就不需要部署下行的通知推送系统;还有一些场景可能传感器上报的频率比较低,例如5分钟、10分钟才上报一次小报文数据,那么只部署一个“低频小报文的数据上报系统”就可以了。对于组件复用,例如下行的通知推送系统即可部署在物联网领域进行指令推送,还可部署在其他应用程序中作为消息推送系统给终端设备/用户进行消息推送,例如:终端是浏览器时用websocket协议推送,终端是各种手机app时用mqtt协议进行消息推送。

        这种灵活的组装方式,需要在设计和研发过程中遵循组件化、产品化的要求,最重要的体现是让测试团队参与项目整个过程,把质量控制的重点放在项目推进的过程中,而不仅仅是验收阶段;例如,对于每个服务化的组件(例如下行的推送系统,注意不是里面的Mosquitto或者NPS,它必须能独立完成一个可复用的功能)都是一个单独的小产品,都需要提供相关文档说明:服务是干什么的?大概怎么干的?怎么调用(提供使用示例代码)?怎么部署?以及相应测试报告,测试报告中包括但不限于如下内容:

  • 功能完善性测试,主要对接口进行功能测试;
  • 性能测试(包括正向压力测试和反向压力测试),新服务需要进行7*24小时压测;
  • 部署文档测试。

        在实际项目过程中涉及的组件可能不止上述组件,例如常用的设备管理服务,对外接入网关等等,下面给出了这种整体架构的示意图:

整体结构示意图

这里需要注意:

1、上述系统在对接时对设备端有很多要求,为简化设备端的使用复杂度,需要将对设备端的约束封装成SDK提供给用户,以集成到应用系统中,还可以做成agent程序独立运行,做成agent的方式可以让设备端多个应用程序共享一个agent通道,如下图所示:

(1)统一内部消息格式,该消息格式主要用于iot云端和终端之间的消息传输,对应用方,无论对终端应用程序还是对接云端的服务都不可见,消息格式使用JSON定义,例如:

{

“id”:”201902190011”,//消息ID,不可重复,全局唯一;

“type”:1,//消息类型,为1表示获取服务的地址

“version”:“1.0”,//协议版本

“content”:[“push”,“service_center”]//待获取服务的ID

}

(2)启动时自动获取所需服务的地址;

(3)对于数据下行功能,所有设备端需要默认订阅同一个管理topic,例如:iot/sys,并能识别特殊功能的消息,例如:切换Mosquitto地址的消息;通过类似设计,能让iot云端对设备端进行管理,例如:让某个Mosquitto下面30%的设备重新负载到其他Mosquitto上,还可以指定某个设备重新更换连接和秘钥。

(4)长连接断线重连的退避策略,长连接断开之后不应马上重连,应该有策略重试,退避之后依然不行时,需要自动获取并切换到其他Mosquitto;

(5)对IOT系统传输的数据进行应用层加解密,同时该加解密对接入方完全透明。

2、上述组件可灵活组装以适应项目需要,但是运维策略和工具也需要同步提供,例如:

(1)生产环境的所有主机需禁止root权限;

(2)生产环境的主机如果不需要对外提供服务,则只分配内网地址;

(3)生产环境主机的只打开应用对外提供服务的端口,不需要打开的端口应全部禁掉;

(4)每个主机都需要配备自动化监控脚本,以完成服务存活监控、重启,开机自启动等动作,另外在服务异常重启时需要能发送高级邮件、短信、钉钉消息等。

        设备所连接服务的地址应通过一个统一的接入地址(URL)动态获取,获取的策略有多种,例如:设备加电启动时获取或者固定时间之后必须重新获取等,可依据项目情况来定,而不应该固定配置到设备端。

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值