边缘计算开源项目解读--kubeedge事件总线

​0 背景

        本文继续解读kubeedge项目中的eventbus(事件总线)模块,这个模块与上一节介绍的devicetwin(设备孪生)相关联。主要通过mqtt协议与终端设备进行通信,将devicetwin模块的期望状态发布给终端设备,并订阅来自终端设备的实际状态,上送给devicetwin模块。这个模块虽然不及设备孪生模块在边缘计算模块核心,但是却是打通终端设备和边缘设备通信的重要模块。下面笔者将从这个模块的架构、与上下文模块的交互和内部核心流程三个角度,分解这个模块,帮助读者理清其中的代码逻辑和业务流程。

1 事件总线的架构

        如下图所示是事件总线模块的文件夹目录和各层模块之间的映射关系。从事件总线的字面意思也可以推断出这个模块主要是用来处理一些通信事件的,并不对数据进行实际的处理。在其内部的架构上也是围绕着通信协议mqtt协议展开,边缘设备和终端设备之间的数据交互都是基于该协议进行。关于mqtt协议的工作原理,笔者在专题《万物互联之通信协议篇》【1】有11篇详尽的介绍,感兴趣的读者可以自行阅读。此处kubeedge边缘开源项目推荐使用mosquitto开源项目中mqtt broker作为服务端,事件总线作为边缘侧的客户端实现,负责订阅/发布主题到broker上,读者也可以根据自己的项目选择其他broker。

        上图中左边是事件总线模块的4个文件夹和一个文件。其中eventbus文件是模块的主入口,控制着整个模块的处理流程,主要实现了设备状态的发布/订阅,对其相关主题进行注册、分发和处理。mqtt文件夹是核心的协议处理模块,主要实现了mqtt客户端和服务端的相关配置、与broker的连接和通信、对mqtt报文的解析处理;需要注意的是其中的服务端是kubeedge内部实现的broker,如果没有使用外部的开源broker,也可以直接使用该组件。dao文件夹则是对数据库的操作,该数据库表中只包含了订阅主题表项,发布的主题并没有存储在其中,因为发布的主题是从devicetwin模块发布的消息中解读出来的,直接发送给broker了,而订阅的主题需要从broker中得到后,缓存到数据库中,然后再根据订阅主题的来源是devicetwin还是云端来分发。最后的config和common文件夹则分别定义了模块的信息,实现了与broker的链接,是整个模块通信的基础。

        综上所述,eventbus模块的架构如图右边所示,模块工作起来首先要同broker进行建链,链接建立后,才可以同broker进行通信,通信的方式是采用发布/订阅结构。通信的有效载荷来自上下相关的两个模块,过程将在第2节中详细介绍。

2 事件总线的上下文

        如下图所示是kubeedge设备孪生这条主线中事件总线模块所处的位置和主要的功能。从图中可以很明显的看出,发到事件总线的数据或者事件总线分发的数据其来源有两个,要么来自/去向edge,要么来自/去向cloud。也就是说这个模块让数据可以就近在边缘设备上处理,或者上送到云端处理,至于卸载到哪一层上,则是由终端用户决定,模块本身并不参与这一决策,只是提供了这两条上送的通道。这种设计方式也符合kubeedge边云协同的定位,当前它只负责打通通路,应用程序员可以自行设计卸载的算法,决定卸载到哪一层,保障了这一架构的通用性。但这也带来了一个缺点,没有提供可以在边缘侧运行的智能算法或者计算框架的API接口,相比于其他的开源项目,在开发上需要程序员具备更高的能力和素质。

        如上图所示,事件总线模块有北向和南向两个交互方向,北向与devicetwin和edgehub通信,南向通过broker与终端设备的mapper通信。在此处我们分为下行方向和上行方向两个数据方向,分析各个模块之间的关系。

        场景1:下行方向发布期望状态到终端

        当用户想要调整设备的状态时,从云端界面配置设备的期望状态,下发更新给边缘侧的devicetwin(设备孪生),设备孪生模块将期望状态进一步封装成消息发送到事件总线模块,由事件总线模块将其封装成mqtt消息报文的格式(该格式包含了发布主题和有效载荷,有效载荷部分采用json编码)。接下来消息报文被发送到broker上,如果某个设备订阅了该主题消息,就可以从broker上获得该期望状态,在mapper上转换成设备通信的消息格式,最终发送给设备,设备根据该期望状态调整实际状态。这个流程相比于直接通过云控制终端设备,似乎变长了,但是如果从设备维护的视角看,下行方向对于时间的要求并没有那么高,相反对于稳定性的要求更高。在该框架下,即使边缘侧与云端暂时脱管了,边缘侧仍然可以独立地管理终端设备,边缘侧和云端可以互为主备,保障对终端设备的管理。

        场景2:上行方向订阅实际状态分发到云端或者边缘端

        当设备的实际状态发生变化时,可以通过终端与边缘连接的协议(如wifi/ble/mobus)等将状态发送给边缘侧,边缘侧的mapper模块将协议统一转换成mqtt报文格式,发布给broker。事件总线模块订阅了该设备的主题后,就会接收到设备的状态,然后由该模块过滤主题的上送方向,是上送到devicetwin还是通过edgehub上送到云端,这个卸载的方向是由终端指定的,最终设备的实际状态会被保存到边缘侧或者云端。这个流程实现了上行的数据的就近处理方式,可以放到边缘设备处理数据,对于实时性要求较高的应用,可以减少上送到云端所带来的网络时延。

3 事件总线的内部核心流程

​        事件总线内部实现的核心功能就是主题的发布和订阅。发布实现流程如下图所示,eventbus首先会与mqtt broker建立链接,建链需要的信息包括服务端的URL,标识客户端身份的ID,用户名和密码,链接建立后才可以收发主题消息。如果过程中出现断链,会反复链接,直到链接建立。发布主题时,设备的期望状态会被封装成mqtt消息,broker收到消息后,会发布确认主题的消息给到eventbus,确定主题已经发布给服务端。

​         订阅主题的过程略微复杂一些,同样需要首先建立链接,不过订阅的主题需要在eventbus进行分发,因此需要注册每个订阅主题的处理接口。当mqtt broker发送消息过来时,eventbus会过滤消息报文,并将主题插入到主题数据库中缓存,然后根据前面注册的主题处理接口,对消息进行处理,对应的消息会被转换成边缘侧内部通信的消息格式,最后再根据主题的策略分发到对应的模块。在此处采用了常见的注册/分发结构,可以很方便地实现mqtt协议和边缘侧消息之间的格式转换的分离,减少模块之间的耦合度。另外订阅的主题主要是设备的真实状态信息,当不需要再关注某个设备的状态时,就可以在事件总线模块中取消对该主题的订阅。这套订阅/发布的架构非常适合对终端设备的灵活管理。

4 小结

        本文详尽介绍了事件总线的代码架构,与其他模块的交互流程和内部实现发布订阅主题的过程。可以说这个模块功能比较单一,没有复杂的逻辑处理流程,但是却打通了终端和核心的设备孪生模块的通信,实现了数据的转换,最重要的是支持终端决策将数据卸载到哪一层上,而支持这种卸载能力是边缘计算网关的核心。后续笔者将继续解读设备孪生这条主线上的mapper模块,敬请期待。

参考文献

【1】(1条消息) 万物互联之通信协议篇_linus_ben的博客-CSDN博客​

猜你喜欢

转载自blog.csdn.net/linus_ben/article/details/127333571