Java互联网架构-直播互动平台高并发分布式架构应用设计

概述html

网页HTML 静态化: 其实你们都知道网页静态化,效率最高,消耗最小的就是纯静态化的 html 页面,因此咱们尽量使咱们的网站上的页面采用静态页面来实现,这个最简单的方法其实也是最有效的方法,可是对于大量内容而且频繁更新的网站,咱们没法所有手动去挨个实现,因而出现了咱们常见的信息发布系统 CMS,像咱们常访问的各个门户站点的新闻频道,甚至他们的其余频道,都是经过信息发布系统来管理和实现的,信息发布系统能够实现最简单的信息录入自动生成静态页面,还能具有频道管理,权限管理,自动抓取等功能,对于一个大型网站来讲,拥有一套高效,可管理的CMS 是必不可少的,除了门户和信息发布类型的网站,对于交互性要求很高的社区类型网站来讲,尽量的静态化也是提升 性能的必要手段,将社区内的帖子,文章进行实时的静态化,有更新的时候再从新静态化也是大量使用的策略,像Mop 的大杂烩就是使用了这样的策略,网易社区等也是如此同时,html 静态化也是某些缓存策略使用的手段,对于系统中频繁使用数据库查询可是内容更新很小的 应用,能够考虑使用 html 静态化来实现,好比论坛中论坛的公用设置信息,这些信息目前的主流论坛都 能够进行后台管理而且存储再数据库中,这些信息其实大量被前台程序调用,可是更新频率很小,能够 考虑将这部份内容进行后台更新的时候进行静态化,这样避免了大量的数据库访问请求;程序员

图片服务器分离: 对Web 服务器来讲,无论是 Apache,IIS 仍是其余容器,图片是最消耗资源的,因而咱们 有必要将图片与页面进行分离,这是基本上大型网站都会采用的策略,他们都有独立的图片服务器,甚至不少台图片服务器,这样的架构能够下降提供页面访问请求的服务器系统压力,而且能够保证系统不 会由于图片问题而崩溃,在应用服务器和图片服务器上,能够进行不一样的配置优化,好比 apache 在配置 ContentType 的时候能够尽可能少支持,尽量少的 LoadModule,保证更高的系统消耗和执行效率;算法

数据库集群和库表散列: 大型网站都有复杂的应用,这些应用必须使用数据库,那么在面对大量访问的时候,数据库的瓶颈很快就能显现出来,这时一台数据库将很快没法知足应用,因而咱们须要使用数据库集群或者库表散列,在数据库集群方面, 不少数据库都有本身的解决方案, Oracle, Sybase 等都有很好的方案,经常使用的 MySQL 提供的 Master/Slave 也是相似的方案,您使用了什么样的 DB,就参考相应的解决方案来实施便可,上面提到的数据库集群因为在架构,成本,扩张性方面都会受到所采用 DB 类型的限制,因而咱们须要从 应用程序的角度来考虑改善系统架构,库表散列是经常使用而且最有效的解决方案,咱们在应用程序中安装 业务和应用或者功能模块将数据库进行分离,不一样的模块对应不一样的数据库或者表,再按照必定的策略 对某个页面或者功能进行更小的数据库散列,好比用户表,按照用户 ID 进行表散列,这样就可以低成本 的提高系统的性能而且有很好的扩展性,sohu 的论坛就是采用了这样的架构,将论坛的用户,设置,帖 子等信息进行数据库分离,而后对帖子,用户按照板块和 ID 进行散列数据库和表,最终能够在配置文件 中进行简单的配置便能让系统随时增长一台低成本的数据库进来补充系统性能;数据库

核心需求apache

先说一下这个核心需求为何会出现。你们在看移动直播的时候,若是有人关注的话,会发现那些主播常常问的一句话就是“卡不卡,是否是又卡了,我要疯了,又卡住了”。大家看点播的时候,看短视频的时候,不会有人这么问吧?不会说大家看短视频,它又卡了,这种问题是最近才出现的。真正的客户都已经返回这种问题了,说明流媒体的门槛又变高了,因此他们对流媒体的需求是在增加的。那咱们就看一下这些需求都有哪些。编程

