分布式物联网边缘计算服务设计与实现

1 引言

1.1 课题的研究背景和意义

到2020年,全球联网的设备已超过200亿台,随着IPv6主干网建设和5G移动网络的部署,将有更多的物联网设备之间连接到互联网。云端需要处理越来越多的边缘端设备数据,同时边缘端设备的安全性也面临着不小的挑战。

无人驾驶汽车的传感器和摄像头,实时捕捉路况信息,每秒大约会产生1GB的数据,如果无人驾驶判断依赖于云服务,不能保证服务的随时可用性和稳定性,而且还会给服务器造成不少的带宽压力。所以无人驾驶汽车这类产品需要能自身进行计算而不依赖于互联网。再以智能家居为例,越来越多的家庭设备依赖于云计算平台来进行控制,一旦网络出现故障,即使家里仍然有电,设备也不能很好的控制了。现在市场上几乎所有的智能音箱产品,只要脱离了互联网运行,就是电子废品,不管问什么问题,甚至是问个时间,都只会回答“请先连接到网络”。

边缘计算架构是将每个边缘节点设备赋予自主计算能力,简单来讲就是在边缘物联网传感器网络中加入一个高级网关,这个网关负责对传感器数据分析或存储,将部分信息、结果信息或报警信息上报到云服务。比如道路上的摄像头,边缘网关节点通过机器学习训练好的识别模型对摄像头画面进行汽车违规分析,假如识别到了违规情况和违规的车牌号,网关则会将这条违规信息上报到服务器。

本课题将云端的分布式服务架构整合到边缘计算架构中,并引入DevOps开发模型。将云端技术应用到边缘物联网设备中。同时能在边缘端支持横向拓展、应用隔离、服务发现、负载均衡、滚动升级。

1.2 国内外研究现状

1.2.1 国内研究现状

KubeEdge是华为在2018年开源的面向边缘环境容器管理平台,KubeEdge能够接入云端Kubernetes集群,使得边缘应用的管理可以跟云端应用的管理一样,采用Kubernetes API。KubeEdge是一个开源系统,将本机容器化应用程序业务流程和设备管理扩展到边缘的主机。它基于 Kubernetes 构建,为云和边缘之间的网络、应用程序部署和元数据同步提供核心基础设施支持。它还支持 MQTT,并允许开发人员在 Edge 上编写自定义逻辑并启用资源受限的设备通信。

KubeEdge架构

KubeEdge分为云端节点和边缘节点,云端节点依赖于Kubernetes集群,云端节点实现了一套Kubernetes API,将边缘节点与Kubernetes集群整合到一起管理。目前KubuEdge还处于初级开发版本,很多Kubernetes的基本组件还不支持(如:Persistent Volume、Ingress、Secret),这也给集群管理产生了很多麻烦。

1.2.2 国外研究现状

K3S是Rancher出品的一个开源、简化、轻量Kubernetes,为物联网和边缘计算建立分布式的Kubernetes。支持ARM64和ARMv7架构,从很小的树莓派到AWS的a1.4xlarge 32GiB服务器都能运行。K3S只有一个不到40MB的可执行二进制文件,并且内置了容器引擎而不需要额外安装Docker,减少了安装、运行和更新Kubernetes集群所需的依赖性和步骤。

K3S架构

K3S移除了所有Beta版的API,与Kubernetes架构基本差别不大。master节点用了更轻便的SQLite代替了k8s的etcd数据库,边缘节点使用了内置的容器引擎来代替Docker CE引擎。还可以使用Flannel网络组件打通集群Pod之间的网络通讯。K3S除了可以在物联网边缘计算场景中使用,还可以在ARM服务器集群中运行分布式应用。

1.3 本课题的研究内容及章节安排

1.3.1 课题研究的内容

通过查阅大量现有的边缘计算资料和书籍,结合多年来对云计算技术的学习和了解以及分析现有分布式边缘计算架构的特点和缺陷,通过云端K8S集群+边缘端K3S+边缘服务发现+DevOps自动化部署,实现了一套易管理、易扩展、易部署的分布式物联网边缘计算架构。

