基于 WebRTC 的云游戏解决方案和技术优化
Photo by Sean Do on Unsplash
本次演讲主要内容将包括云游戏整体方案的架构介绍、使用开Open WebRTC ToolKit (OWT)实现流和控制命令的传输,以及为实现云游戏所需的超低延迟所做的优化。
文 / 诸剑俊
整理 / LiveVideoStack
大家好,我是来自英特尔的诸剑俊,我们组主要从事有关于WebRTC的研发,并且有一个基于WebRTC的开源项目OpenWebRTC Toolkit (https://github.com/open-webrtc-toolkit),这次演讲的主题是基于英特尔平台和WebRTC技术的云游戏解决方案。
首先介绍一下云游戏,云游戏对于一些人来说已经比较熟悉了,这个概念不是特别新,最初叫作云游戏或者远程游戏,但由于以前的网络没有现在发达,而且带宽也没现在好。随着接入带宽的增加,再加上5G的建设,云游戏近几年又流行起来了。然后我会对我们的技术方案和碰到的挑战进行讲解,以及英特尔对此所做的一些优化,也会在此与大家分享。
1. 云游戏概述
1.1 云游戏介绍
关于云游戏,它的游戏是跑的服务器上的,所以运算都是在服务器上做的,客户端其实只是收了服务端发来的一个图像或者指令,最后在客户端上呈现出来以服务用户。所以云游戏涉及两个要素:一是在服务器上操作,二是在客户端上观看。
1.2 云游戏的参与方
云游戏的产业主要有以上几个参与方,前三个相当于业界的一些提供方。第一个是云服务提供商,它主要是作为基础架构的提供方,因为搭建云游戏需要有一个较好的基础架构。
1.2.1 云服务提供商
云服务提供商在国内比如有阿里云、腾讯云,以及国外的微软公司等。由于游戏对场景有一些硬件的需求,云服务提供商可以提供以下服务:首先它拥有比较高的图像的处理能力;其次因为游戏对画面质量的要求比较高,所以需要有比较好的QoS去控制基础架构;再次整合CDN解决方案提供直播等功能;最后云游戏可能是云服务下一个利润增长点。
1.2.2 游戏服务提供商
游戏服务提供商,与游戏开发者不同,它提供的是游戏服务、游戏平台。
如果游戏跑在云端,就比较容易进行反作弊操作,因为客户端获取不了内存里的数据,所以没办法修改数据或者做像地图全开这种效果。但反作弊操作也会带来一个问题,那就是游戏做了反作弊后,不改游戏而是去直接提供云游戏,这在目前其实是做不到的,因为游戏内部一般会防止云游戏的应用程序去获取数据。
其次,游戏的服务提供商可以更方便地对游戏进行更新和升级,因为传统的游戏方案一旦升级就需要用户进行下载和安装。但是如果采用云游戏这种方案,服务端一旦更新完毕,用户就可以直接进行游戏。
最后,云游戏可以针对云游戏机房和游戏后端服务器机房间链路进行优化。因为云游戏跑在云端,游戏跑在服务器上,游戏后端的服务器也是在一个数据中心,由于在云游戏的机房和游戏后端的机房的链路比较固定,所以可以做一些优化,把云游戏的机房和游戏服务部署在同一个机房里面,这样延迟反而会更低。
1.2.3 游戏开发商
对于传统的游戏开发者来说,云游戏提供给游戏开发者一个比较好的平台,让它可以更关注对游戏本身做一些优化,对内容进行提升,以减少兼容性问题;其次云游戏跑在云上,云上的设备有固定的配置,所以可以对特定的平台做一些优化。
1.3 云游戏的质量要求
关于云游戏在质量要求的方面,如果想提供给用户玩家一个较好的游戏体验,有几点会影响到用户的体验。
第一是延迟,这是大家比较关心的,关于延迟,我们基本上调研了一下对于不同类型的游戏,它会有不同的延迟要求。FPS游戏要求比较高,如果超过100ms,大家可能就会受不了。另外,RPG游戏在500ms左右,即时战略游戏在1000ms,即一秒,还是能够接受的。
第二是视频质量,因为对云游戏玩家来说,不想在本地跑太强大的机子,以减少不必要的投入,所以云游戏要做到让玩家在不太好的机子上体验一个比较好的效果。其中一种衡量视频质量的参数是PSNR,一般来说PSNR值在30以上,视频质量会比较好,但是高于25的话也是可以接受的,这个取决于客户订阅的服务等级以及客户端的网络配置情况。
第三是刷新率,现在的大部分显示器的刷新率在60左右,最近发现有一些玩家特别是一些比较专业的游戏玩家,要求刷新率为144,因为现在一些新的硬件刷新率都已经支持到144了,而且用户觉得在144和60之间是能观察到一些差距的。
第四分辨率,现在的分辨率基本上都在1080p以上,但是对4K的要求目前还不高。我们收到的一些反馈是玩家会更关心刷新率,而不是把分辨率无限地往上升。
最后是带宽,带宽用的越少,成本就越低,所以要求带宽越低越好。
2. 现状和挑战
现阶段的一些挑战,大部分情况下主要是网络带来的一些挑战。首先云游戏带宽的使用确实有点高,音视频通话在几兆带宽的情况下,可以达到比较好的效果,但是云游戏基本上要在16Mbps以上的带宽才会呈现出比较好的效果。
其次,玩家在不同的设备上,比如iPad、手机或笔记本,连了一个WiFi网络或者4G的网络,但当网络不稳定时,整个网络参数就会全部变掉,所以这也是需要解决的一个问题。
最后是高质量和低延迟之间的平衡,因为想提供高质量的游戏效果,带宽的使用就会增加,对于服务器的性能要求也就更高,若要尽快地把服务端的图像发送到客户端,就需要在低延时与高质量之间做权衡。
2.1 实现模式
关于实现模式,目前来说采取两种方案。一种是服务端进行一些游戏上的处理,再把渲染的指令发到客户端,由客户端来进行渲染。这样的好处是渲染指令的数据量会比较小,发到客户端以后对带宽的要求会比较低,但缺点是如果是一个高质量的游戏,它的渲染指令对计算机的要求会比较高,那么对于用户来说,还是需要买一块好的显卡的。
另外一种方案是传输图像,服务端将一切准备好,游戏在服务端可以进行操作,再通过一定的方法把图像获取出来,然后发到客户端。这样发送的是一个视频流。这种方式的好处是客户端不需要太强大的CPU、显卡之类的投入,但是对带宽的要求比较高。
2.1.1 整体架构
这部分是目前我们实现云游戏解决方案里的一个高层面整体架构图,它包含了几个模块。一是捕获和编码模块,它的作用是从游戏里去获取音频、视频以及指针信息,再把音频和视频进行编码,然后把编码好的数据帧发送到传输层。
WebRTC实时音视频和数据传输为云游戏提供了很好的技术支撑,用户不用下载任何插件,在浏览器里就可以玩高端游戏,所以用WebRTC进行视频和音频的传输。传输层会把音视和视频的数据发到客户端,客户端再进行解码和播放。因为玩游戏,用户是有输入的,所以客户端还需要采集用户的鼠标、键盘、手柄等信息,这些信息通过WebRTC的data channel,发到服务器上的WebRTC的传输层,然后传输层会把指令拆出后再传到事件的重播模块,重播模块相当于把用户在客户端的指令重新应用到游戏里面去。
2.1.2 硬件方案
接下来为大家介绍一下英特尔目前的硬件方案,因为要在机房里面部署云游戏需要一些硬件,名字是叫PCFarm,它的思路是在有限的空间、有限的机房和机柜下,提供更大、更多的处理能力,可以将多达144个高性能的PC放在一个两米的标准机柜里面,并且提供多种用户的输入接口。
2.1.3 模块图
这张图是一个软件层面的模块图,从图中右下角开始,它相当于是用户的一个游戏,当有一些视频、音频需要呈现出来时,在Render模块有两种方案去获取游戏中的数据。一种方案是抓屏,通过抓整个显示器屏或者抓游戏所在区的屏。另一种方案是截取游戏的绘图指令。对绘图函数进行挂钩(hook),当游戏有内容需要呈现的时,那么数据的输出直接就接到输入的接口。但这种方式,不是每个游戏都可以做的,需要和游戏厂商合作。因为一般游戏厂商不会直接开放接口也不会允许其它的程序进行拦截,所以我们会寻求一些合作,如果有厂商愿意合作的话,可以更方便地使用这种性能更高的方案。
通过两种方案采集到的游戏数据会被发送到编码模块,编码模块会做一些编码上的优化,再将编码后的数据打包发送到网络模块,最终发送到客户端。
2.1.4 解决方案的实现
我们解决方案的实现是基于GamingAnywhere,它是一个很早的开源项目,是基于开源项目进行运作的,并已经提供了比较多的跟远程游戏、远程应用有关的功能。我们对GamingAnywhere做了一些优化,上图是GamingAnywhere里面的一些线程和模型,它会有一个音视频的输入,音视频的输入有模块化的接口被送到下一层的音视频的编码器中。一种接口,多种实现,接口实现后可以对它进行优化。图中右边这条通路是一个控制流程,它从客户端发送数据到服务器,默认带了一个RTSP服务器。
3. 云游戏的优化
3.1 传输层的优化
在传输方面,除了原有的RTSP方式,我们也加入了WebRTC的支持。WebRTC提供低延迟、点到点的通信,很适合云游戏这种应用场景。我们测试了在弱网的环境下,WebRTC会有比较好的体验。在3%左右的丢包环境下,WebRTC会有较好的画质和更低的延迟。
3.1.1 WebRTC
WebRTC技术虽然出现很久了,但它的标准还是停留在1.0。即使如此,基于WebRTC也有一些优点:
首先,它是实时的,所以它的时延会比较低,设计延迟可能在200-300ms左右,但其实它的延迟在云游戏场景里还是不够低,云游戏需要更低的延迟。
其次,WebRTC是一套开放的标准,受到了主流浏览器的支持。并且它也是跨平台的,在各个平台都能用而且不需要插件,打开浏览器就可以用。因为WebRTC是一个开放的标准,所以其他的原生应用程序,只要实现了WebRTC标准就可以接入,这也是使用WebRTC解决方案的好处。
3.1.2 Open WebRTC Toolkit (OWT)
上图是我们基于WebRTC做的一个开源项目Open WebRTC Toolkit,目的是让大家能够更方便地使用WebRTC,并且在服务端提供的一些比较强大的媒体处理能力,包括会议、转码、媒体分析以及推流等功能。而且可用其中一个模块或者所有模块,进行分布式的部署,部署在不同的机房中有不同的接入节点,让用户进行就近接入。其次,客户端提供了一个全平台的解决方案,我们的云游戏用OWT作为其中一部分进行传输就可以享受到这些好处,比如有比较全的客户端支持等。
3.1.3 基于GA的增强
对于GamingAnywhere加上OWT就变成了图中这样的一个架构,图中不同的颜色代表了不同的模块,绿色的是GamingAnywhere中已经有的对于音视频的输入,包括对于鼠标、键盘、事件的重播等。我们做了一些自己的模块并对其进行了优化,体现在图中红色的部分,主要是对编码部分进行了优化。
另外,传输层用了OWT的P2P SDK作为其中一端,放在云服务的服务器上,另外一端是各种各样的客户端。上图右边是客户端,绿色的部分是我们要对其进行增强,主要增强的是两个部分,一部分是因为GamingAnywhere用的方案是基于视频传输的方案,可能在某些情况下我们需要用到基于指定模式的云游戏,所以我们也希望能够把视频的输入源变成绘制指令。另外一个是在传输层,除了WebRTC以外,我们也在考虑对QUIC增加支持,QUIC是一个基于UDP的传输协议,它在为HTTP设计的,提供可靠的传输通路和流的概念。目前有P2P QUIC在W3C ORTC CG中开发,提供了类似data channel的接口,WebTransport(CS QUIC)
在WICG中开发。此外QUIC还提供了非可靠的传输,这对音视频的传输比较友好。
3.1.4 GA+WebRTC
上图部分我将对WebRTC的传输模块做一个更详细的解释,首先,在视频源外部进行编码器的优化,这是基于SDK做的一个编码好的视频数据,视频数据再把编码好的视频源送进WebRTC的模块,所以这里用到的是一个已经构造好的接口。其次,音频方面,目前我们是直接把GamingAnywhere抓到的音频的PCM数据直接输入,用WebRTC内置的音频编码器进行编码,最终将音频和视频全部发送到发送器,作为RTP打包后再发送出去。另一端通过客户端把鼠标、键盘等事件全部收集好,再传到datachannel的SCTP模块。通过ga-controller把客户端上JSON格式的鼠标、键盘事件转成SDL格式的事件送到SDL模块。
3.1.5 游戏加直播参考方案
这张图与刚才的内容比较类似,但是加入了一个直播模块。因为考虑到现在好多直播的应用场景,游戏主播直接通过云游戏方案玩游戏,然后直接就可以直播,因此增加了直播模块。在右下角有一个媒体服务器和一些直播客户端,通过OWT服务端的产品来实现,OWT的服务器提供比较强大的媒体处理转码以及推流功能,再把游戏服务器里的WebRTC的传输模块进行了扩展,除了游戏的客户端、P2P的WebRTC连接传数据以外,还要往媒体服务器上也推一路。这样的数据由于是从游戏服务器直接推过去的,所以它的延时很低。但是做直播的客户端是不能把他的鼠标、键盘用户输入事件给传过来的,玩游戏在这个参考方案中只支持一个人进行操作。如果要多人协同操作,需要做少量修改。
3.1.6 网络穿透
因为我们采用WebRTC方案,所以会有在网络方面的一些功能,比如网络穿透。如果把云游戏的游戏服务器部署在大型的数据机房,出现的问题会比较少。因为机房的端口会有配置进行开放,但是云游戏方案不一定运用在大型的公有云,也可能是私有云或家庭云,这种情况下,它就是一个真正的P2P连接,就会用到网络穿透的功能。网络穿透的主要原因是两端可能在路由器或者说在NAT的防火墙后面,在这种情况下它们就不能进行直接的连接,因为它的网络地址会进行转换。
像图中左边的电脑把自己的IP地址告诉右边的手机,那手机是连接不上的,它需要获得设备在互联网(公网)的地址。这里STUN Server的作用是客户端向STUN Server发一个包,然后STUN Server会回发一个包,这个包就走过了一条从内到外的链路。如果有多层路由器的话,它能通过STUN协议解出自己在每一层路由器上的IP地址和映射到端口的地址,这样它就知道了自己的所有的IP地址和映射到的端口,再把这个信息发到对端,再由对端把信息发到这一端,那么两方就可以进行连接,因为已经获取了对面的可连接的端口号以及可连接的IP地址。WebRTC还会做优先级的计算,如果两个人在同一个内网里面,虽然也会获得外网的IP地址,但是它会选择最近的那一条路径来进行连接。但是光用STUN通过探测NET转换地址的方式不能满足所有的网络环境,因为有很多NET是对称型的,它不允许外面直接发一个端口,而是需要从内部先发出去一个数据。
对于这种情况,对称型的NET或者规则比较复杂的防火墙,可能会把很多端口给禁掉,那么这种情况下光靠STUNserver是不够的,所以还需要TURN Server转发数据。有了TURN Server,连接成功的概率就会高很多,因为它可以进行转发而且又可以部署在公网,所以它就变成了两端和服务器的连接。但是缺点也显而易见的,用了TURN Server以后,流量都往服务器走,对于服务的提供商来说,这将带来比较大的成本。
3.1.7 OWT客户端
这是一张OWT客户端的图,服务端是一个集成在游戏服务器里P2P的客户端,另外一端可以是任何的OWT客户端。客户端结构的主要划分方式:首先它是基于Google的libwebrtc来作为它的底层,即图中绿色的模块,然后对整个WebRTC进行一些改正和增强。在此基础上我们提供了三组的API:一种是用于安卓的API;一种是用于Native开发的API;最后一种是提供给网页使用的JavaScript API。每一个SDK被分成两个模块,一个是P2P模块,用于点对点的连接;另一个是会议模块,用于推流,可用于直播。在Windows方面做了媒体层的增强,提供了硬件加速以及增加了优化后的Intel Media SDK的支持。
3.2 发送端优化
接下来的部分是关于发送端优化的内容,因为我们可能在运行程序时会发现延迟很大的问题,所以需要尽量减少延迟。我们观察了整个数据包在链路里面的时间,发现数据在节律发送器上面停留的时间过长,所以就修改了线程模型,把不同的线程在云游戏场景里面的优先级做了调整,是为了让数据包能够尽快发送到客户端。
造成延迟还有一个问题是带宽预测,因为WebRTC默认用的是gcc的带宽预测,所以它是基于延迟和丢包的,基于延迟的带宽预测非常敏感,可以快速降低带宽,这样不容易引起过量的数据包在网络通路上的堆积。但是这样会影响对带宽要求较高的场景的效果,于是我们对权值进行了调整。
3.3 接收端优化
在对发送端进行优化的同时我们在接收端上面也做了一些优化。接收端的优化主要在于增加了对Intel Media SDK的低延迟的解码,可以让解码端的时间降低。另外是音视频同步,我们发现有时候因为RTP上的时间戳没有打好,会导致视频已经到了,但还是要等音频。原因在于服务端是由两个线程跑的,一个取音频,一个取视频,两者并未完全同步,所以在接收端造成了额外的延迟,针对这一点我们对时间戳进行了优化。另外在某些情况下可以把音视频同步关闭,这样在云游戏场景里面的效果就会好一些。因为在云游戏场景中,大家希望能够尽快的收到数据,稍微有一点延迟造成音视频不同步的问题,对用户的影响反而不是特别大。
3.3.1 基于深度学习的超分辨率
接着介绍一下英特尔基于深度学习的超分辨率,因为某些情况下带宽实在提不上去,那就只能下调编码的质量,向客户端上传一个较低的分辨率。但是如果客户端的GPU性能很好,计算机性能很强大,就可以使用像超分辨率的技术为客户端提升视频质量。
3.4 客户端指针优化
在某些场景,比如玩家在游戏大厅聊天,这种情况下没有太多画面上的改动,但是由于用户不停地滑动鼠标,会导致整个图像被抓屏的图像有改变,所以编码器要重新工作,并将重新编好的帧发送到客户端。这就增加了编码器和带宽的消耗。针对这种问题,团队的解决方案是把鼠标和视频分开进行传输,视频如果碰到上文提到的这种情况,就不用再重新编码了,只需鼠标往客户端传一个更新的指针。有时鼠标会有样式的变动,如果有样式的变化,会把这个样式发送到客户端,由客户端在页面上面进行绘制以后再把鼠标指针对应贴到该有的位置上。
本文主要介绍技术方案,实际使用和部署中需要考虑版权和许可协议,建议咨询游戏厂商或与游戏厂商合作。
推荐阅读
-
UNIX 之父肯和丹尼斯(第二部分)--也许是因为宣传的缘故,今天人们的注意力大多集中在 "野生 "黑客身上,更多关注的是他们造成的破坏,而不是他们给技术带来的突破。如果回到 50 年前,情况就完全不同了。那时的黑客更像是为了爱好而自愿加班的模范员工,他们根本不在自己家里工作。 当然,那时的电脑还远远买不起。如果你对计算机技术感兴趣,就必须投身于学术机构或巨型企业。比如通用电气或贝尔实验室。 肯尼斯-莱恩-汤普森(Kenneth Lane Thompson)就是这些老派黑客中的一员,黑客们亲切地称他为 "肯"。他出生于 1943 年的前婴儿潮时代,22 岁从大学毕业,一年后获得硕士学位--这两个学位都来自加州大学伯克利分校的电子工程和计算科学专业。随后,他进入贝尔实验室,开始了 Multics 的研发工作。 不过,他并不总是在工作。他利用大型计算机编写了一款名为 "星际迷航 "的游戏,他和同事丹尼斯-里奇(Dennis Ritchie)在办公室里玩这款游戏。因此,当贝尔实验室在 1969 年退出 Multics 计划时,他和丹尼斯都有点失望。 不过很快,他们就找到了一台闲置的 PDP-7 机器。这台机器在当时属于低端产品,售价只有 7.2 万美元,所以贝尔实验室并没有太在意。幸运的是肯重写了《星际迷航》程序,开发了基于 Multics 的新操作系统,以便在 PDP-7 上运行游戏,甚至还为操作系统开发了一种新的编程语言 "B"。 这位 Unix 之父没有得到应有的尊重。
-
基于 WebRTC 的云游戏解决方案和技术优化
-
openEuler郑州用户组成立!openEuler与hyperfusion携手共建河南地区用户生态 - 开幕致辞 超融合操作系统业务总经理、openEuler委员会成员蒋振华先生为本次活动致辞。 在本次活动的致辞中,他提到,作为openEuler社区早期的成员,超融合见证了openEuler从成立到在各行业商业落地,再到跨越生态拐点的过程,感谢openEuler提供了一个全产业链共同创新的平台,共同推动创新技术的商业落地。 同时,本次活动得到了郑州市郑东新区大数据管理局、郑州中原科技城投资服务局的大力支持。 郑东新区大数据管理局曹光远 在活动致辞中表示,openEuler的应用和*应用设施的深度优化,为郑东新区数字化转型提供了安全、可靠、高性能的技术基础;郑州中原科技城招商服务局王林表示,郑东新区欢迎所有openEuler生态相关企业扎根当地,围绕openEuler社区共同发展,形成合力。 openEuler社区及运维功能介绍 openEuler技术委员会委员胡峰 openEuler技术委员会委员胡峰先生在本次活动中介绍了openEuler社区目前发展的整体情况,并重点从技术层面介绍了openEuler的运维功能。 openEuler 晚会 胡峰先生介绍智能运维工具 A-Ops 和 openEuler gala、 阿波罗 Apollo、智能漏洞管理解决方案等新功能,以及涵盖各种运维场景的精品运维组件。在*交流环节,许多用户就目前使用的 openEuler 在*交流环节,许多用户就自己在使用openEuler过程中遇到的一些问题与胡峰先生进行了进一步的交流。 软硬结合,构建多样化算力操作系统 Hyperfusion 基于 openEuler 的基础上,结合自身软硬件技术积累,推出了富讯服务器操作系统 FusionOS FusionOS. FusionOS 首席架构师张海亮 分享了 FusionOS FusionOS首席架构师张海亮分享了FusionOS的软硬件协同优势、卓越的性能和可靠性,以及FusionOS在金融、运营商、*、互联网等行业的实践案例,引起了众多用户的兴趣,分享结束后,不少参会者就FusionOS的特点向讲师提问并进行了交流。
-
数据库深度分页和优化解决方案介绍 | 京瓷云技术团队
-
RTC 技术|弹出式互动游戏解决方案和低延迟传输引擎体验优化
-
纯干货分享 | 研发效能提升——敏捷需求篇-而敏捷需求是提升效能的方式中不可或缺的模块之一。 云智慧的敏捷教练——Iris Xu近期在公司做了一场分享,主题为「敏捷需求挖掘和组织方法,交付更高业务价值的产品」。Iris具有丰富的团队敏捷转型实施经验,完成了企业多个团队从传统模式到敏捷转型的落地和实施,积淀了很多的经验。 这次分享主要包含以下2个部分: 第一部分是用户影响地图 第二部分是事件驱动的业务分析Event driven business analysis(以下简称EDBA) 用户影响地图,是一种从业务目标到产品需求映射的需求挖掘和组织的方法。 在软件开发过程中可能会遇到一些问题,比如大家使用不同的业务语言、技术语言,造成角色间的沟通阻碍,还会导致一些问题,比如需求误解、需求传递错误等;这会直接导致产品的功能需求和要实现的业务目标不是映射关系。 但在交付期间,研发人员必须要将这些需求实现交付,他们实则并不清楚这些功能需求产生的原因是什么、要解决客户的哪些痛点。研发人员往往只是拿到了解决方案,需要把它实现,但没有和业务侧一起去思考解决方案是否正确,能否真正的帮助客户解决问题。而用户影响地图通常是能够连接业务目标和产品功能的一种手段。 我们在每次迭代里加入的假设,也就是功能需求。首先把它先实现,再逐步去验证我们每一个小目标是否已经实现,再看下一个目标要是什么。那影响地图就是在这个过程中帮我们不断地去梳理目标和功能之间的关系。 我们在软件开发中可能存在的一些问题 针对这些问题,我们如何避免?先简单介绍做敏捷转型的常规思路: 先做团队级的敏捷,首先把产品、开发、测试人员,还有一些更后端的人员比如交互运维的同学放在一起,组成一个特训团队做交付。这个团队要包含交付过程中所涉及的所有角色。 接着业务敏捷要打通整个业务环节和研发侧的一个交付。上图中可以看到在敏捷中需求是分层管理的,第一层是业务需求,在这个层级是以用户目标和业务目标作为输入进行规划,同时需要去考虑客户的诉求。业务人员通过获取到的业务需求,进一步的和团队一起将其分解为产品需求。所以业务需求其实是我们真正去发布和运营的单元,它可以被独立发布到我们的生产环境上。我们的产品需求其实就是产品的具体功能,它是我们集成和测试的对象,也就是我们最终去部署到系统上的一个基本单元。产品需求再到了我们的开发团队,映射到迭代计划会上要把它分解为相应的技术任务,包括我们平时所说的比如一些前端的开发、后端的开发、测试都是相应的技术任务。所以业务敏捷要达到的目标是需要去持续顺畅高质量的交付业务价值。 将这几个点串起来,形成金字塔结构。最上层我们会把业务目标放在整个金字塔的塔尖。这个业务目标是通过用户的目标以及北极星指标确立的。确认业务目标后再去梳理相应的业务流程,最后生产。另外产品需求包含了操作流程和业务规则,具需求交付时间、工程时间以及我们的一些质量标准的要求。 谈到用户影响的地图,在敏捷江湖上其实有一个传说,大家都有一个说法叫做敏捷需求的“任督二脉”。用户影响地图其实就是任脉,在黑客马拉松上用过的用户故事地图其实叫督脉。所以说用户影响地图是在用户故事地图之前,先帮我们去梳理出我们要做哪些东西。当我们真正识别出我们要实现的业务活动之后,用户故事地图才去梳理我们整个的业务工作流,以及每个工作流节点下所要包含的具体功能和用户故事。所以说用户影响地图需要解决的问题,我们包括以下这些: 首先是范围蔓延,我们在整张地图上,功能和对应的业务目标是要去有一个映射的。这就避免了一些在我们比如有很多干系人参与的会议上,那大家都有不同想法些立场,会提出很多需求(正确以及错误的需求)。这个时候我们会依据目标去看这些需求是否真的是会影响我们的目标。 这里提到的错误需求,比如是利益相关的人提出的、客户认为产品应该有的、某个产品经理需求分析师认为可以有的....但是这些功能在用户影响地图中匹配不到对应目标的话,就需要降低优先级或弃掉。另外,通常我们去制定解决方案的时候,会考虑较完美的实现,导致解决方案括很多的功能。这个时候关键目标至关重要,会帮助我们梳理筛选、确定优先级。 看一下用户影响到地图概貌 总共分为一个三层的结构: 第一层why,你的业务目标哪个是最重要的,为什么?涉及到的角色有哪些? 第二层how ,怎样产生影响?影响用户角色什么样的行为? (不需要去列出所有的影响,基于业务目标) 第三层what,最关键的是在梳理需求时不需一次把所有细节想全,这通常团队中经常遇到的问题。 我们用这个例子来看一下 这是一个客服中心的影响地图,业务目标是 3个月内不增加客服人数的前提下能支持1.5倍的用户数。此业务目标设定是符合 smart 原则的,specific非常的具体,miserable 是可以衡量的,action reoriented是面向活动的, real list 也是很实际的。 量化的目标会指引我们接下来的行动,梳理一个业务目标,尽量去量化,比如 :我们通过打造一条什么样的流水线,能够提高整个部署的效率,时间是原来的 1/2 。这样才是一个能量化的有意义的目标。 回到这幅图, how 层级识别出来的内容,客服角色:想要对它施加的影响,把客户引导到论坛上,帮助客户更容易的跟踪问题,更快速的去定位问题。初级用户:方论坛上找到问题。高级用户:在论坛上回答问题。通过我们这些用户角色,进行活动,完成在不增加客户客服人数的前提下支持更多的用户数量。 最后一个层级,才是我们日常接触比较多的真正的功能的特性和需求,比如引导到客户到论坛上,其实这个产品就需要有一个常见问题的论坛的链接。这个层次需要我们团队进一步地在交付,在每个迭代之前做进一步的梳理,细化成相应的用户故事。 这个是云智慧团队中,自己做的影响地图的范例,可以看下整个的层级结构。序号表示优先级。 那我们用户影响地图可以总结为:
-
小红书大产品部架构 小红书产品概览--经过性能、稳定性、成本等多个维度的详细评估,小红书最终决定选择基于腾讯云星海自研硬件的SA2云服务器作为主力机型使用。结合其秒级的快速扩缩、超强兼容和平滑迁移能力,小红书在抵御上亿次用户访问、保证系统稳定运行的同时,也实现了成本的大幅降低。 星海SA2云服务器是基于腾讯云星海的首款自研服务器。腾讯云星海作为自研硬件品牌,通过创新的高兼容性架构、简洁可靠的自主设计,结合腾讯自身业务以及百万客户上云需求的特点,致力于为云计算时代提供安全、稳定、性能领先的基础架构产品和服务。如今,星海SA2云服务器也正在为越来越多的企业提供低成本、高效率、更安全的弹性计算服务。 以下是与小红书SRE总监陈敖翔的对话实录。 问:请您介绍一下小红书及其主要商业模式? 小红书是一个面向年轻人的生活方式平台,在这里,他们发现了向上、多元的真实世界。小红书日活超过 3500 万,月活跃用户超过 1 亿,日均笔记曝光量达 80 亿。小红书由社交平台和在线购物两大部分组成。与其他线上平台相比,小红书的内容基于真实的口碑分享,播种不止于线上,还为线下实体店赋能。 问:围绕业务发展,小红书的系统架构经历了怎样的变革和演进? 系统架构变化不大,影响最深的是资源开销。过去三年,资源开销大幅增加,同比增长约 10 倍。在此背景下,我们努力进行优化,包括很早就开始使用 K8S 进行资源调度。到 18 年年中,绝大多数服务已经完全实现了容器化。 问:目前小红书系统架构中的计算基础设施建设和布局是怎样的? 我们目前的建设方式可以简单描述为星型结构。腾讯云在上海的一个区是我们的计算中心,承载着我们的核心数据和在线业务。在外围,我们还有两个数据中心进行计算分流,同时承担灾备和线上业务双活的角色。 与其他新兴电子商务互联网公司类似,小红书的大部分计算能力主要用于线下数据分析、模型训练和在线推荐等平台。随着业务的发展,对算力的需求也在加速增长。
-
41 个下载免费 3D 模型的最佳网站-使用说明:使用权限可能因型号而异。因此,在下载文件之前,请仔细检查每个下载页面上的许可证和使用权限。 17. Clara.io Clara.io 是一个创建 3D 内容的全球平台,也是一个培养新 3D 艺术家的社区。Clara.io 提供+100,000个免费的3D模型,包括OBJ,Blend,STL,FBX,DAE,Babylon.JS,Three.JS格式,用于 Clara.io,Unity 3D,Blender,Sketchup,Cinema 4D,3DS Max和Maya。 使用说明:免费,标准和专业帐户仅供个人使用,如果您需要将 clara.io 用于商业用途,请与销售团队联系。 18. 3DExport 3DExport是一个市场,您可以在其中购买和销售用于CG项目的3D模型,3D打印模型和纹理。它提供15 +不同的3D格式供下载,如3DS MAX(.max),Cinema4D(.c4d),Maya(.mb,.ma),Lightwave(.lwo),Softimage(.xsi),Wavefront OBJ(.obj),Autodesk FBX(.fbx)等。它还提供15种不同的语言! 使用说明:免费下载仅供个人和非商业用途。 19. 3D Warehouse 3D Warehouse是一个开放的库,允许用户共享和下载SketchUp 3D模型,用于建筑,设计,施工和娱乐!任何人都可以免费制作,修改和重新上传内容到3D仓库,您可以找到任何您能想到的东西,如家具,电子产品,室内产品等。 使用说明:3D Warehouse中的所有模型都是免费的,因此任何人都可以下载文件以用于SketchUp甚至其他软件,如AutoCAD,Revit和ArchiCAD。 20. CadNav.com CadNav是CGI平面设计师和CAD / CAM / CAE工程师的在线3D模型库,我们提供超过50000 +免费3D模型和CAD模型下载。在CadNav网站上,您可以下载高质量的多边形网格3D模型,3D CAD实体对象,纹理,Vray材料,3D作品,CAD图纸等。 使用说明:免费下载仅供个人和非商业用途。 21. All3dfree.net 就像网站名称一样,它提供免费的3D模型,还包括Vray材料,CAD块,2d和3d纹理集合,无需注册即可免费下载。它是不断更新的,因此您可以查找或请求3DS,MAX,C4D,skp,OBJ,FBX,MTL等格式的模型。 使用说明:所有资源均不允许用于商业用途,否则您将承担责任。 22. Hum3D 自2005年以来,Hum3D帮助来自3多个国家的80D艺术家节省3D建模时间,并制作逼真的3D模型,用于电影,视频游戏,AR应用程序和可视化。所有模型均由首席3D艺术家进行验证,他们检查其是否符合专业要求和最新的3D建模标准。 使用说明:免费下载仅供个人和非商业用途。 23. Artist-3D.com 艺术家-3D 库存的免费 3D 模型下载按通用类别排序。它为人体解剖学、汽车、家具、火箭、卫星等模型提供 AutoDesk 3DS Max 格式。您还可以在浏览他们的网站时找到教程和类似类型的建模。 使用说明:使用权限可能因型号而异。因此,在下载文件之前,请仔细检查每个下载页面上的许可证和使用权限。 24. Free the models 就像本网站的标题一样,它为3d应用程序和3d游戏引擎提供免费的内容模型。您可以为您的任何项目找到许多有趣且有用的模型!它提供3ds,wavefront,bryce,poser,lightwave,md2和unity3d格式的模型。还有一个很棒的纹理集合,可以在您最喜欢的建模和渲染程序中使用。 使用说明:您从这里下载的所有内容都可以免费使用,除非它不能包含在另一个免费的网络或CD收藏中,也不能单独出售。否则,您可以在商业游戏,3D应用程序或渲染作品中使用它。您不必提供信用,但如果您这样做,那就太好了。 25. Resources.blogscopia 本网站由一家名为Scopia的公司创建。他们制作3D图像和视频,您可以找到许多为CGI工作的信息架构设计的模型,所有这些都可以在现实生活中使用。您可以免费下载它们,但是,如果您想一次下载它们,您可以支付 3 到 9 欧元。 使用说明:您可以免费下载模型部分的所有文件。每个压缩文件都包含您也可以在此处找到的许可证。基本上,您可以对文件执行任何操作。唯一的限制是不归属于Scopia的重新分发。 26.ambientCG 1000+公共领域PBR材料适合所有人!环境CG是使用许多不同的方法和资产类型创建的,例如照片纹理(PBR),贴花(PBR),图集(PBR),照片纹理(普通),物质存档(SBSAR),雕刻画笔,3D模型和地形。您可以在所有项目中*使用它们! 使用说明:在 ambientCG 上提供下载的所有 PBR 材料、画笔、照片和 3D 模型均根据知识共享 CC0 1.0 通用许可提供。您可以复制、修改、分发和执行作品,即使是出于商业目的,也无需征得许可。信用将不胜感激。 不要满足于平庸的大理石纹理 - 立即使用我们的免费PBR大理石纹理升级您的3D设计。 27.Pixar One Twenty Eight 这是一个提供官方动画行业经典纹理的网站:皮克斯,创建于 1993 年,该纹理库包括 128 个重复纹理,现在免费提供。 它包含您来到的纹理,包括砖块和动物毛皮。肯定会有一些你可以使用的东西。 使用说明:皮克斯动画工作室的《Pixar One Twenty Eight》根据知识共享署名4.0国际许可协议进行许可。即使出于商业目的,您也可以重新混合、调整和构建您的作品,只要您以相同的条款对新创作进行信用和许可。 访问数以千计的免费纹理并提升您的设计游戏 - 立即开始下载! 28. 3DXO 即使有近 620 个免费贴纸可供下载,3DXO 也不是最大的资源,但它的内容非常有用,不需要注册。无论是简单的墙壁或地板,还是一些奇怪的小东西,您都需要的纹理都可以在此网站上看到。 使用说明:使用权限可能因型号而异。因此,在下载文件之前,请仔细检查每个下载页面上的许可证和使用权限。 29. 3DModelsCC0 3DModelsCC0 与其他产品的不同之处在于它包含超过 250+ 个高质量 3D 模型,并且本网站上的所有内容都是免费的,完全是公共领域!使用我们的模型时无需信用或归属! 使用说明:为每个人提供完全免费的公共领域内容。 30.Sketch up texture club Sketchup Texture Club是一个非营利性的教育和信息门户网站,由3D社区的图像促进协会管理,特别强调面向学生和建筑和室内设计专业人士的可视化和渲染技术,以及所有正在学习3D可视化的人。 使用说明:您无需支付版税或使用费。纹理可以免费下载和使用。不允许将纹理作为竞争产品出售或重新分发,即使图像被修改也是如此。 31. FlippedNormals FlippedNormal 是一个提供计算机图形和 3D 资产的市场,您可以找到许多用于雕刻、建模、纹理、概念艺术、3D 模型、游戏资产或课程的高级资产! 使用说明:使用权限可能因型号而异。因此,在下载文件之前,请仔细检查每个下载页面上的许可证和使用权限。 32. NASA 3D NASA 3D网站是一个在线门户,提供与太空和各种NASA任务相关的大量三维模型和模拟。该网站是用户友好的,并提供有关每个型号的详细信息。该网站允许用户探索和下载几种不同格式的模型,包括 OBJ、STL 和 FBX,只需单击下载按钮即可。 使用说明: 要下载模型,只需单击模型页面上的下载按钮并选择所需的格式。 33. 3DAGOGO (Astroprint) 3DAGOGO 是一个提供广泛 3D 模型的网站,包括角色、车辆和建筑物。3DAGOGO 的独特功能之一是它专注于适合 3D 打印的模型,使其成为希望创建物理原型或模型的设计师的绝佳资源。要使用 3DAGOGO,设计师只需在网站上搜索他们正在寻找的模型类型,然后下载 STL 格式的文件。 使用说明: 要使用 3DAGOGO,只需搜索所需的 3D 模型类型并下载 STL 格式的文件。根据需要自定义模型,并确保在将其用于商业目的之前检查使用权限。 34. FreeCAD FreeCAD是一款了不起的3D建模软件,可让您在计算机上创建令人难以置信的3D设计。该软件可免费下载和使用,它提供了广泛的工具和功能,可用于创建用于各种目的的3D模型。 该网站易于浏览,您可以找到开始使用FreeCAD的所有必要信息。此外,该网站还提供一系列教程和指南,可帮助您了解 3D 建模的来龙去脉。 使用说明: 要下载模型,请访问网站并从库中选择所需的模型。该网站还提供了一系列使用该软件的教程和指南。 35. Pinshape Pinshape是一个提供一系列3D打印模型的网站。网站上提供的型号质量很高,因此您可以确保您的最终印刷产品看起来很棒。该网站提供了广泛的模型,包括从家居用品到小雕像和珠宝的所有物品。 但这还不是Pinshape所能提供的全部!该网站还允许用户上传和共享自己的3D模型。这意味着您不仅可以下载出色的模型,还可以通过分享自己的设计为社区做出贡献。此外,Pinshape 提供了一系列自定义选项,因此您可以调整和调整模型以满足您的特定需求。 使用说明: 要下载模型,请在网站上创建一个帐户,搜索所需的模型,然后单击下载按钮。该网站还为每种型号提供了一系列定制选项。 36.Yeggi Yeggi 提供了大量免费的 3D 模型,您可以下载各种格式的模型,例如 STL、OBJ 和 FBX。该网站易于使用,您可以按关键字、类别或特定网站搜索模型。 Yeggi 对于任何寻找 3D 模型的人来说都是一个很好的资源。它提供了大量的模型集合,从日常物品到复杂的机械,以及介于两者之间的一切。该网站的收藏量在不断增长,每天都有新的型号增加。 使用说明: 要下载模型,请在网站上搜索所需的模型,然后单击下载按钮。该网站还提供指向托管模型的原始网站的链接。 37. Open3DModel 来自开放3D模型的图像 Open3DModel具有各种类别的模型,包括建筑,车辆和角色。无论您需要建筑物,汽车还是人的3D模型,都可以在此网站上找到。 该网站易于浏览,您可以按类别或关键字搜索模型。每个模型都附带预览图像和详细信息,例如文件格式、大小和多边形数量。此信息可以帮助您选择适合您需求的模型。 使用说明: 要下载模型,请访问网站,从库中选择所需的模型,然后单击下载按钮。 使用最好的 3D 资产管理工具简化您的 3D 制作流程。立即试用它们,将您的 3D 项目提升到一个新的水平! 38. 3DExport 对于那些为其 3D 设计项目寻找 3D 模型、纹理和其他资源的人来说,该平台是一个很好的资源。该网站有大量模型可供选择,包括 3D 打印对象、游戏资产等。用户可以按类别、文件格式或价格范围浏览,以找到适合其项目的完美资源。此外,3DExport 还提供一系列教程和其他 3D 资源,以帮助用户提高技能并创建更令人印象深刻的设计。 使用说明: 要使用 3DExport,只需创建一个帐户并浏览可用型号。您可以按类别、格式和价格进行搜索,以找到所需的型号。找到喜欢的模型后,只需下载它并开始在您的项目中使用它。 39.Blend Swap Blend Swap是一个社区驱动的市场,提供与Blender软件兼容的各种免费3D模型。该平台允许用户共享和下载模型、纹理和其他资产,以便在他们的项目中使用。 使用说明: 创建免费帐户后,您可以浏览社区上传的大量3D模型。当您找到要使用的一个时,只需下载它并将其导入您选择的 3D 软件即可。 40. 3DShook 3DShook 是一个高级 3D 模型市场,提供一系列用于建筑、游戏等各个行业的高质量模型。该平台提供基于订阅的模型,具有不同的定价计划,允许用户访问一系列模型。 使用说明: 注册免费帐户后,只需浏览3D模型库,选择您喜欢的模型,然后以您需要的格式下载它们。 41. Smithsonian X 3D 史密森尼 X 3D 对于正在寻找历史文物和文物的高质量 3D 模型的设计师来说,这是一个独特的资源。该平台提供了大量3D模型,这些模型是根据史密森尼博物馆和研究中心中的真实物体扫描创建的。 使用说明:
-
实战体验:基于云原生技术的DevOps、GitOps、K8S和BPF在生产级麻将游戏服务器上的应用与开发
-
【Netty】「萌新入门」(七)ByteBuf 的性能优化-堆内存的分配和释放都是由 Java 虚拟机自动管理的,这意味着它们可以快速地被分配和释放,但是也会产生一些开销。 直接内存需要手动分配和释放,因为它由操作系统管理,这使得分配和释放的速度更快,但是也需要更多的系统资源。 另外,直接内存可以映射到本地文件中,这对于需要频繁读写文件的应用程序非常有用。 此外,直接内存还可以避免在使用 NIO 进行网络传输时发生数据拷贝的情况。在使用传统的 I/O 时,数据必须先从文件或网络中读取到堆内存中,然后再从堆内存中复制到直接缓冲区中,最后再通过 SocketChannel 发送到网络中。而使用直接缓冲区时,数据可以直接从文件或网络中读取到直接缓冲区中,并且可以直接从直接缓冲区中发送到网络中,避免了不必要的数据拷贝和内存分配。 通过 ByteBufAllocator.DEFAULT.directBuffer 方法来创建基于直接内存的 ByteBuf: ByteBuf directBuf = ByteBufAllocator.DEFAULT.directBuffer(16); 通过 ByteBufAllocator.DEFAULT.heapBuffer 方法来创建基于堆内存的 ByteBuf: ByteBuf heapBuf = ByteBufAllocator.DEFAULT.heapBuffer(16); 注意: 直接内存是一种特殊的内存分配方式,可以通过在堆外申请内存来避免 JVM 堆内存的限制,从而提高读写性能和降低 GC 压力。但是,直接内存的创建和销毁代价昂贵,因此需要慎重使用。 此外,由于直接内存不受 JVM 垃圾回收的管理,我们需要主动释放这部分内存,否则会造成内存泄漏。通常情况下,可以使用 ByteBuffer.clear 方法来释放直接内存中的数据,或者使用 ByteBuffer.cleaner 方法来手动释放直接内存空间。 测试代码: public static void testCreateByteBuf { ByteBuf buf = ByteBufAllocator.DEFAULT.buffer(16); System.out.println(buf.getClass); ByteBuf heapBuf = ByteBufAllocator.DEFAULT.heapBuffer(16); System.out.println(heapBuf.getClass); ByteBuf directBuf = ByteBufAllocator.DEFAULT.directBuffer(16); System.out.println(directBuf.getClass); } 运行结果: class io.netty.buffer.PooledUnsafeDirectByteBuf class io.netty.buffer.PooledUnsafeHeapByteBuf class io.netty.buffer.PooledUnsafeDirectByteBuf 池化技术 在 Netty 中,池化技术指的是通过对象池来重用已经创建的对象,从而避免了频繁地创建和销毁对象,这种技术可以提高系统的性能和可伸缩性。 通过设置 VM options,来决定池化功能是否开启: -Dio.netty.allocator.type={unpooled|pooled} 在 Netty 4.1 版本以后,非 Android 平台默认启用池化实现,Android 平台启用非池化实现; 这里我们使用非池化功能进行测试,依旧使用的是上面的测试代码 testCreateByteBuf,运行结果如下所示: class io.netty.buffer.UnpooledByteBufAllocator$InstrumentedUnpooledUnsafeDirectByteBuf class io.netty.buffer.UnpooledByteBufAllocator$InstrumentedUnpooledUnsafeHeapByteBuf class io.netty.buffer.UnpooledByteBufAllocator$InstrumentedUnpooledUnsafeDirectByteBuf 可以看到,ByteBuf 类由 PooledUnsafeDirectByteBuf 变成了 UnpooledUnsafeDirectByteBuf; 在没有池化的情况下,每次使用都需要创建新的 ByteBuf 实例,这个操作会涉及到内存的分配和初始化,如果是直接内存则代价更为昂贵,而且频繁的内存分配也可能导致内存碎片问题,增加 GC 压力。 使用池化技术可以避免频繁内存分配带来的开销,并且重用池中的 ByteBuf 实例,减少了内存占用和内存碎片问题。另外,池化技术还可以采用类似 jemalloc 的内存分配算法,进一步提升分配效率。 在高并发环境下,池化技术的优点更加明显,因为内存的分配和释放都是比较耗时的操作,频繁的内存分配和释放会导致系统性能下降,甚至可能出现内存溢出的风险。使用池化技术可以将内存分配和释放的操作集中到预先分配的池中,从而有效地降低系统的内存开销和风险。 内存释放 当在 Netty 中使用 ByteBuf 来处理数据时,需要特别注意内存回收问题。 Netty 提供了不同类型的 ByteBuf 实现,包括堆内存(JVM 内存)实现 UnpooledHeapByteBuf 和堆外内存(直接内存)实现 UnpooledDirectByteBuf,以及池化技术实现的 PooledByteBuf 及其子类。 UnpooledHeapByteBuf:通过 Java 的垃圾回收机制来自动回收内存; UnpooledDirectByteBuf:由于 JVM 的垃圾回收机制无法管理这些内存,因此需要手动调用 release 方法来释放内存; PooledByteBuf:使用了池化机制,需要更复杂的规则来回收内存; 由于池化技术的特殊性质,释放 PooledByteBuf 对象所使用的内存并不是立即被回收的,而是被放入一个内存池中,待下次分配内存时再次使用。因此,释放 PooledByteBuf 对象的内存可能会延迟到后续的某个时间点。为了避免内存泄漏和占用过多内存,我们需要根据实际情况来设置池化技术的相关参数,以便及时回收内存; Netty 采用了引用计数法来控制 ByteBuf 对象的内存回收,在博文 「源码解析」ByteBuf 的引用计数机制 中将会通过解读源码的形式对 ByteBuf 的引用计数法进行深入理解; 每个 ByteBuf 对象被创建时,都会初始化为1,表示该对象的初始计数为1。 在使用 ByteBuf 对象过程中,如果当前 handler 已经使用完该对象,需要通过调用 release 方法将计数减1,当计数为0时,底层内存会被回收,该对象也就被销毁了。此时即使 ByteBuf 对象还在,其各个方法均无法正常使用。 但是,如果当前 handler 还需要继续使用该对象,可以通过调用 retain 方法将计数加1,这样即使其他 handler 已经调用了 release 方法,该对象的内存仍然不会被回收。这种机制可以有效地避免了内存泄漏和意外访问已经释放的内存的情况。 一般来说,应该尽可能地保证 retain 和 release 方法成对出现,以确保计数正确。