写点什么

双 11 猫晚互动前端容器化之路

  • 2020-04-04
  • 本文字数:4013 字

    阅读完需:约 13 分钟

双 11 猫晚互动前端容器化之路

一、猫晚简介

天猫双 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)监控体系要齐全,预案要细化。


作者介绍


阿里文娱前端专家沐南


2020-04-04 18:08932

评论

发布
暂无评论
发现更多内容

从AI作画到AI做视频,这一跳改变了什么?

脑极体

nodejs实现jwt

coder2028

node.js

JavaWeb(一)

Studying_swz

后端 10月月更

ZooKeeper数据模型

穿过生命散发芬芳

zookeeper 10月月更

翟佳:StreamNative 组织构建之路丨声网开发者创业讲堂 • 第 5 期

声网

技术管理 人工智能’

高效能敏捷交付团队反思:特性团队(FeatureTeam)+Scrum

laofo

DevOps 敏捷 研发效能 持续交付 敏捷研发

Java多线程 关闭线程池 shutdown() 、shutdownNow()、awaitTermination()

Yeats_Liao

后端 Java core 10月月更

你的公司需要数据中台吗?

久歌

架构

All Eyes on Docs! 练就火眼金睛,就来StarRocks 极客营

StarRocks

数据库

Linux中的目录结构是什么样的?有人说像“树”,你觉得呢

wljslmz

Linux 10月月更 目录结构

Java注解

急需上岸的小谢

10月月更

深聊Nodejs模块化

coder2028

node.js

JDBC学习

Studying_swz

后端 10月月更

挑战 30 天学完 Python:Day6 数据类型 - 元组tuple

MegaQi

Python 挑战30天学完Python 10月月更

Go 语言入门很简单:Go 语言的错误处理

宇宙之一粟

异常处理 错误处理 Go 语言 10月月更

2022-10-18:以下go语言代码输出什么?A:panic;B:编译错误;C:moonfdd1。 package main import ( “fmt“ “net/url“ ) // 其中

福大大架构师每日一题

golang 福大大 选择题

Go基础数据类型使用实战:int float bool

王中阳Go

Go golang 学习方法 golang 面试 10月月更

Vue组件入门(八)v-model + 自定义参数

Augus

Vue 3 10月月更

java部分基础总结

Studying_swz

java 编程 10月月更

leetcode 380. Insert Delete GetRandom O(1) O(1) 时间插入、删除和获取随机元素 (中等)

okokabcd

LeetCode 数据结构与算法

Go slice切片详解和实战:make append copy

王中阳Go

Go golang 学习方法 #go 10月月更

你用Go写过中间件吗?带你用Go实现【操作日志中间件】

王中阳Go

golang 高效工作 学习方法 #go 10月月更

【资损】知名金融企业的资损与资损防控

小明Java问道之路

架构 安全 金融科技 10月月更 资损

抢滩东南亚,融云IM助力应用抓住经济转型红利

融云 RongCloud

互联网 数字化 IM

改变线程状态的方法

急需上岸的小谢

10月月更

如何实现多个Git仓库同步

Appleex

git

日志管理与分析系统的基本功能

阿泽🧸

日志管理 10月月更

画一个冰糖葫芦祝大家甜甜蜜蜜

急需上岸的小谢

10月月更

让Jenkins执行GitHub上的pipeline脚本

程序员欣宸

GitHub jenkins 10月月更

Zebec 以 Layer2 的形式推出 Zebec Chain,流支付新时达来临了

西柚子

Java多线程 线程池的生命周期及运行状态

Yeats_Liao

后端 Java core 10月月更

双 11 猫晚互动前端容器化之路_文化 & 方法_阿里巴巴文娱技术_InfoQ精选文章