抖出干货,一句话,不管多大规模、多么复杂,任何Web应用都是立足于Request/Reply的通信模式而解决一个问题,这个问题是,如何把这个Request投送到未知规模的设备集群中进行求解,然后作为Reply返回。这里的Request是逻辑Request,即不单单说HTTP Request,或者是SQL Request,而是Business Request。
好了,以上这段话可以涵盖目前世界上所有接触到的Web应用,从搜索引擎到短视频应用,涵盖所有系统的后端核心思路。
这里具体结合实际情况来展开论述。
首先存在几个来自现实世界中的约束
- 任何的商业都是希望自己的业务规模可以无暂停的无限增长。
- 随着业务量的增长,围绕业务逻辑的计算量也在增加。
- 机器资源总是有限的,包括任何一台设备的IO带宽、CPU、内存、存储等。
对于视频平台的应用来说,其实可以分2大类
- 视频点播类(VOD)
- 实时直播类(Live)
当然一个网站当然可以提供2种服务,但是在实际世界中,这两个类别存在交集以及不同的点。
这里的业务请求逻辑主要分为两大类
- 内容发布者
- 内容观看者
内容请求者的类别又有两个大类
- 预制作内容上传
- 实时流媒体上传
预制作内容上传
这个问题可以归纳为,如何收集完整的用户内容,提供给后续的处理程序。这里的问题是
- 用户不需要理睬数据的流向,只有一个入口。
- 服务器系统必须要保证待处理的数据的完整性。
这里的解决方案可以采用,准备若干强大的高带宽高速网络传输节点。以用户上传请求作为一个Session,根据后端处理节点的资源空闲程度,从前端直接通过Broker输入到某个后端的某处理节点。后端处理节点的特色是,计算能力可以很强,存储空间很大。当用户所有的内容上传完毕之后,则告知处理节点开始处理,同时处理节点发布Session的处理进度,进而前端获取并推送给用户。当处理完毕之后,转码也完成,可以告知后续节点生成永久性的播放地址,刷新CDN,将新通知发往前端。前端刷新一次,获得更新后的网页,直接点击播放。
实时流媒体上传
这个问题可以归纳为,如何把用户持续性的数据分配给内部处理程序进行。
- 用户一般来说有固定的输入点,譬如RTMP的URL。
- 可能需要多协议的支持,譬如WebRTC。
这里一样需要高带宽、兼容某种协议的网络前端节点,作为固定的资源分配给用户,譬如Twitch,每一个注册用户都知晓自己的RTMP URL。每当用户开始发送数据的时候,根据视频带宽和码率的差异,需要从后端分配一个或者共享计算节点进行流媒体的实时编解码。每一个计算节点在计算量允许的情况下可能可以执行若干转码工作处理几路视频。每一个程序的执行各自独立,在处理的过程中会不停的向Broker发送每一个Session的处理状态,同时直接将处理后的原始媒体数据交给后续的处理环节,在这个过程中已经生成了MP4片段,并且可以直接发送给CDN。同时前端的播放器直接不停的抓取最新的生成片段用来播放。
那么所有的短视频应用其实都是属于第一大类,而近年来兴起的网络直播平台如Twitch则属于1+2类。
寥寥几语,已经把这个地方概括完毕。至于用什么多媒体库如FFmpeg、x264做什么的这些内容,都是具体的执行细节,在此不阐述。因为这些都是具体节点的工作逻辑,可以和架构的设计彻底解耦合,成为功能独立的程序,只要稳定执行,就没有问题。至于具体的媒体问题,譬如H264、H265、AV1,AAC音频处理等具体媒体相关的处理,还是HLS或者DASH,本质上这个独立的程序都可以完成。并且这个程序一定可以在不同的硬件环境下通过媒体片段进行测试,获知系统综合性能,进而优化系统的资源利用率和开销。
对于播放来说,虽然也有两大类
- 观看已经录制的视频内容
- 观看正在直播的视频内容
但是对于播放端来说,只是一个Request/Reply抓取数据的过程。其实任何的网络视频应用都是不断的抓取片段,丢入本地的缓冲进行播放。无论是MPEG-Dash还是HLS,本质上都是定义了一组媒体文件序列,由客户端不断的抓取。但是对于播放这一个动作来说,无论是来自VOD还是直播的内容,本质上并没有任何区别,因为数据都是需要处理后按照次序丢入CDN,客户端通过HLS或者MPEG-DASH的索引进行下载。这个地方的设计主要在于客户端的设计和编码,并无过多的技术难度。
抖音类别的短视频,其实都是第1类。快手视频直播是第2类。又有录播又有直播的算1+2,一般是传统视频平台。有没有纯粹属于第2类的呢,当然也有,而且一般应用场合为B2B,非C2C。