一、猫晚简介
天猫双 11 狂欢夜,以下简称“猫晚”。晚会有丰富的节目以及多样的互动,用户可以在互动中得到双 11 所需的购物权益。在这三年中,互动也从简单的 H5 互动逐渐演变成为依赖 Weex、 H5、游戏引擎的多样互动。
二、互动技术挑战
1. 多平台同时直播
2019 年猫晚在优酷、淘宝、天猫同时播出,同时附带了 13 种互动,其中不乏“叠叠乐”等流程复杂的游戏。开发会面临两个问题:
a)渠道多、平台多。如何保证多平台开发效率且体验一致?
b)互动类型多,每个互动都有独立逻辑,直播间需要将所有互动做串联。这些看似独立又有关联的互动,如何能高效、健壮地落地在不同平台呢?
2. 年年创新、迭代速度快
我们需要在既定的时间内,实现快速迭代,并且要保证用户的良好体验。那么又会碰到一些问题:
1)迭代速度快。开发期只有几个月,客户端发版节奏无法满足。如何处理“发版”“快速迭代”这两个互相冲突的要求?
2)PC 端、H5 如何跟上移动端的脚步?
3. 如丝般顺滑的体验
“双 11 天猫狂欢节”的品牌有多响亮,“猫晚”同时在线人数就有多高。人数多就等于“机型多”,每年做猫晚几乎什么型号的手机都能碰到。
从服务端的角度来看,高同时在线就意味着服务端需要承担更高的 QPS,部署更多的机器。又会引出几个问题:
a)同时在线高的情况下,如何保证每个用户的体验?
b)高并发下如何保证服务稳定?
三、技术策略
为了更好的解决上述问题,我们提出了组件化、容器化方案。同时针对一些用户体验,从技术方面进行了优化。
1. 组件化
需要在优酷、淘宝、天猫至少三个平台同时落地互动,的前提下如何保证同时进行多个平台开发的效率呢?
1)互动组件化
经过需求分析发现,每种互动其实是个较为封闭的环,每种互动都在内部有套独立的逻辑。
那是不是可以使用“组件化”的思想把不同互动拆分成“互动组件”然后分配出去,让每个开发只负责某一种或几种互动,通过内部 NPM 分发,在不同平台统一依赖这些“互动组件”,最终组装成直播间。
2)抹平平台差异
组件化要想同时运行在多个平台上,就要处理平台差异,有两种选择:
a)组件适配不同平台;
b)统一标准,平台去兼容组件。
两种方案没有好坏之分,但由于今年猫晚有着多达十多种互动模式,为了减少适配的工作量,选择了第二种方案。
我们在平台上实现了一套“适配框架”,抹平不同平台的差异,它主要有三个职责:
a)提供标准化 API,整合容器能力;
b)提供标准化数据模型,不同平台组件可以获取相同的数据;
c)提供节目单与互动服务通信,获取数据,控制互动组件的渲染逻辑。
这样,互动组件只需要对接“适配框架”,无需关心平台。
3)组件标准化
决定“适配框架”方案后,就需要统一组件的整个生命周期,使得每个组件都有统一的标准。在此基础上,我们提供了统一的“脚手架”,把控组件从创建到部署的过程:
a)自动化创建组件托管仓库;
b)自动生成初始化目录和模版;
c)统一编码风格,统一 ES 版本;
d)提供开发调试能力;
e)自动化部署 NPM。
4)方案
跨平台输出效果
2. 容器化
每年的用户诉求都有所不同,每年的产品方案也在变化,必须要做好充足的准备。我们使用“容器”支撑不断变化的需求。
1)热更新与选型
客户端依赖版本发布、用户更新的策略来分发,比 H5 的分发效率低。但使用 H5 在移动浏览器环境下渲染复杂互动,会遇到性能瓶颈。选型方面,我们需求:
a)热更新
b)高性能渲染
c)前端可以轻松上手
框架上我们选择了 Weex,引用一则 Weex 官网的介绍:
Weex 致力于使开发者能基于通用跨平台的 Web 开发语言和开发经验,来构建 Android、 iOS 和 Web 应用。简单来说,在集成了 WeexSDK 之后,你可以使用 JavaScript 语言和前端开发经验来开发移动应用。
Weex 最终渲染的是 Native UI,性能上要优于浏览器渲染。借助 Weex 的渲染远程 jsBundle 的能力,实现实时更新。
Weex 的渲染引擎与 DSL 是分开的,在 DSL 选型上有两个选择 Rax 或 Vue,考虑到阿里集团内复用性上,选择了 Rax。Rax 在几届双 11 中也有很好的表现。同时,我们也保留了 Webview,渲染一些 H5 游戏。
2)容器化的能力
Weex 有两种方式来扩展能力:
a)Module 可以封装一些接口,调用原生能力;
b)Component 可以使用原生实现 Weex 组件。
有了手段以后,容器能力需要封装到哪种程度?有两个选择:
a)提供完整的业务组件,开箱即用。业务只需摆放位置,拼装;
b)只提供基础能力,业务需要在此基础上实现业务逻辑。
显而易见,想要支撑不断变化的需求,容器的能力不能太定制化。所以我们选择了第二种方案:
a)在 Module 方面,容器提供了包括“流媒体、下载、相册、通信、埋点、键盘、支付、屏幕旋转”等 31 个 Module,给容器扩展出近几十种原生能力;
b)在 Component 方面,封装了“Webview、播放器、动画、进度条、聊天列表、弹幕”等 18 个 Component,扩展出了一些通用的 Native View,提高渲染性能。
最后,我们抽离了直播间逻辑。使播放,通信等基础功能功能可以单独剥离出来,做为“直播间基础逻辑”,业务层可以选择继承方式来扩展自己的能力。
3)模版,创造更多的搭配
在日常的业务中,容器需要支撑多种多样的直播。有普通直播,也有猫晚这种大型互动直播。
我们在容器中增加了“模版”的概念,把模版和直播类型建立起关系,通过不同的模版来支撑不同类型的直播。例如猫晚直播间会渲染“2019 猫晚模版”,展现给用户相应的界面。在模版加载过程中,加入了提前推送 Cache 的能力,使得大部分用户可以直接从本地加载模版,大大加快了首屏渲染的速度。
4)输出到多终端
搞定了移动端后,我们还需要处理 PC 和 H5,每个终端单独开发有些费时费力。在多端输出方案上,容器借助了 Rax 的跨平台渲染能力。剥离了组件的样式和业务逻辑,使得各终端可以共用一份业务逻辑,然后实现不同的样式,最后分别构建后运行在各终端的容器中。
5)方案
最终形成了容器化的方案:
最终渲染结果:
3. 体验优化
在保证了产品需求落地后,还需要考虑如何保证互动有“丝般顺滑”的体验,下面介绍其中几个优化方案。
1)互动游戏秒开优化
今年双 11,用户在直播间内和现场进行了游戏互动。互动开始后,会进入选队阶段,用户在此阶段可以选择自己喜欢的队伍。选队阶段结束后,线上会和现场连线,一起进行一次互动游戏。
游戏本身是依赖 H5 游戏引擎实现的,代码体积较大。在浏览器环境中,会遇到加载速度的挑战。网络层面上,每个用户网络环境不同,必然有网络不好的情况出现。用户可能会等待很长时间才能玩到游戏,体验非常不好。
我们来看一下游戏加载的流程:
可以看到,服务器会在“选队阶段”开始一段时间后,发送“选队结束”的信号,让所有用户停止选队。等待晚会现场可以进行游戏后,会发送“游戏开始”信号,客户端会拉起 webveiw 面板去加载游戏。
有两个阶段用户无法操作互动,需要等待。一个是“选队结束”信号收到后,直到收到“游戏开始”信号。随后会拉起 webveiw 面板;另外一个是“游戏开始”信号收到后,直到游戏加载成功。
第一个阶段服务器发送“选队结束”、“游戏开始”这两个信号之间所需时间,是依据晚会现场的节奏,这个优化空间比较小。
第二个阶段,游戏本身会做一些资源压缩,资源整合,可以从体积层面提高游戏加载速度。但是这也有局限性,游戏的图片、特效等很丰富,优化后的资源体积也是远远大于普通 H5 页面的,再叠加游戏初始化耗时,在普通网络环境下无法做到“秒开”。
在“空间”层面上,我们无法再优化的情况下,我们是否可以从“时间”层面上做一些优化?从上面的流程图中可以看到,选队结束后,就已经可以做游戏的加载初始化工作了。随后游戏初始化完成,收到“游戏开始”指令后,只需拉起面板即可。这样游戏就会是提早准备好,大大缩短了等待时间。
2)互动与视频对齐
晚会虽然是同步直播给用户的,但综合每个用户的网络情况以及客户端解码性能,每个用户在同一时刻看到的画面是不同的。以“互动开始”信号为例,“互动指令”是在主持人说出“开始”等关键信号时,下发给客户端。
“视频”和“互动”是两条互不相干的链路。我们把用户看到“视频画面”的时刻记为 T1,看到“互动”的时刻记为 T2。可以看出,“T1”与“T2”是没有任何关系的,除非凑巧,理论上用户是无法在看到“主持人喊开始”时,同时看到相应的互动。这样就会缺失“现场感”,互动直播的质量会大打折扣。
那如何让用户看到相应视频时,同时看到相应互动呢?
视频编码中的 SEI(附加增强信息),可以附带一些自定义数据。如果使用 SEI 附带互动标识,真正的互动数据则提早一些下发到客户端。互动可以实时监听解码视频时的 SEI 标识,发现当前互动的标识时,执行相应的操作。
这样用户就会在看到“主持人喊开始”时,同时看到相应的互动展示,就有了“现场感”。
3)高并发下的服务端稳定性优化
在互动开发中,避免不了客户端与服务端做一些数据的通信,其中又有许多,是程序自动触发的。尤其在互动直播场景下,用户会集中在某个时间段内做一些操作。QPS 监控上,往往可以看到一根尖刺,请求时机都比较集中。同时在线只有几千个人的情况下,没有什么优化的价值。但是如果像猫晚这种百万级别同时在线的互动直播中,就很有优化的必要了。
这样会带来几个好处:
a)可以大大降低 QPS,减少部署工作成本;
b)减少集群机器数量,节省开支。
同时在线越高,这些好处就越明显。在开发大型直播互动时,提前要建立起流量评估模型,方案细化到每一个接口。如果一些请求过于集中,就通过一些手段打散掉(在一个时间段内取一个随机时间点,发送请求)。后续演练场次里面,不断地验证模型的准确性。如果有不符合的地方及时修正。
四、大型直播互动经验
最后分享在参与大型直播互动中的经验:
a)技术设计、选型,以稳定性为标准,客户第一,保证用户权益、用户体验;
b)多进行演练,并且搜集数据,重点分析预期外指标,调整对应技术参数;
c)多平台统一架构,一套代码,多平台部署,保证一致性;
d)建立流量评估模型,消峰策略,降级策略;
e)监控体系要齐全,预案要细化。
作者介绍:
阿里文娱前端专家沐南
评论