首先将分布式物联网边缘计算架构分为云-边-端三层。云端包括完整的Kubernetes集群、Azure DevOps Agent服务、Rancher集群管理服务、NFS服务、K3S Server。边缘端作为物联网边缘网关运行K3S Agent,边缘端与云端共享Config Map、Secert、Persistent Volume,并集成DDNS以更好的支持IPv6网络访问,集成frpc以穿透IPv4 NAT网络进行直接访问。设备端可以通过端口扫描、UDP广播、DNS等方式扫描局域网内的边缘节点,当前网络如果不存在边缘节点,设备端也可以直接连接到云端工作。

NFS服务器作为Kubernetes的一个Persistent Volume用来保存跨集群节点使用的持久化数据(如:配置文件、用户上传的文件等),Rancher集群管理服务可以同时管理云端的Kubernetes集群和边缘端的k3s集群,同时给Azure DevOps提供应用部署接口API。DDNS服务通过阿里云DNS解析API将所有边缘节点的IPv4和IPv6地址解析在域名<边缘节点主机名>.zuozishi.online上。frpc服务将边缘节点需要远程访问和管理的端口通过frp服务穿透到公网服务器,这样就能突破IPv4 NAT网络直接访问到边缘节点,这是一种IPv4到IPv6的过渡解决方案。

所有的云端、边缘端、设备端代码托管在Github和Azure DevOps Repos平台上,当本地代码推送到在线仓库时,触发Azure Pipelines自动化编译、测试、部署事件,将应用镜像推送到阿里云镜像库,通过应用部署配置文件将应用部署到云端、边缘端或设备端。云端、边缘端或设备端会根据配置文件从阿里云镜像库拉取镜像并运行。

云端、边缘端示例应用为网络音乐播放服务。网络音乐播放服务使用ASP .Net Core 3.1框架,实现用户使用酷狗账号登录、用户播放列表、音乐搜索、获取音乐歌词和URL等API接口,提供一个简单的Web访问界面,通过SignalR协议与设备端连接并通信。 设备端通过UDP广播包查询本地边缘节点,然后使用SignalR协议连接,实时报告音乐播放情况并接收控制指令。手机APP也在这个应用场景中作为设备端,一样通过UDP广播包查询本地边缘节点然后连接并通信。如果本地不存在边缘节点,音乐播放设备和手机APP将直接连到云端部署的应用进行工作。

1.3.2 论文章节安排

本文章节安排如下:

第一章、引言。介绍分布式边缘计算的背景和意义,介绍国内外分布式边缘计算架构的发展和研究现状,介绍论文的主要研究内容和章节安排。

第二章、分布式边缘计算相关技术。介绍边缘计算和分布式的概念和特点,介绍虚拟化和容器技术的发展。

第三章、云端架构的分析与设计。介绍分布式物联网边缘计算架构中服务端服务器的规划和重要服务的部署。

第四章、边缘端架构的分析与设计。介绍分布式物联网边缘计算架构中边缘端的配置规划和重要服务。

1.4 本章小结

本章先介绍了分布式边缘计算的研究背景和意义,介绍了分布式边缘计算架构发展中存在的些许问题,肯定了研究的意义。本章还对论文研究内容进行了介绍,并对系统的总体设计思路进行了描述。 最后,还对论文的整体章节进行安排。

2 分布式边缘计算相关技术

2.1 边缘计算的概念和特点

边缘计算采用一种分散式运算的架构,将之前由网络中心节点处理的应用程序、数据资料与服务的运算交由网络逻辑上的边缘节点处理。边缘计算将大型服务进行分解,切割成更小和更容易管理的部分,把原本完全由中心节点处理的大型服务分散到边缘节点。而边缘节点更接近用户终端装置,这一特点显著提高了数据处理速度与传送速度,进一步降低时延。

边缘计算作为云计算模型的扩展和延伸,直面目前集中式云计算模型的发展短板,具有缓解网络带宽压力、增强服务响应能力、保护隐私数据等特征。在智慧城市、智能制造、智能交通、智能家居、智能零售以及视频监控系统等领域,边缘计算都在扮演着先进的改革者形象,推动传统的“云到端”演进为“云-边-端”的新型计算架构。

边缘计算架构

2.2 虚拟化和容器技术