一、首先内容产生方就是推流端,如今主流的IOS、安卓,IOS比较简单,就是那个几个机型,基本你们适配都很好。可是安卓的碎片化是很是严重的,大量的精力都须要作对安卓的适配,并且软编耗电量广泛很是高,手机用了一会就会发烫,都担忧会不会爆炸。用户体验就是在不一样的网络状况下,上传的视频有可能会卡,有可能不连贯,报各类各样的错误,这个是做为一个开发者他本身不可能去适配的。说白了从用户那边提的需求就是推流端不能卡,画质要好,不能太烫,这是咱们接触到的客户真正提的问题,是咱们从有点偏技术的角度抽取出来的,它背后对应的是哪些事情。后端

二、而后是分发网络。分发网络其实躲在一个很后面的地方,用户其实看不见的。真正对分发网络提需求用户也提不出来,因此基本这部分需求都会提给播放端,提的需求也是不能卡,不能花屏,首屏必定要快,一点就要看到,还不能把延时弄的太大。其实这些不少都是和源站分发网络有关系的,只是用户看不到这个需求会跟后面的播放器接在一块儿。浏览器

对这个需求咱们作一些抽象来讲就是用户的可触达性要好,咱们的CDN节点要在全区域、全运营商有覆盖,包括教育网。有不少人,像那些小运营商都会忽视教育网,咱们也遇到过这样的例子,教育网确实很差接,由于节点不够多,这其实不是什么难点,只是一个坑,注意到了就能作到。低延时的操做大部分来自端的配合,服务端只要是作好缓存,保证这个数据是连贯的。若是要丢数据的话,把关键帧保留好,丢GOP中间那些PB帧,主要是在端上会收到。缓存

首屏时间,就是用户点开就要看,之前那些开源架构就是rtmp server,它是作不到一点开就能看的,如今一些开源的国内资源写得也比较好了,能够看到。咱们是本身开发的,因此也花了一些工做,能保存以前的关键帧的信息,用户一点开就能看,这个就是很细节的东西了。若是这个作很差的话,会黑屏、绿屏,或者是半天看不着图像。安全

三、在播放器这边也是咱们在接业务的时候,遇到用户投诉最多的,由于全部的问题都是在观看的时候体现的,全部的雷都得是播放器的同窗去扛。这个需求也是不能卡,不能延迟过高。若是延迟高了,要追回来,追的时候声音不能变,最好是追的策略也能本身控制,这是用户真正提出来的需求。

对于咱们来讲,要知足这些需求,咱们须要作好多分辨率的适配,保证好流畅性,保证好咱们追赶的策略不会出现任何异常。因此这三个端不少是相互耦合的,像推流和分发在一块儿,要保障好用户的流畅性和画质,分发和播放器在一块儿要保证好低延时和播放的流畅。全部的这些需求里共同的一点就是不能卡,后面咱们在设计方案的时候,也是重点考虑怎么能作到不卡。

解决方案

这个是咱们这边的系统架构图。最下层是依托金山的云服务,由于咱们已经有了很好的平台,提供了咱们计算资源,提供了存储,提供了不少自建的节点,固然还不够多,咱们仍是个融合CDN,而后提供了数据分析的能力。咱们依托它作了橙色的这一层,就是咱们本身的核心,流媒体直播,而后围绕这个核心咱们再作的回看点播、在线转码、鉴权、内容审核。

为何要作回看点播?由于这不是一个短视频录播的项目,而是一个直播,直播就决定它的并发不会很高,内容不会不少,热点比较少。若是你不回看的话,用户很难维持它的日活,很难维护用户黏度,因此用户必定会要求作回看的。

为何要作在线转码?推流端其实作了不少把更好的画质想尽办法传上来的工做,投了不少人力来作。传上来以后,观看也在移动端,它不必定看得了。若是他看不了怎么办?咱们就须要在线转,在线转码其实承担的更多更重要的事情。

