1、背景
传输协议作为“终端”与“算力”的连接通道,其稳定性及传输效率决定了终端算力应用的用户体验,是产品向用户提供“一点接入、即取即用”算力服务的核心关键与重要保障。
行业内主流的云终端传输协议的应用主要集中在VMWare的PCoIP协议、Citrix的ICA协议、Microsoft的RDP协议和RedHat的SPICE协议。其中SPICE协议是唯一完全开源的协议,多数云电脑厂商在开发产品时大都会参考SPICE协议的架构进行传输协议的开发。SaaS产品部算力服务产品组为了实现云电脑关键技术自主掌控,基于SPICE协议,同时借鉴前沿的WebRTC、QUIC等协议,从带内协议改造、编解码优化、广域网传输、虚拟显示方案、USB重定向、SDK优化等6方面探索云终端传输协议的产品化思路。
2、SPICE协议原理详解
2.1 整体架构
SPICE协议从结构上可以分为四个组成部分:
- 虚拟机侧(guest):部署在服务器侧、提供虚拟桌面服务的虚拟机中,用于接收操作系统和应用程序的图形命令,如虚拟图形适配器(QXL driver)以及代理(VDI Agent);
- 服务端侧(spice server):以libspice动态库形式供虚拟机监控管理程序(qemu)使用;
- 客户端侧(spice client):终端用户交互操作远程虚拟机的程序(remote-viewer或者spice-gtk);
- 协议部分(spice protocol):定义了SPICE各个组件之间通信的消息和规则。
各部分之间的关系如图所示:
图2.1 SPICE协议相关组件之间的关系
SPICE协议整体架构,如下图所示。客户端运行在用户终端设备上,为用户提供桌面环境。SPICE服务端以动态链接库的形式与KVM虚拟机整合,通过SPICE协议与客户端进行通信。
图2.2 SPICE协议架构
从架构图上可以看出,Client和Server通过channels进行通信,每个channel类型对应着特定的数据类型。每个channel使用专门的TCP socket,这个socket可以是安全的(使用SSL)或者不安全的。关于channel的细节将在后续章节讲解。
2.2 Server端原理详解
SPICE服务端是通过libspice实现的,libspice是一个虚拟设备接口(VDI)可插拔库。一方面,服务器使用SPICE协议与远程客户端通信;另一方面,SPICE协议与VDI主机应用程序(例如QEMU)进行交互。服务端架构图如图2.3所示,服务端通过各种通道与客户端进行通信,包括主通道、输入通道、回放通道、记录通道、显示通道和光标通道。每个通道传输不同类型的数据,例如主通道传输一些简单控制指令、输入通道传输鼠标键盘等消息、显示通道传输桌面显示相关数据等,并且每个通道使用一个专用的TCP套接字。
图2.3 服务端架构图
服务端与虚拟机之间的通信需要借助QEMU虚拟化出QXL接口和I/O接口。I/O接口包含代理接口、输入接口和音频接口(回放接口和记录接口),分别完成与主通道、输入通道、回放通道和记录接口的建立。QXL接口通过虚拟机中的QXL驱动完成图形设备接口的封装调用,方便对显示通道和光标通道进行操作。与I/O接口不同的是,QXL接口可以有多个,以便支持多屏显示等功能。
SPICE图形系统结构图如图2.4所示,Red Sever为每一个QXL接口发起调度请求,而Red Dispatcher会通过通道的套接字创建Red Worker。Red Dispatcher负责QXL的调度工作。当程序初始化、图像压缩更改、视频流变化、鼠标模式设置时,就会新建Red Worker进行具体的处理。Red Worker负责处理具体的QXL命令,需要对显示通道和光标通道进行管理,包括通信管道的维度、图像压缩、视频流创建和编码、缓存控制等。
图2.4 图形系统架构图
综合上述,SPICE服务端核心的三个组件分别为:
(1) Red Server (reds.c)
Red Server主要用来监听客户端连接请求,接受连接并与客户端通信,主要负责:
- 通道
管理通道(注册,注销,停止)
通知Client活动的通道,便于Client创建它们
主通道和输入通道的管理
socket操作以及链接管理
处理SSL和ticketing
- VDI接口处理(增加,移除)
- 处理用户命令
- 和Guest Agent通信
(2) Red Worker(red_worker.c)
SPICE服务端为每个QXL接口创建一个工作者线程(Red Worker),Red Worker主要负责:
- 处理QXL设备命令(draw, update, cursor等)
- 处理接受自Red分配器的消息
- 显示通道和光标通道管理
- 图像压缩(使用quic, lz, glz 编码)
- 视频流处理(鉴别视频流,创建流和编码)
(3) Red Dispatcher(red_dispatcher.c)
Red Dispatcher主要用于QXL的调度工作,主要负责:
- 为每个QXL实例一个调度器
- 创建和初始化Red Worker线程
- 执行QXL的调度工作
2.3 Guest端原理详解
在SPICE协议中,Guest端即是用户所使用的虚拟机,目前Guest端支持windows,linux等不同操作系统的虚拟化。Guest端由虚拟化的硬件构成,通过SPICE将内容远程传输至Client端供用户操作使用,Guest端的用户体验存在瓶颈,为此SPICE协议在Guest端中设计了Vdagent和qxl两个模块以增强用户的使用体验。
图2.5 guest框架图
(1)Vdagent
Vdagent是运行于Guest端中的应用程序,通过qemu创建的特定spicemvc设备与Server进行通讯。Vdagent既是Client端、Server端的指令执行器,也是Guest端的事件监听器。在基础的用户使用上,如键鼠同步、音画显示等功能皆可通过qemu提供的虚拟硬件接口进行实现,但由于Client端是以应用程序的形式运行在客户物理机中,使得Guest端和用户物理机间接产生了交互,因此Vdagent实现了以下四种功能以增强用户体验。
- Client端鼠标模式
基于qemu,spcie协议提供了一种Server端鼠标控制模式,该模式通过接收Client端的鼠标位移矢量对qemu虚拟鼠标进行相对位移控制。而Vdagent实现了一种Client端鼠标模式,该模式抛弃了qemu提供的虚拟鼠标接口,转而在Vdagent中通过Client端鼠标的相对位置信息移动Guest端鼠标。
相比而言,Vdagent的Client端鼠标模式可以适应更加复杂的网络传输环境,在丢包严重的网络状况下也可以保证整体的控制效果,减少鼠标拖影等情况的出现。
- 分辨率自适应
在用户看来,协议的Client端就是运行在用户物理机上的一个窗口程序,应是可以切换窗口大小的。若没有分辨率自适应功能,那么在窗口大小切换后,会导致Client端与Guest端分辨率不匹配,从而桌面画面出现放大、缩小,甚至显示不完全或黑边问题。因此,vdagent通过调用QXL调整Guest端分辨率以适应Client端窗口大小的方式避免分辨率匹配问题。
- 共享剪切板
若用户同时使用其本地的物理机和Guest端来进行工作学习,那么两台机器之间的文本共享就显得十分有必要。基于此Client端和Vdagent两端都实现了剪切板的监听与写入功能,当一方的本地剪切板更新时,另一方便会接收到该剪切板数据并更新其对应的剪切板,以此实现共享剪切板数据。
- 文件传输功能
同共享剪切板类似,两台机器之前的文件传输也同文本共享一样重要,用户物理机可直接选择文件并拖拽到Client端窗口以启动文件传输,而Vdagent则会将接收文件放在Guest端的指定路径下。
(2)QXL
广义上的QXL指显示模块,而狭义上的QXL则分为两部分,一部分是由qemu创建的QXL显卡设备,另一部分则是Guest端中对应QXL显卡的QXL驱动。Guest端的画面必须经过显卡绘制,而QXL显卡仅是qemu通过cpu虚拟而来,因此性能较差,在没有QXL驱动情况下,画面刷新存在明显割裂。
为此,guest端针对不同系统开发了功能相同的QXL驱动,一方面增强了QXL显卡处理画面的效果,另一方面也提供了调用QXL显卡实现调整分辨率的接口供vdagent实现分辨率自适应功能。
2.4 Client端原理详解
SPICE客户端主要作用是解析和渲染远端发送的数据,提供远程访问虚拟机桌面的能力。SPICE Server端和Client端均采用了模块化的思想、多通道的解决方案来实现远程桌面的传输。其优点是降低了代码的耦合度,便于通过横向扩展来支持新的功能。SPICE的每一个通道都提供一个特定的功能。Client基础架构如图2.6所示。
为了拥有一个纯净的跨平台结构,SPICE定义了一套通用的接口(Platform类),将其特定于平台的实现保留在并行目录中。这套接口定义了许多低级服务,例如定时器和光标操作。
Application是主类,它包含和控制Client,monitors和screens。主要功能有解析命令行参数,运行主消息循环,处理事件(连接、断开连接、错误等),将鼠标事件重定向到输入处理程序,切换全屏模式等。
(1)Channels
Client和server通过channels进行通信。每种channel类型用于特定类型的数据。每个channel都使用专用的TCP套接字,可以是安全(使用SSL)或不安全。在Client端,每个通道都有一个线程,可以通过区分线程优先级来为每个通道提供不同的QoS。
RedClient - main channel类,它能够控制其他实例化channel(使用工厂模式创建channel,连接、断开连接等)。
图2.6 客户端基础架构图
- 所有channel的祖先是:
RedPeer - 用于安全和不安全通信的socket封装类,提供基础功能,例如connect,disconnect,close,send,receive和用于迁移的套接字交换。它定义了通用消息类:InMessages,CompoundInMessage和OutMessage。所有消息都包括type,size和data。
RedChannelBase - 继承于RedPeer,提供与Server建立通道连接的基本功能,并支持与服务器的通道功能交换。
RedChannel - 继承于RedChannelBase。此类是所有实例化channel的父级。处理发送传出消息和分派传入消息。RedChannel线程运行具有各种事件源的事件循环(例如,发送和中止触发器)。通道套接字被添加为事件源,用于触发SPICE消息的发送和接收。
- 可用的channel有:
Main - 由RedClient实现
DisplayChannel - 处理图形命令,图像和视频流
InputsChannel - 键盘和鼠标输入
CursorChannel - 指针设备位置,可见性和光标形状
PlaybackChannel - 从server端接收的音频,由Client播放
RecordChannel - 在Client捕获的音频
(2)Screens and Windows
ScreenLayer - screen layer被附加到特定screen,提供矩形区域的操作(set,clear,update,invalidate等)。
RedScreen - 使用screen layers(例如,显示,光标)来实现screen逻辑并控制窗口来显示其内容。
RedDrawable - 特定于平台的basic pixmap的实现。支持基本渲染操作(例如,复制(copy),混合(blend),组合(combine)。
RedWindow_p - 特定于平台的窗口数据和方法。
RedWindow - 继承于RedDrawable和RedWindow_p。实现了基本窗口状态和跨平台相关的功能(例如,显示,隐藏,移动,最小化,设置标题,设置光标等)。
3、SPICE协议产品化改造方案
SPICE协议具有完全开源这个最大的优势,方便对其进行功能的扩展以及适配特定场景的二次开发。但同时在产品化方面短板也很明显。SPICE协议要实现产品化的改造,仍然存在着许多亟待解决的问题。例如视频处理能力不足、网络传输带宽占用过大、画面容易出现卡顿、用户使用体验差等突出问题。本文针对通用场景下的用户体验,提出了一些产品化改造的思路。
3.1 带内协议改造
SPICE协议是一种典型的带外协议,带外协议是指客户端通过QEMU层与服务端进行交互,这一特点导致SPICE协议严重依赖于QEMU,使其丧失灵活性。为了更好地与移动云的底层虚拟化层进行对接,也为了降低对QEMU的依赖,需要将SPICE协议改造成带内协议。
带内协议与带外协议最大的区别在于SPICE服务端的位置不同。带外协议的架构图如图3.1所示,SPICE服务端位于QEMU层,分别通过QXL设备和VDI端口与虚拟机的QXL驱动和VDI代理进行交互。客户端需要通过宿主机的IP地址加上端口号连接上SPICE服务端,不同的虚拟机需要不同的端口进行连接。
图3.1 带外协议结构图
带内协议的架构图如图3.2所示,SPICE服务端位于虚拟机中,作为Guest中的一个SPICE进程,负责数据的传输。Guest除了QXL驱动和VDI代理之外,需要实现抓屏和视频编码的功能。带外协议的视频编码功能是在服务端实现的,带内协议需要借助DXGI等工具实现抓屏并传输,并在Guest端实现视频的编码。服务端与客户端的传输部分,借助WebRTC传输技术,实现更高效、稳定的数据通信。
图3.2 带内协议架构图
目前,SPICE协议的带内改造有两种较为可行的方案,如图3.3所示。方案一是将SPICE服务端和QEMU有关SPICE的初始化和调用部分代码迁移到SPICE进程中,使得SPICE成为一个可执行的服务,该服务负责完成系统底层的数据交互,并通过多通道与客户端进行连接;方案二是借助SPICE流代理组件,流代理负责完成抓屏、编码等功能,并通过迁移到虚拟机中libspice与客户端进行连接。两种方案的目的相同,均是将SPICE服务端移植到虚拟机,但实现方式不同。难点都在于SPICE服务端作为QEMU的一个动态库,只包含被QEMU调用的接口,初始化部分和调用部分需要从QEMU中移植出来,并将其改造成兼容不同操作系统的服务。综上所述,方案二使用SPICE流代理组件实现抓屏、编码等功能可行性更高,也更易于实现,方案二作为带内改造方案更加合适。
图3.3 带内改造方案
3.2 H.26x编解码集成
(1)H.264编解码集成
H.264是国际标准化组织(ISO)和国际电信联盟(ITU)共同提出的继MPEG4之后的新一代数字视频压缩格式。在SPICE中,H.264主要是通过Gstreamer中的x264enc实现。目前,Gstreamer主要用于处理音频或视频。x264enc是Gstreamer的插件,是基于x264库实现H.264编码的一种具体方案。
具体的集成过程如下:首先在spice-server的物理机上安装x264编码库,接着安装Gstreamer。在Gstreamer中,x265enc在gst-plugins-bad插件包中,正确安装该插件包后,安装spice-server即可在Server端开启H264编码。同样的,客户端正确安装Gstreamer后,可以进行H264解码。
Gstreamer的核心就是管道,将数据流输入管道,经过管道的处理后输出数据流。在sever端的H.264编码中,管道使用x264enc对数据流进行编码后,最输出H.264数据流并发送至客户端。客户端进行解码处理后,将图形界面显示到客户端上。在SPICE中,对Gstreamer中H.264编码管道的具体描述如下:
appsrc is-live=true format=time do-timestamp=true name=src ! videoconvert ! x264enc name=encoder byte-stream=true qp-min=15 qp-max=35 tune=4 sliced-threads=true speed-preset=ultrafast intra-refresh=true ! appsink name=sink
H.264编码管道主要由四个元素构成,分别是appsrc,videoconvert,x264enc和appsink。其中appsrc主要是获取应用程序的数据,将其插入到Gstreamer的管道中。videoconvert的主要功能是转换多种视频格式,具体而言是在SPICE中将appsrc获取的数据流格式转换为下一个元素,如x264enc,能够接收的视频格式。appsink是一个sink的应用程序插件,能够使得应用程序获取管道中的数据流。以上三个元素为Gstreamer常用的元素。
在H.264编码中,核心是x264enc元素。x264enc主要是将原始视频编码为H.264编码格式,在x264enc的属性控制中,qp代表量化器参数,qp相关的参数与码率控制相关,当启用了qp相关的参数设置,x264enc将使用QP模式,qp的值反应了编码后图像的质量与原始视频流质量的差距,当量化参数qp=0时,编码器将产生无损的输出,当量化参数qp=51(x264enc可设置的最大量化器)时,图像的质量将会降到最低,但是码率会提升。
图3.4 不同qp的对比(左qp=51,右qp等于0)
目前,Server端能够完成H.264编码,流量带宽有明显下降。H.264的解码工作主要由Client端完成,使用基于Gstreamer的H.264解码器。在Client具体的实现主要是由uridecodebin插件实现,该插件可以根据给定的uri,自动选择合适的音视频解码器,从而屏蔽了不同媒体的封装类型和解码器的类型。在Client端中,首先采用同样采取appsrc将数据流从应用程序中获取出来,decodebin会自动检测输入数据流的格式并在后台构造相应的Gstreamer元素来进行解码。decodebin插入typefind元素来确定流的媒体类型,在H.264解码过程中,视频流的数据格式为h-x264,使用h264parse元素来分割输出H.264帧数据,使用avdec_h264进行解码,解码后使用videoconvert将视频流转换成appsink能够接收的方式,进而传输至应用程序进行渲染成像。
图3.5 H.264解码器管道
(2)H.265编解码集成
H.265是ITU-T VCEG继H.264之后所制定的新的视频编码标准。在server端,H.265的集成同样是基于Gstreamer的,采用的是x265enc编码器,最终具体实现的管道描述如下:
appsrc is-live=true format=time do-timestamp=true name=src ! videoconvert ! video/x-raw,format=\(string\)I420 ! x265enc name=encoder tune=4 speed-preset=ultrafast ! video/x-h265, stream-format=byte-stream, alignment=au, profile=\(string\)main ! appsink name=sink
与H.264相同,H.265的管道输入的原始数据流同样是从应用程序中获取,因此仍然采用appsrc获取数据,通过videoconvert将视频转换成x265enc能够处理的数据格式。与H.264不同的是,此处显式的给出了videoconvert的输出数据格式,为I420格式,原因在于,采用的x265enc版本对于I420格式适应较好。相较于x264enc,x265enc的参数量较少,在SPICE中目前仅设置tune与speed-preset=ultrafast来控制码率与图像质量。需要指出的是,在开发过程中,H.265相较于H.264,采用的x265enc不成熟,在H.265理论上可行的方案并没有完全支持,因此需要显式地指出数据的各种格式,如果数据流没有指定视频格式,可能会导致数据流错误,无法进行正确地编码。H.265解码工作与H.264工作类似,仅需要将h264parse与avdec_h264替换为h265parse与avdec_h265,该工作可以由decodebin进行自行处理完成替换。
3.3 广域网环境传输优化
(1)SPICE在广域网的局限性
SPICE的三大模块相互隔离,为保证模块间的通信,SPICE基于qemu虚拟硬件实现了Server端与Guest端的通信。而Client端与Server端通常安装在不同的物理机上,因此采用TCP传输协议建立二者的数据通道。
在局域网环境下TCP协议尚能满足视音频传输的需求,而在较为复杂的广域网环境中,TCP协议较大的数据头部和阻塞、丢包重发等机制都会增加数据在长链路网络下的延迟和额外带宽消耗。SPICE是实时桌面传输协议,远程数据不仅包含实时音视数据,还包括其他实时指令数据,对网络传输的延迟和吞吐有着较高的要求。为实现SPICE移植到广域网下的需求,势必需要对传输进行优化。
(2)基于QUIC协议的传输优化
QUIC是由谷歌对标TCP制定的一种基于UDP的应用层可靠传输协议,相比TCP在传输层实现的可靠性,QUIC在应用层实现的可靠性更能适应复杂网络,因此在网络情况较为复杂的广域网,QUIC可以充分利用底层UDP的特点,在保证数据传输可靠性的前提下,降低传输延迟、提高传输速率。
图3.6 TCP和QUIC的传输架构
如图所示,Client端和Server端都属于应用层,左边是SPICE当前的网络传输方案,基于websocket通过底层TCP协议传输与接收数据。右边则是改造后的QUIC传输方案,改造需要在Client端和Server端同时进行,由于QUIC的功能与TCP一致,因此在将TCP切换为QUIC后,还需要在整体架构上增加部分机制以实现websocket的功能。
(3)基于webrtc框架的传输优化
webrtc是谷歌发布的一项实时通信的音视频传输技术,它提供了包括音视频的采集、编解码、网络传输、显示等功能。相比QUIC,webrtc则是直接对标websocket等传输框架,实现应用间的传输连接。标准webrtc采用UDP协议作为底层传输协议,实现了应用间点对点的连接,并且对传输机制进行了优化,相比基于TCP的websocket框架,基于UDP的webrtc有着更强的稳定性和更低的延迟。
图3.7 websocket和webrtc的传输架构
相较来说基于webrtc的优化架构与原本websocket架构类似,在Client和Server端,二者都需要将原本的websocket框架转换为webrtc。
3.4 虚拟显示方案
在云终端传输协议的显示技术方案中,通常有3种实现方式分别为:
虚拟显卡、GPU虚拟化(vGPU)、显卡直通。
考虑到产品成本及物理资源消耗,针对普通办公需求的用户,目前主流的云桌面(电脑)产品均采用的是虚拟显卡技术方案。
(1)虚拟显卡工作原理
在传输协议服务端(Server)的虚拟机管理软件(vmware、hyper-v、qemu-kvm)中,通常内置有一种或多种虚拟显卡设备(QXL、Cirrur、SVGA等)提供给虚拟机,虚拟机内的windows操作系统会将桌面显示数据全部写入到虚拟显卡中。
虚拟显卡接收虚拟机的所有桌面图像后,把图像数据通过某种手段(如共享内存)共享给宿主机上的虚拟机管理软件。管理软件将这部分数据在某个窗口中还原出来,从而在宿主机上看到虚拟机的桌面图像;同时,把虚拟显卡共享给宿主机的图像数据截获下来(管理软件内置有API截获每个虚拟机的图像数据),再经过图像压缩算法(通常采用H.264)压缩后,通过网络传输协议(如SPICE、VNC)发送给客户端。具体工作流程可参考下图:
图3.8 虚拟显卡工作原理
(2)Windows显示驱动模型(WDDM)
提到显卡(无论是物理显卡,还是虚拟显卡),自然少不了显卡驱动的参与。
Windows操作系统的显示/图形驱动模型,从win7开始均采用的Windows Display Driver Model(WDDM)模型,完整的WDDM显示驱动模型由两部分组成:内核模式(Kernel-Mode)的微端口驱动(Display Miniport Driver)与用户模式(User-Mode)的显示驱动(Display Driver)。其架构如下:
图3.9 WDDM架构示意图
在WDDM 1.2版本中引入了三种显卡驱动类型,分别为:
- Full Graphics Driver
完整功能版本,支持2D和3D硬件加速,拥有完整的渲染(Render)、显示(Display)和视频(Video)功能。
- DOD:Display Only Driver(内核模式驱动)
顾名思义,这一类的驱动只有最基本的显示功能,不支持运算(渲染)。
- ROD:Render Only Driver
该类型驱动仅支持渲染功能,不支持显示功能。
在云桌面应用中,虚拟机内部通常采用的是DOD驱动程序来驱动虚拟显卡(QXL)进行显示,而把复杂、耗时的渲染工作交给宿主机侧的CPU。
(3)间接显示驱动(IDD)
在Win10 1607版本之后,WDDM 2.1版本提供了间接显示驱动(IDD,Indirect Display Driver)的模型来实现虚拟显示器的功能。
- IDD工作原理
该驱动在Windows电脑(虚拟机)上模拟出一个“虚拟显示器”设备,利用软件的手段将该虚拟显示器接到(虚拟/物理)显卡的输出端口上(模拟HDMI/VGA)。对于虚拟机操作系统而言,该虚拟显示器相当于“真实的物理显示器”,可以在系统显示设置控制面板上看到该设备,也能像物理显示器一样被复制、扩展。客观上该虚拟显示器是“不存在”的,因此看不到该显示器的画面。但是我们可以将虚拟显卡输出到虚拟显示器的显示数据截获,再在某个窗口画出来,或者通过传输协议发送给所需要的客户端,即可在客户端窗口内实现虚拟机双屏显示;
- IDD架构
IDD驱动是在IddCx(Indirect Display Driver Class eXtension,间接显示驱动类扩展)的基础上开发的,属于“纯”用户模式驱动程序,不包含任何内核模式的组件,能够使用任何 DirectX API 来处理桌面镜像数据。同时,IDD运行在session 0中,在用户session中没有运行任何组件,因此有助于提高整体系统可靠性。该驱动框架如下图:
图3.10 IDD架构示意图
(4)虚拟显示方案优化
基于SPICE传输协议的虚拟机,若要提升虚拟机画面显示性能,支持多屏显示、窗口自适应、分辨率调节等功能,需要开发相应的显示驱动程序;具体可以参考以下方案:
- 一显卡、多显示器(DoD+IDD)
图3.11 DoD+IDD显示方案
该方案利用底层虚拟化软件加载一个虚拟显卡并采用DoD驱动显示,再通过一个IDD虚拟显示器拓展屏幕,实现双屏;
- 多显卡、多显示器(DoD+DoD)
图3.12 DoD+DoD显示方案
该方案实际上是给虚拟机添加2个虚拟显卡并采用DoD驱动,每个虚拟显卡对应一个宿主机中的虚拟显示设备,进而实现双屏;
3.5 USB重定向策略
(1)SPICE协议中的USB重定向存在的问题
USB外设的使用是云终端产品中影响用户体验的关键一环。现阶段SPICE协议在USB重定向上还存在如下问题:
①由于USB驱动加载模式会频繁的安装卸载驱动,造成了在文件(夹)
的传输过程中效率低下且不稳定。首先,驱动的安装和卸载时间较长,在一些老旧配置的机器上甚至要花费几分钟来安装驱动,导致设备从开始映射到真正能够使用需要花费较长的时间等待。其次,驱动的安装卸载会引起设备的反复刷新,容易影响已经映射成功的其他设备,导致其他设备工作异常等。最后,频繁的安装卸载驱动容易造成系统的设备库混乱,在不进行重定向时,系统也没办法加载正确的设备驱动导致设备不可用。
②其它USB设备如摄像头重定向等有待进一步功能开发及测试。对于大容
量数据的传输和USB摄像头等有大量实时输出传输的场景,其效率是比较低的,同时一定会占用大量的带宽,这些也都是要考虑的因素。
(2)改造方案
整个重定向的过程中涉及到了SPICE客户端,SPICE服务端和Guest端,详细的处理流程如下图3.12所示。
在需要USB设备映射时,USB设备的控制和读写请求通过Guest端发出,通过虚拟化软件QEMU提供的VDI接口将命令传送给SPICE服务端。SPICE服务端在收到消息后基于libusbredir定义的USB重定向协议读数据进行处理,然后通过SPICE协议定义的USBRedir通道,将数据发送到客户端。客户端通过USB通用驱动对收到的数据进行解析,然后对物理USB设备进行操作。物理USB设备做出应答后再通过原路径返回数据。
在不需要进行USB设备映射时,SPICE将对应标识的通用设备驱动进行卸载,操作系统通过USB设备属性进行驱动匹配设备然后将设备弹出,再让设备重新被识别,在此查询自己的驱动库,在驱动库中查找合适的驱动,由于系统有备份机制,即使原来的USB设备有厂商自定义的功能设备驱动,在被通用设备驱动覆盖安装后仍然能够找到设备驱动,SPICE将对应标识的通用设备驱动卸载后,USB设备重新识别时,仍能重新正确加载设备驱动。
图3.13 USB设备重定向架构图
整个SPICE云终端传输协议项目中USB设备重定向采用USBRedir技术,基于该技术,针对SPICE协议中USB重定向存在的问题,改造方案如下:
- 驱动替换
通过驱动替换技术代替目前采用的驱动安装方式加载驱动。驱动安装时更新操作系统的驱动库来进行设备驱动的加载,而驱动替换技术则是修改USB设备属性来达到匹配通用驱动的目的。操作系统是通过USB设备属性进行驱动匹配,预先将通用设备驱动安装到一组自定义的设备属性上面,在进行映射时修改USB属性信息为之前预定义的的设备属性,这样操作系统根据设备属性匹配驱动时,就会加载通用设备驱动,在不进行重定向时不做任何设备信息的修改直接上报设备的真实信息,以此操作系统就会加载设备对应的功能驱动。最终通过修改设备属性实现驱动替换就可以避免驱动的频繁安装卸载。
- usbredir+压缩编解码
通过USB数据的压缩方法来改善USB重定向的效果,降低带宽,提升数据传输效率。在USB重定向过程中,存在大量数据传输的场景通常为文件拷贝和USB摄像头传输等。在文件拷贝的应用场景中,由于文件内容不能被修改,为此需要进行无损压缩。而在USB摄像头重定向之类的应用场景中,传输USB采集的数据量通常比较大,一般没有进行数据的压缩处理,而且此类数据可以允许信息量的损失,为此可以通过成熟的视频编解码压缩算法如MJPEG、H.264等进行压缩处理后再发送到服务端,由服务端做解码处理后再还原数据。
3.6 SDK裁剪优化
(1)API重构
SPICE采用GTK+实现的客户端的代码。GTK+底层采用GObject(C语言)来模拟面向对象,代码实现较为繁琐,随着代码量的增加,其代码的维护难度也比较高,且最为重要的是如果不熟悉GTK+运行机制,开发者几乎很难使用这套API接口,因而新版的Server端的代码已经不在使用GObject来模拟面向对象,转而使用C++来开发代码。基于这一原因,我们也需要对客户端的框架进行优化,选取基于C++的跨平台框架Qt进行代码的重构,重新设计API,降低用户调用API的难度。
(2)smartcard裁剪
智能卡—内嵌有微芯片的塑料卡(通常是一张信用卡的大小)的通称 ,一般芯片都有CPU、RAM和I/O,需要特定的读卡器进行交互,但是无法使用一种读卡器兼容所有类型的智能卡。此外,虽然智能卡对于许多应用程序来说可能更安全,但它们仍然容易受到某些类型的进攻。如可以通过智能卡技术从芯片恢复信息的进攻。差分功率分析可用于推断公钥算法(如RSA)使用的片上私钥。再者,移动云云电脑主要面向个人用户,面向私有云部署的智能卡使用情景几乎很难用到,因此可以移除此功能。
(3)协程裁剪
spice-gtk采用原生的协程来实现I/O的读写,虽然原生的协程与相比线程能够减少创建的开销和避免无意义的调度,但是并不十分适合移动端平台。协程适合于高并发吞吐的场景,牺牲了线程的公平性,如果存在一个较长时间的计算任务(如图像解码),将影响到IO任务的响应延时,即会影响其它同步进行的数据处理(如音频播放)。而且单线程的协程方案并不能从根本上避免阻塞,如文件操作、内存缺页,所以对于云桌面终端这种并不需要应对高并发的场景,使用多线程更能兼顾各个channel数据处理的公平性,从而在显示复杂动画网页时不会影响音频播放和外设重定向。
4、总结及演进方向
由于SPICE协议的出现是为了解决远程桌面的问题,其在目前的移动互联网时代甚至未来的全真互联网时代有着明显的不足。想要适应飞速发展的互联网,云终端传输协议还要朝着不同的技术路线继续演进。
1️⃣ 适配容器技术
以Docker为代表的容器技术发展迅速,不同于资源消耗过多的虚拟机,Docker以轻量、资源消耗少的优势在云游戏、云手机等云应用普遍采用。云终端传输协议应适配容器技术以支持轻量的云应用场景。
2️⃣ 超高清视频支持
超高清是显示产业继数字化、高清化后的新一轮重大技术变革,随着用户显示屏分辨率的不断提高,云终端传输协议对超高清视频的支持已提上日程。
3️⃣ 全景视频支持
元宇宙已成为当下最火热的话题,虚拟现实(VR)作为元宇宙最有望落地的入口,被称为“下一代通用计算平台”,它使用计算机创建出逼真的三维立体虚拟场景,用户可以与虚拟环境进行交互,从而得到强烈的沉浸感。云终端传输协议若想在元宇宙中有一席之地,要朝着可穿戴终端方向演进。
综上,目前的云终端传输协议像是站在下一代互联网革命入口的上古猿人,仍处于非常原始的状态,想要支撑未来宇宙,目前来看要走的路还有很长。
👇参考文献
[1] Gstreamer Plugins Documentation [EB/OL] .https://gstreamer.freedesktop.org/documentation/plugins_doc.html?gi-language=c,2022.
[2] Spice for Newbie [EB/OL] https://www.spice-space.org/spice-for-newbies.html.
[3] Lan Y , Hao X . Research on technology of desktop virtualization based on SPICE protocol and its improvement solutions[M]. Springer-Verlag New York, Inc. 2014.
[4] 王哲. 云平台虚拟桌面架构中SPICE协议的研究与优化[D].电子科技大学,2020.
[5] 张丁丹. 基于桌面云的USB设备重定向系统设计与实现[D].电子科技大学,2020.
[6] WDDM Architecture-Windows Driver [EB/OL]. https://learn.microsoft.com/en-us/windows-hardware/drivers/display/windows-vista-and-later-display-driver-model-architecture.
[7] 彭晓平,张雪坚,黄波. 基于KVM的虚拟化技术研究[J]. 中国新通信,2017(20):77-80. DOI:10.3969/j.issn.1673-4866.2017.20.066.
[8] 乔咏. SPICE协议的视频传输分析与改进[D]. 山东:山东大学,2013. DOI:10.7666/d.Y2433562.
[9] Thompson S . The cold hard truth about TCP/IP performance over the WAN.(Storage Networking)(Wide Area Network )(Transmission Control Protocol/Internet Protocol )[J]. Computer Technology Review, 2004, XXIV(8):p.24.
[10] Langley A , Iyengar J , Bailey J , et al. The QUIC Transport Protocol: Design and Internet-Scale Deployment[C]// the Conference of the ACM Special Interest Group. ACM, 2017.