虚拟化是云计算的重要技术,可以将物理资源弹性地分配给客户。主机虚拟化的思想可以追溯到 IBM 机器的逻辑分区,即把一台 IBM 机器划分成若干台逻辑的服务器,每台逻辑服务器拥有独占的计算资源(CPU、内存、硬盘、网卡),可以单独安装和运行操作系统。IBM 机器价格昂贵,相对于当时的计算任务来说,机器的计算能力太过强大,所以需要划分为更小的计算单元。

后来随着个人计算机处理能力的不断发展,1998 年 VMware 公司成立,这家公司专注于机器虚拟化的软件解决方案。也就是说,对于不支持逻辑分区的计算机,可以直接通过安装 VMware 虚拟化软件来模拟更多的虚拟机,然后再在这些虚拟机里安装操作系统和应用软件,可以给虚拟机灵活配置内存、CPU、硬盘和网卡等资源。

虚拟化技术

但是在每台虚拟机里都要安装和运行操作系统的做法,仍然浪费了很多计算资源。为此,有公司专门推出了应用软件容器产品,即在操作系统层上创建一个个容器,这些容器共享下层的操作系统内核和硬件资源,但是每个容器可单独限制 CPU、内存、硬盘和网络带宽容量,并且拥有单独的 IP 地址和操作系统管理员账户,可以关闭和重启。与虚拟机最大的不同是,容器里不用再安装操作系统,因此浪费的计算资源也就大大减少了,这样同样一台计算机就可以服务于更多的租户。

容器技术

2.3 分布式架构和Kubernetes

分布式系统是一个硬件或软件组件分布在不同的网络计算机上,彼此之间仅仅通过消息传递进行通信和协调的系统。

在3G移动网络发展初期,随着上网人数的飙升和人均上网带宽增加,单服务器应用已经不能满足需求,云计算开始发展,企业也开始将一个应用的不同组件放在多个服务器上来均衡流量和提高可用性。例如像淘宝这类的网站,要解决的重点问题就是海量商品搜索、下单、支付等问题; 像腾讯这类的网站,要解决的是数亿级别用户的实时消息传输;而像百度这类的公司所要解决的又是海量数据的搜索。每一个种类的业务都有自己不同的系统架构。

分布式架构应用

Kubernetes 是用于自动部署,扩展和管理容器化应用程序的开源系统。它将组成应用程序的容器组合成逻辑单元,以便于管理和服务发现。Kubernetes 源自Google 15 年生产环境的运维经验,同时凝聚了社区的最佳创意和实践。Google 每周运行数十亿个容器,Kubernetes 基于与之相同的原则来设计,能够在不扩张运维团队的情况下进行规模扩展。Kubernetes 是开源系统,可以自由地部署在企业内部,私有云、混合云或公有云。

Kubernetes是一个全新的的分布式架构领先方案,它基于容器技术,目的是实现资源管理的自动化,以及多个数据中心的资源利用率的最大化。通常,我们会把Kubernetes看作Docker的上层架构,就好像Java与J2EE的关系一样:J2EE是以Java为基础的企业级软件架构,Kubernetes则以Docker为基础打造了一个云计算时代的全新分布式系统架构。

Kubernetes并不是依赖于Docker,也可以支持其他的容器引擎,如:Rocket、lxd 、rkt。

3 云端架构的分析与设计

3.1 云端基础架构配置和规划

云端服务器使用了五台阿里云的ECS(Elastic Compute Service)学生免费版入门级服务器,详细配置如下:

  • CPU:2核

  • 内存:4GiB

  • 操作系统:CentOS 7.7 64位

  • 独立公网IP

  • 公网带宽:1Mbps

  • 系统盘:40GiB (2120 IOPS)

  • 地域:阿里云-华北2(北京)

注:由于个人能力,实验集群只在阿里云北京区域中搭建,如果跨不同地区搭建集群,则可以实现多地负载均衡,不过需要收取跨地区通信的流量费。

由于五台机器属于不同的阿里云账号下,所以这五台机器不属于一个局域网,需要先在阿里云平台配置跨账号的云企业网,配置云企业网的实质则是配置这五个机器内网网段的路由表,配置完成后则认为这五台机器通过这个路由表进行跨网段通信。