鉴权,用户都不想被盗链,尤为是推流的时候,若是我不鉴权,谁均可以来推,推个法lun功怎么办?这是必需要有的。内容审核,如今咱们没有办法帮他作到自动审核,技术还不够。如今作到的是截图,按用户指定的时间按期截图,这样的话,用户就能够请一些外包来看是否是有敏感内容,是否是要下线,这个对于如今这种三四秒延迟的直播来讲很是重要。你作不到的话,没准政策因素你就作不下去了。

数据分析一部分是依托金山已有的,一部分是咱们本身作的,由于咱们延迟性,时效性要求更高。客户会常常大半夜忽然提出一个主播看起来特别卡,问你为何,要是像之前那种方式,一个小时生成报表,而后出体验图,告诉他为何卡了,客户可没有这个耐心。

咱们如今基本能作到5秒间隔就出以前的各类问题定位,这个定位包括从源站收集的数据画的曲线。还有从端上,若是端上用户容许的话,推流和拉流端咱们都会有上报数据,几个曲线一拟合,咱们就知道问题出在哪里。因此如今不止是RD能够来查这个问题,咱们不少售前都在承担着帮用户出这个图的工做。

这个是介绍业务具体的流程图,这个流程图并无什么特别,只是通常的流媒体的数据走向、各类请求。可是其中有一些坑我能够跟你们重点说一下,首先看一下直播发起流程,这确定是由应用向本身的服务端去请求一个推流地址,这个推流地址他就用来向咱们的流媒体服务器推,而后咱们给它鉴权。

鉴权以后,它能够在参数里选择是否是要录像。若是须要录像截图,或者须要HLS的分发,咱们均可以帮他作,作完以后存到咱们的存储里,这也是后面会提到的,咱们各个业务之间在作隔离、分不一样的优先级,这种后端的多媒体的处理尽可能都会依赖别的服务,而后就是正常的结束流程。

这个是实际中遇到的一个问题,如今作流媒体,用户推流,他想知道这个流结没结束,通常互联网公司作云服务都怎么作?都是给回调,若是这个推流结束了,我来回调业务方,让业务方知道我结束了,你能够作你的逻辑了。

但实际操做中咱们遇到了问题,就是业务方的服务器没那么可靠,咱们可能过去时间特别久,有延时,有丢,或者他们的服务稳定性咱们也确认不了,这其实就是一个双方的耦合了。并且它的服务器,因为是咱们来调,它的鉴权功能没有办法作得很复杂,他本身的服务器也存在安全漏洞。若是有人来攻击他的话,他的整个业务流程的状态全是乱的。

在试了几家客户以后,咱们就改为另一种方式,也是你们广泛都接受的,就是由APP和本身的Server发心跳,若是APP的网络不异常的话,它本身结束它的Server确定是知道的。若是异常的话心跳断了,他也会判断出是结束了的。并且咱们这边源站服务也会保证,你5秒钟没有数据就必定是结束的了,咱们会把你的流给踢掉,这样就能达到用户的业务状态也是稳定的,咱们的流媒体服务也是稳定的,并且耦合也会比较少。

这是咱们实际遇到的一个坑,这个其实不难,只是看如今广泛云服务提供商还都是在用回掉的方式,因此我特别提一下另外还有一种可选的方式,效果更好。

播放的流程,播放器会先向他本身的服务请求播放地址,而后来咱们这拉流,能够是鉴权也能够不鉴权,取决于它的业务形态。若是拉流失败,咱们有一些定制化的操做,他用RTMP来拉流的话,咱们会告诉他具体是什么错,包括鉴权失效,鉴权参数错误,仍是这个流有问题,咱们都会在状态告诉他的。这是以前用户提到的需求,说是播放须要知道哪里出了问题,因此咱们尽可能把状态码都特别详细的返回给用户。包括咱们原站也有查询接口,若是他须要那种统一查询也能够来查。

一、推流端实现方案

这是推流端的实现,推流端设计的原则总结下来就是自适应,推流谁均可以作,开源的也不少。可是为何有的作得好,有的作得很差呢?就是看自适应作的好很差。

总结下来有三点自适应,一个是帧率和码率自适应,这是你们都能想到的。我推流,若是网络卡了,我就降点帧率或者降一点码率,把这个事情作好,把流能正常推上去,不要卡顿。也是这张图里画到的,在发送网络的时候,咱们作了一个QS模块,咱们团队除了作工程化的人以外,还会有四五个博士专门作算法的。