云企业网

云企业网-路由表

其中一台机器作为master节点,两台机器作为node工作节点,一台服务器用来部署NFS文件共享服务、Azure Pipelines Agent和Rancher集群管理服务,一台作为k3s的master节点。

主机名 内网IP 外网IP 角色
Zuozishi-Master 172.17.151.242 39.107.139.105 k8s master
Zuozishi-Slave1 172.17.57.231 39.97.161.176 k8s工作节点
Zuozishi-Slave2 172.17.77.128 47.93.236.68 k8s工作节点
Aliyun-YXM 172.17.196.228 39.97.114.49 k3s master、frps服务
Aliyun-TXR 172.17.81.0 47.94.90.203 NFS服务、集群管理者

考虑到外部连接集群和应用的安全性,尽量使用了HTTPS协议,所以先要为主机申请SSL证书,本项目使用在阿里云申请的一年有效期的免费SSL证书。

SSL证书申请

3.2 Kubernetes集群配置

graph TB
    subgraph 阿里云
    A[k8s主节点] --> B[k8s工作节点1]
    A[k8s主节点] --> C[k8s工作节点2]
    end

修改需要安装Kubernetes所有主机的Hosts

echo > /etc/hosts < EOF
::1 localhost
127.0.0.1 localhost
172.17.57.231   Zuozishi-Slave1
172.17.77.128   Zuozishi-Slave2
172.17.196.228  Zuozishi-Slave3
172.17.81.0     Aliyun-TXR      Zuozishi-NFS
172.17.151.242  Zuozishi-Master
172.17.151.242  Zuozishi-Master Zuozishi-Master
EOF

在master节点运行自己编写的一键配置/安装脚本,脚本大概过程如下:

  1. 关闭防火墙

  2. 配置软件安装源(yum)为阿里云镜像源

  3. 安装相关工具(wget、net-tools、sshpass)、docker-ce(容器运行引擎)、docker-ce-cli(容器引擎命令行管理工具)、kubelet(k8s核心)、kubeadm(k8s部署工具)、kubectl(k8s命令行管理工具)

  4. 下载Kubernetes所依赖的Docker镜像

  5. 配置Kubernetes容器内网络(安装weave网络插件)

  6. 安装kubernetes-dashboard(Web管理工具)

  7. 配置用于远程访问的SSL证书

工作节点配置与master前4个步骤相同,最后运行kubeadm join命令将该主机向master注册为工作节点即可。

3.3 K3S集群配置

graph TB
    subgraph 阿里云
    A[k3s主节点]
    end
    subgraph 边缘2
    A --> B[边缘网关]
    B --> 设备03
    B --> 设备04
    end
    subgraph 边缘1
    A --> C[边缘网关]
    C --> 设备01
    C --> 设备02
    end

k3s相比k8s的安装简单不少,只需要运行几句命令:

# master节点
curl -sfL https://get.k3s.io | sh -

# 安装Web管理工具
GITHUB_URL=https://github.com/kubernetes/dashboard/releases
VERSION_KUBE_DASHBOARD=$(curl -w '%{url_effective}' -I -L -s -S ${GITHUB_URL}/latest -o /dev/null | sed -e 's|.*/||')
k3s kubectl create -f https://raw.githubusercontent.com/kubernetes/dashboard/${VERSION_KUBE_DASHBOARD}/aio/deploy/recommended.yaml

# 编译节点
export K3S_URL=39.97.114.49
export K3S_TOKEN=<密钥>
curl -sfL https://get.k3s.io | sh -

3.4 NFS服务器配置

NFS 即网络文件系统(Network File System),可以通过网络让不同机器、不同系统之间可以实现文件共享。在该项目中,NFS服务负责保存集群应用中所需的配置文件和一致性文件(即在集群环境中,多台机器访问同一份文件)。通过Kubernets的Persistent Volume(持久卷),将NFS挂载到容器内,多个容器就能访问到同一份文件。

graph TB
    subgraph 阿里云
    A[k8s主节点] --> B[k8s工作节点1]
    A[k8s主节点] --> C[k8s工作节点2]
    D[NFS服务器]
    D -- 配置文件 --> B
    D -- 配置文件 --> C
    end