在这里就有一些体现,咱们在码率自适应的时候,是直接能够回馈给编码器的,让编码器动态调整本身的码率,尽可能保证质量无损,传出来的视频码率降低,视频平滑。帧率的控制就比较简单了,当咱们发现网络卡顿了,咱们就会反馈给帧率控制模块。

在采集的时候作一些丢弃的操做,目的就是把咱们发送的带宽降下来。这个咱们是基于TCP作的,确定没有UDP的效果好,UDP是咱们下一步的尝试,如今尚未开始。由于UDP还涉及到源站的一些架构重构,咱们尚未来得及作,如今基于TCP的效果其实已经不错了。后面除了这种简单的自适应以外,咱们还加了一个算法类的,那个效果就会更明显。

第二种自适应是软硬自适应,这个很好理解,像硬件编码的优势就是手机不烫,缺点一大堆,用MediaRecorder的话,音视频很难同步,用MediaCodec的话,版本兼容有问题,如今还不太好普及。用软编的话码率低,画质好,除了CPU特别烫,别的都是优势。

怎么能把这两个结合起来?咱们如今在作的一些策略性的东西,这个就是个体力活,就咱们在本身这边来配置黑白名单,有一些Top50到Top100的高端机型咱们用人来测,性能没有问题的话,咱们就上软编。由于刚才也听到了软编都是优势,除了烫。

热门机型有一些低端的,软编受不了的就改为硬编。由于硬编是体力工做,因此适配的机型确定是有限的,没有谁敢保证可以全平台、全机型适配硬编,因此下面的一些非热门机型,咱们来不及适配就软编。这样作下来的话,基本能达到99%以上的适配率。在一些大用户那边已经验证过了这个数据。

第三个自适应,算法自适应。咱们是真正的第一家可以把h.265作成商业化的公司。如今全部的都在提h.265,不知道你们对h.265了不了解,有没有人据说过h.265能够商业化在Web端无插件播放?咱们如今作到了在赛扬机器上能够播30FPS的720P视频,在浏览器上不用装任何插件,这是咱们持续优化的结果。固然这个不适合移动的场景,是咱们在接另一个场景的时候用到的。

在移动端咱们作到了IOS手机720P编码,作到15FPS,而后CPU不会打满,多是50%到70%之间。以前数据是打满一个核。这是由于咱们以前有不少作算法的团队,最开始是作技术受权,后来想在一些产品上落地,移动直播实际上是h.265的一个很好的落地的场景,为何这么说呢?

推流端的任务是把更好的画质推上来,网络有限的状况下,我怎么能推上来更好的画质?h.265相对h.264来讲能把带宽省掉30%。30%的概念是在视频点播类的应用里能省点钱,在初创应用来讲根本就不在意,由于主播更贵,谁在意这样30%的带宽。

可是在移动推流就不同了,30%是从480P到720P的变化,就是你原本只能推480P上来的画质,通过h.265这种编码以后能推上来720P的,主播的需求就是网络够好,CPU够好,我为何不推更好的视频上去呢?这就是h.265的一个场景,我用算法的优点,你的机器只要可以让我作到用265来自适应,我就能够推上去更好的画质。

二、分发网络-多集群源站设计

分发网络是躲在很远的一个地方了,咱们当时设计的三个原则就是高并发、高可用、系统解耦,前两个很虚了,只要是作系统都会想怎么高并发,怎么高可用,怎么横向扩展最容易。

咱们作了一个多源站,相对于不少公司在作单源站的方式,咱们就是为了让用户能更好的触达咱们的网络。在各个集群、各个城市作了多源站,如今不光是国内有几个点,在香港和美国咱们也各作了一个点。这样怎么能作到横向的扩容和数据与业务中心的隔离,是花了一些心思的。这种方案并非很难,用一些存储作好同步其实也作到了。

高可用,就像DNS这种,保证服务单点的,高可用都能作到。怎么作到系统解耦,由于传统的CDN只是负责流媒体的分发,咱们相对于它的优点就是咱们除了作流媒体分发之外,还作了不少多媒体的功能,像截图、录像、转码、多分辨率适配这些东西,这些东西是会影响系统稳定性的。怎么能在这里作到真正的解耦,保证系统稳定是下了不少工夫的。