NFS服务器配置如下:

  1. 安装 NFS 软件包yum install -y nfs-common nfs-utils rpcbind

  2. 添加 NFS 共享目录

    将/nfsroot目录设置为NFS共享目录,设置改目录的权限为最宽松的权限chmod 777 /nfsroot

  3. 启动NFS服务/etc/init.d/nfs-kernel-server start

3.5 多集群管理服务配置

多集群管理服务Rancher可以在一个Web应用中管理多个k8s或k3s集群,并通过提供的API接口来通过微软云DevOps远程管理集群和部署应用。

graph TB
    subgraph 阿里云
    A[Rancher] --> B[k8s主节点]
    A --> C[k3s主节点]
    end

本项目的Rancher服务安装在独立于k8s集群的服务器中,运行在Docker容器中,使用devops.zuozishi.info域名的HTTPS证书,暴露6443端口访问。安装命令如下:

docker run -d --restart=unless-stopped \
  -p 6443:443 \
  -v <FULL_CHAIN.pem>:/etc/rancher/ssl/cert.pem \
  -v <PRIVATE_KEY.pem>:/etc/rancher/ssl/key.pem \
  -v <CA_CERTS.pem>:/etc/rancher/ssl/cacerts.pem \
  rancher/rancher:latest

由于域名未经备案,80端口和443端口无法使用。

安装完成后通过地址https://devops.zuozishi.info:6443访问管理页面,设置初始密码。然后将k8s和k3s集群加入到管理中心。最后再新建一个远程访问API的密钥,用于远程部署应用。

3.6 Azure DevOps Agent配置

在云端架构中,采用了混合云模式。基础服务和应用运行在阿里云ECS中,可执行文件以容器的方式保存在阿里云容器镜像服务中。而代码和自动化测试编译由微软云DevOps负责。在测试编译环节中,代码需要编译成多架构版本的(包括x86_64和arm、arm64)可执行文件,同时满足在云端环境(x64)和边缘环境(arm或arm64)运行。所以当代码push到仓库时,Azure DevOps会分别在x64和arm架构服务器中编译代码,这里负责编译代码的服务器就称之为Azure DevOps Agent。Azure DevOps中会给账号分配一个免费的agent(x64架构),因为应用要在编译节点树莓派(arm架构)中运行,需要配置一台arm架构的agent服务器负责编译代码生成arm架构的可执行程序。值得一提的是,在2020年前后,arm在服务器市场越来越有优势。

graph TB
    A([开发者推送代码]) --> B
    subgraph Azure DevOps
    B[(代码仓库)]
    B --> C
    B --> D
    B --> E
    subgraph 编译
    C[x86_64 Agent]
    D[ARM Agent]
    E[ARM64 Agent]
    end
    end
    subgraph 阿里云
    G[(阿里云容器镜像库)]
    C -- x86_64架构应用镜像 --> G
    D -- ARM架构应用镜像 --> G
    E -- ARM64架构应用镜像 --> G
    end

由于个人能力有限,本项目使用树莓派作为agent服务器。

Azure DevOps Agent服务配置过程如下:

  1. 登录Azure DevOps平台

  2. 在个人中心页面中创建一个API Key用于agent用户认证

  3. 下载arm版本的agent服务程序

  4. 运行./config.sh,配置API Key

  5. 运行agent服务

配置Agent

4 边缘端架构的分析与设计

4.1 边缘端基础架构配置和规划

边缘端包括边缘网关和设备,边缘网关主要负责连接设备并接收和处理设备发送的数据。边缘网关作为k3s工作节点,可以通过k3s主节点进行管理,边缘应用通过k3s主节点进行下发,以容器方式运行在边缘网关,应用下发后,即使边缘网关失去了对主节点的连接,也不会影响现有应用的运行,但是无法及时对应用进行更新。

graph TD
    subgraph 阿里云
    A[k3s主节点]
    end
    subgraph 边缘
    A -.下发应用.-> D[边缘网关]
    E[设备1] --> D
    F[设备2] --> D
    end

在本项目中,使用树莓派4B作为边缘网关,使用iTop-4413 ARM9开发板作为设备。

树莓派4B的主要参数如下:

  • SOC:Boradcom BCM2711

  • CPU:64位 1.5GHz 四核(28nm工艺)

  • 内存:4GB LPDDR4

  • GPU:Boradcom VideoCore VI @ 500MHz

  • 供电接口:Type-C(5V 3A)

  • WiFi网络:802.11AC 无线 2.4GHz/5GHz 双频

  • 有线网络:真千兆以太网

  • 操作系统:Raspbian Buster with desktop(32位系统)

iTop-4412开发板主要参数如下:

  • CPU:Exynos4412,四核Cortex-A9,主频为1.4GHz-1.6GHz

  • 内存:2GB 双通道 DDR3

  • 供电接口:5V/2A

  • 有线网络:10M/100M自适应网口

  • I/O接口:耳机输出、MIC输入、2路串口、1路A/D、摄像头接口、WiFi接口、HDMI输出、2路USB Host、1路USB OTG、GPIO(20PIN)、LCD接口(2个LVDS接口、1个RGB接口)、MIPI接口、GPS接口、JTAG接口

  • 操作系统:Android 4.4(API Level 19)

4.2 Aliyun-DDNS服务设计

Aliyun-DDNS负责把边缘网关的外部IPv4和IPv6地址通过阿里云DNS解析服务解析到域名<边缘网关主机名>.zuozishi.online,如果边缘网关使用公网IP或支持IPv6网络,则可以通过解析的域名直接能远程访问到边缘网关,方便管理。

主要代码如下:

# python3
if checkRecord('A'):
    print("删除域名中已有的IPv4解析数据")
    delRecord('A')

if checkRecord('AAAA'):
    print("删除域名中已有的IPv6解析数据")
    delRecord('AAAA')

ip = getIp4Addres()
print("公网IPv4地址:" + ip)
recid = addRecord(ip, 'A')
print("已向域名添加解析记录,ID:" + recid)

ipv6 = getIp6Addres()
print("公网IPv6地址:" + ipv6)
recid = addRecord(ipv6, 'AAAA')
print("已向域名添加解析记录,ID:" + recid)

4.3 frp服务设计

frps服务主要针对于IPv4的NAT网络和非IPv6网络环境中,是对边缘网关进行远程访问的一种额外手段,通过端口转发方式,将处于内网的边缘网关通过frp服务将边缘网关的某个端口映射到具有公网IP主机的某个端口上。

sequenceDiagram
    内网主机->>公网主机: 通过7000端口连接到frps服务
    Note over 内网主机,公网主机: frp服务生命周期内保持连接
    内网主机->>公网主机: 注册配置文件
    Note over 内网主机,公网主机: frps和frpc端口映射关系
    客户端->>公网主机: 通过8080端口访问
    公网主机->>内网主机: 通过7000端口长连接请求8080端口数据
    内网主机->>公网主机: 网页数据
    公网主机->>客户端: 网页数据

frps:指frp server(frp服务端,公网主机)
frpc:指frp client(frp客户端,内网主机)

4.4 服务发现

边缘物联网设备通过服务发现来找到局域网中可以连接的边缘网关,服务发现使用简单服务发现协议(SSDP,Simple Service Discovery Protocol)实现。边缘网关通过SSDP协议在网络中注册为UPnP边缘网关设备,通过Kubernetes API(边缘网关为k3s,但是API是兼容的)将可用的边缘应用作为UPnP属性。物联网设备端扫描网络中可用的UPnP设备,通过UPnP设备属性判断局域网中有没有可用的边缘网关,然后通过SSDP协议中的xml链接获取UPnP设备描述文件,设备描述文件包括边缘网关中运行的服务和服务端口号,然后设备端进行连接。

简单服务发现协议(SSDP)是一种应用层协议,是构成通用即插即用(UPnP)技术的核心协议之一。简单服务发现协议提供了在局部网络里面发现设备的机制。

sequenceDiagram
    边缘设备->>边缘网关: 发送M-SEARCH UDP广播
    边缘网关->>边缘设备: 响应搜索请求
    边缘设备->>边缘网关: 获取UPnP设备描述文件
    边缘网关->>边缘设备: 响应设备信息和服务信息
    边缘设备->>边缘网关: 通过服务端口连接服务

5. 应用的设计与实现