一些开源服务,也作多分辨率适配,可是它全部的转码调度都是由它的流媒体服务来调起的。包括转码的生命周期也是流媒体服务来控制的,他们都在同级部署。其实这是有很大问题的,多分辨率适配和原画的推送和分发彻底不是一个优先级的服务。作系统定级的时候就应该把它们分离开,应该分离在不一样的系统来作。

多集群源站就是刚才说到的,尽可能用三线机房,或者BPG机房,而后在各个城市南北都布点,尽可能的更近的触达用户,让用户推流更容易。同时咱们在每一个源站都部署了金山云的存储,KS3。

部存储的目的也是为了可以更好的保证用户截图和录像的文件的可靠性,存下来以后咱们就无论了,交给KS3,固然KS3多媒体服务也是咱们维护的。作转码截图,或者是转分辨率合并一系列操做,是由另一套系统来作,咱们把这些多媒体的服务和源站的服务作了解耦。

在线转码是一个很是耗CPU的业务。一台如今很高端配置的24核机器,若是我想转一些画质比较好的视频,每一个视频转三个分辨率,这样我转八路就把它打满了,这是很耗CPU的。若是我转了没人看,这个CPU就在那耗着,并且这个是不适合和源站混部的一个服务。

转码要和数据离的近,在那个源站集群的同一机房,咱们会申请一些转码的资源,而后由核心机房来统一调度。咱们把调度和具体的功能分离开,根据你这个流推到哪,咱们就就近在哪里转码。转码也加了一些实时转码的策略。

为何要作在线转码?由于推流端已是尽最大努力把最好的画质、最高的带宽传上来。可是播放端不必定看得了,这样咱们就须要把它转出来,并且h.265虽然好,可是有个最大的问题就是在移动端的浏览器上没有办法播。分享出来的必须是h.264,要否则去微信或者是QQ浏览器,你是看不了的。

就是若是我用了很高深的技术手段,把你的h.265的视频推上来了,画质很好。但不在咱们端上就看不了,你要想分享的话,咱们能够帮你转出一份h.264的来分享。转码是一个高CPU占用的场景,若是我不对CPU作合理的分配的话,很快个人机器资源就会被打满。

咱们作了两种策略,一种是有限的机器合理调度。咱们的转码系统是个分布式,流水线式的,相似Storm那种系统,可是咱们本身作得更适合转码。任务进来以后,咱们第一个流程不是转,而是分析,看看你是要转成什么样,你是什么画质,大概会用什么CPU。

若是你的CPU占用不少,我会认为这是一个很难再次被调度的服务,好比你一下进来一个占四个核的转码服务,后来再来一堆占一个核的,确定是一个核的比较好调度,这个机器资源紧张了,我能够给你调度另一台机器,或者另一台机器原本就有些空余,如今剩三个核,我接不了四个核的,我只能先接一个核的,因此咱们会按优先级,优先分配高CPU占用的任务,而后才是低CPU占用的任务,在流式系统里,会在预分析以后把不一样的任务扔进不一样的优先级队列,这个优先级队列就承担着去转不一样分辨率视频的职能。

并且在后头若是须要降级容灾的话,也是靠这个优先级队列来解决的,每一个用户会有配额。我刚才说24和准24路,其实对于一个云服务公司来讲这个量过小了。像我以前在百度作媒体云的时候,天天转码量是有30万,我以为一个业务作大了,一天30万的转码量是很正常的。

这是考验并发的一个项目,怎么能作到尽可能的把CPU打平,由于波峰波谷很明显。像h.265这个场景,咱们是作了一套实时转码,有人分享就马上给你转,让用户一旦开始分享的时候,能达到秒开的做用。可是你不看的时候,咱们会有策略尽快帮你停下来。由于这种分享出去的视频并非一个高并发的业务,有人看咱们才给他转是个比较合理的场景。