5.1 音乐播放服务

5.1.1 概述

音乐播放服务运行在边缘端,提供用户登录、实时控制、播放列表、网络资源搜索等功能。基于ASP Net Core框架,使用Visual Studio IDE进行开发,开发语言:C#。

.NET Core是一个能在Windows、Linux、macOS平台上运行Web服务和命令行应用的跨平台的.NET框架。

音乐播放服务主要使用了ASP Net Core的三大模块:API Controller、Razor Pages、SignalR Hub。

  • API Controller: 提供音乐搜索、用户登录、播放列表等RESTful API
  • Razor Pages: 提供网页页面、渲染页面
  • SignalR Hub: 提供播放器和播放控制端的实时通信通道(实现实时控制和日志上报)

5.1.2 API设计

API使用HTTP协议,采用JSON数据交换格式。API分为登录、在线资源、播放列表大三类别,服务使用酷狗用户认证。

  1. 登录相关:

    • POST http(s)://hostname/api/login/update
      更新用户Cookie

    • GET http(s)://hostname/api/login/check
      检测用户Cookie是否有效

  2. 在线资源相关:

    • GET http(s)://hostname/api/presearch/{keyword}
      获取预搜索结果,keyword-关键词
    • GET http(s)://hostname/api/search/{keyword}
      获取预搜索结果,keyword-关键词
    • GET http(s)://hostname/api/search/{keyword}/source
      搜索并返回第一个播放源(用于语音搜索),keyword-关键词
    • GET http(s)://hostname/api/song/{hash}
      获取歌曲信息,hash-歌曲哈希值
    • GET http(s)://hostname/api/song/{hash}/source
      获取歌曲播放源,hash-歌曲哈希值
    • GET http(s)://hostname/api/mv/{hash}
      获取MV信息,hash-MV哈希值
    • GET http(s)://hostname/api/mv/{hash}/source
      获取MV播放源,hash-MV哈希值
    • GET http(s)://hostname/api/lrc/{keyword}/{duration}
      获取歌词,hash-歌曲哈希值,duration-歌曲总时长
  3. 播放列表相关:

    • GET http(s)://hostname/api/playlist/isfav/{mid}
      判断是否是喜欢的音乐,mid-音乐ID
    • GET http(s)://hostname/api/playlist/fav
      获取喜欢的音乐列表
    • POST http(s)://hostname/api/playlist/fav
      将歌曲添加到喜欢的音乐
    • DELETE http(s)://hostname/api/playlist/fav/{mid}
      将歌曲从喜欢的音乐列表中移除,mid-音乐ID
    • GET http(s)://hostname/api/playlist/all
      获取全部播放列表
    • POST http(s)://hostname/api/playlist/song/{id}
      将歌曲添加到播放列表,title-播放列表id
    • DELETE http(s)://hostname/api/playlist/song/{id}/{mid}
      将歌曲从播放乐列表中移除,id-播放列表ID,mid-音乐ID
    • GET http(s)://hostname/api/playlist/isin/{id}/{mid}
      判断音乐是否在播放列表中,id-播放列表ID,mid-音乐ID

5.1.3 SignalR消息定义

ASP.NET Core SignalR是一种开放源代码库,可简化将实时 web 功能添加到应用程序的功能。 实时 web 功能使服务器端代码可以立即将内容推送到客户端。SignalR会自动选择服务器和客户端功能内的最佳传输方法,包括:WebSocket、服务器发送的事件、长轮询。

SignalR使用“中心”在客户端和服务器之间进行通信。“中心”是一种高级管道,它允许客户端和服务器分别调用方法。 SignalR自动处理跨计算机边界的调度,使客户端能够在服务器上调用方法,反之亦然。 可以将强类型参数传递给方法,从而启用模型绑定。 SignalR提供了两个内置的集线器协议:基于 JSON 的文本协议和基于MessagePack的二进制协议。 与 JSON 相比,MessagePack 通常会创建较小的消息。

音乐播放服务的SignalR“中心”接口定义如下表:

函数名 参数 功能
WriteLog 日志类别, 消息 上报日志
RegisterPlayer 播放器ID 注册为播放器
RegisterClient 客户端ID,客户端群组ID 注册为客户端
PropertyChanged JSON数据 播放器数据变动
RequireData 无 请求播放器重发数据
PlayListChanged 播放列表ID 播放列表变动
EnumPlayers 无 枚举播放器
EnumPlayersCallback 播放器ID 枚举播放器回调
SearchAndPlay 关键词 搜索并播放
MediaCtrl 类别,数据 媒体控制

无论任何语言和任何平台,只要播放端和控制端满足上述接口定义,就能实现远程音乐播放器控制。

5.1.4 网页页面设计

服务提供两个页面,主页和API文档。主页可以对连接到服务的播放器进行控制,支持歌词/进度显示、搜索并播放、播放列表控制、上一曲、下一曲、播放/暂停、音量控制。服务端使用使用Razor渲染页面,页面使用bootstrap作为UI框架,使用VUE.js进行数据绑定,使用SignalR Client库与SignalR“中心”连接。API文档由Swagger自动从代码生成API文档页面。

5.1.5 容器化服务

使用Docker和Dockerfile文件将程序编译,并打包成镜像。Dockerfile打包过程如下:

  1. 使用dotnet/core/aspnet:3.0-buster-slim作为基准镜像
  2. 使用dotnet/core/sdk:3.0-buster作为编译环境镜像
  3. 设定工作目录为/app
  4. 拷贝代码到容器中
  5. 下载程序所依赖的第三方库
  6. 编译
  7. 将基准镜像作为最终运行镜像
  8. 保留服务端口:81
  9. 复制编译后的dll到当前文件夹
  10. 设置容器入口命令:dotnet MusicCloud.dll

5.1.6 Kubernetes服务定义

项目中的kubernetes.k8s.yaml文件定义了音乐播放服务在Kubernets集群中的注册信息。kubernetes.k3s.yaml文件定义了音乐播放服务在k3s集群中的注册信息。
在k8s集群中,使用Deployment调度3个容器运行服务,将NFS PVC映射到容器中/nfs-pvc路径,使用阿里云镜像密钥从阿里云镜像库拉取镜像,注册一个服务,将宿主机的30005端口映射到容器的81端口。
在k3s集群中,使用DaemonSet在每个编译节点都调度一个音乐播放服务,使用阿里云镜像密钥从阿里云镜像库拉取镜像,注册一个服务,将宿主机的30005端口映射到容器的81端口。

5.1.7 自动化编译/部署

项目中的azure-pipelines.yml文件定义了项目代码提交到远程代码库时,触发Azure Pielines运行时所需要执行的编译/部署步骤。

  1. 编译镜像
  2. 将镜像推送到阿里云容器镜像库
  3. 配置Kubernetes应用部署文件
  4. 上传应用部署文件
  5. 部署应用

5.2 音乐播放器和音乐控制端

5.2.1 概述

音乐播放器和音乐控制端基于谷歌Flutter框架,使用Dart语言,以Visual Studio Code作为IDE进行开发。音乐播放器运行在Android 4.4系统的ARM开发板上,可以连接外设,音乐控制端支持Android和iOS。

Flutter是谷歌的移动UI框架,可以快速在iOS和Android上构建高质量的原生用户界面。

音乐播放器和音乐控制端都通过简单服务发现协议(SSDP)搜索局域网中可以连接的边缘网关,连接到音乐播放服务的SignalR“中心”,分别注册为播放器和客户端。播放器接收客户端的控制指令,并上报音乐播放状态和播放列表。控制端向播放端发送控制指令,并接收音乐播放状态和播放列表。


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 wwb123123@outlook.com

文章标题:分布式物联网边缘计算服务设计与实现

本文作者:Zuozishi

发布时间:2020-05-22, 05:37:37

最后更新:2020-05-22, 05:39:26

原始链接:https://zuozishi.github.io/2020/05/22/ProjectEdge/%E5%88%86%E5%B8%83%E5%BC%8F%E7%89%A9%E8%81%94%E7%BD%91%E8%BE%B9%E7%BC%98%E8%AE%A1%E7%AE%97%E6%9C%8D%E5%8A%A1%E8%AE%BE%E8%AE%A1%E4%B8%8E%E5%AE%9E%E7%8E%B0/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录