对于那些低分辨率的如今也在逐步上灰度,不是说全部的你分发了,你发起了,我都给你转,咱们会逐渐判断,有人看咱们才转,尽可能节省系统资源。后面也会考虑存储资源,由于每一个机房都会有存储,存储是彻底不用CPU的,它保证的是磁盘和IO,和咱们彻底是资源不复用的,是能够混部的,后面咱们会考虑一步一步的混部。

CDN的分发环节,分发环节其实有不少东西是须要播放来配合的,好比说如今推流为了保证画质好,我会增长B帧,加大GOP,这样编码出来的视频质量会变好,代价就是我增长了GOP,那个人延迟就会大,用户必定是从上一个关键帧开始看,这样他看到的可能就是5秒甚至是10秒以前的视频,这个对社交类的移动直播是不可忍受的。既然有这种需求,源站就须要把以前的都保存好。可是怎么能让延时被消化掉,就要靠播放端。

三、播放器端实现方案

这是播放端的实现框图,中间少画了一个地方。这就是个传统的播放器框图,没有体现出咱们的核心的技术点,数据从网络接收进来以后,通过RTMP的Demux以后,咱们是有一个模块的,这个模块会去判断当前视频是否须要被丢弃,这个原则也和咱们接收缓存有关系,咱们缓存配的是两秒,若是超过两秒,或者超过某一个其余的阈值的话,咱们会开启丢弃的模式。

这个丢弃有多种策略,有的是直接丢掉帧,有的是快进。若是作过播放器就会知道,传统的视频追赶通常都是在视频解码以后来作追赶。解码就意味着会耗CPU,尤为是如今若是我想播720的视频,光是解码就基本上勉强实时的话,根本就没有什么追赶的余地了。

因此咱们在算法上作了一些优化,咱们拿到这个视频的时候会先去判断它是否是一个能够丢的,若是它是能够丢的,在解码以前咱们就丢,可是这样丢会出问题,由于解码器会内部不连续,一旦解码器内部不连续了,它可能会产生黑屏,因此咱们即便要丢,也是在解码器里边作了一些定制化的开发,仍是把要丢的视频传进去,让它本身来丢,它不去解,这样就能达到更快速的把这个视频丢掉,遇上如今的实际主播的进度。

这样的话,若是咱们网络情况很好,不担忧之后抖动的话,咱们能作到从推流到观看是2秒的延迟,可是通常咱们都控制在4秒,就是为了防止抖动产生。

刚才说的是丢的这种逻辑,若是想快进,相似斗鱼那种,在一点进去以后,开始画面是很快过去的,可是没有音频,咱们如今在作有音频的方式,视频在快进,音频也在快进,这样的话声音会变调,由于采样率变了。之前在作端的经验的时候,也作过这种变速不变调的算法,不少开源的,改改其实效果都能不错,这种算法只要作好逆向优化,放进来以后,音频也能保证不变调。

日志收集,可能日志收集不是全部的开发者都愿意接受的,可是有的开发者是逼着咱们要咱们作,由于他们须要这个数据来定位问题,就像我刚才说的,常常有人会问,是否是又卡了,这个问题被问多了以后,你们都但愿知道为何卡,端上的日志不收集上来是没有办法定位出这个问题的。咱们如今有日志收集的策略在用户赞成的状况下,会按期可能几百条打成一个ZIP包发上来,这个数据是咱们和用户共享的。

总结

到这里,直播互动平台高并发分布式架构应用设计就结束了,,不足之处还望你们多多包涵!!以为收获的话能够点个关注收藏转发一波喔,谢谢大佬们支持。(吹一波,233~~)

下面和你们交流几点编程的经验:

一、多写多敲代码,好的代码与扎实的基础知识必定是实践出来的

2丶 测试、测试再测试,若是你不完全测试本身的代码,那恐怕你开发的就不仅是代码,可能还会声名狼藉。

3丶 简化编程,加快速度,代码风骚,在你完成编码后,应回头而且优化它。从长远来看,这里或那里一些的改进,会让后来的支持人员更加轻松。

最后,每一位读到这里的网友,感谢大家能耐心地看完。但愿在成为一名更优秀的Java程序员的道路上,咱们能够一块儿学习、一块儿进步。

相关文章
相关标签/搜索