写在前面

直播从16年兴起到目前的趋于稳定,期间APP市场上出现过多个直播产品,史称“千播大战”,我有幸参与其中的一款产品(腾讯NOW直播),并经历了从上线到优化再到探索的整个过程。因为是在腾讯所以这款产品的开发有着很深的腾讯印记,我不想来介绍NOW是怎么设计和实现的,我想跳出来讲讲,如果我是这款产品的负责人,那么我要怎么设计,我会怎么实现,我要怎么玩。

总体结构

技术上面分为后台,客户端和web。

在初期设计阶段一定要注意的一点是:android和ios的实现统一。android的特点就是想怎么玩都可以,android基于了开发者无限的权利,但是ios往往受限于各种苹果的政策,所以两端在方案设计初期一定要确定好实现方式,如果不能统一用native那就统一用web,实现不一致的事情迟早都是给自己埋坑。

web的优点就是通用,但是缺点也很明显,速度和安全。

web和native是两个很关键的选择,大致讲注重通用性选择web,注重体验选择native。另外一个关键点是,web可以随时发布,客户端则要有更新周期,在遇到大的bug时,android还能热补丁,ios就很难受了,web则更灵活。如何选择是一门艺术,但切记不要拍脑袋决定。

有了web和客户端,那么对于后台来说我们就要实现两种协议支撑了,http和tcp。

后台的整体架构分为三层,分别为接入层、逻辑层和存储层。如图:

接入层

何为接入层,在流量真正接入到我们业务后台之前,提供就近接入,安全策略、ip收敛和负载均衡等功能,http协议解析之后统一负载均衡的打到后台的nginx中,后续就是逻辑处理了。对于tcp请求,在移动端的复杂网络条件下很多问题都很难处理,业内已经有很多成熟的SDK,如微信mars和网易的云信。我们借助这些SDK完成网络通信,这样做解放了客户端同学的人力,毕竟在复杂网络中做好连接的维护不是一件简单的事情。同时后台对于tcp请求统一接入到一个代理服务中,再有其进行转发,后台隐藏起来方便其内部进行流量控制调整,请求调用链分析,服务质量监控等。

接入层往往逻辑很简单,就是反向代理,再有一些登录态、安全和消息不全的基础功能,无论tcp还是http都要将请求打到逻辑层的业务中。如何标识一个请求对应的服务就需要命令字了,在阿里一个命令字就是java类的全称,子命令字则是具体的方法名,这也是很多java的rpc框架实现的基准。但是上述的实现是需要服务注册、消费等一整套基础框架支撑的,大多数互联网公司都有这个能力,但是腾讯欠缺,因此我们的实现往往最接近事情原本的样子,一个命令字往往是一个16进制的数字或者一个字符串,字符串要比数字更清晰明了。

协议的设计选择pb,因为更高效的编解码效率和简单易懂的pb文件,一个清晰的pb文件能够少写一篇wiki,甚至能够瞬间了解整个流程,但http层通常是json格式。json到pb可以无损失的转换,但pb到json则会丢失精度,原因是byte和long。

那么在逻辑层实现之前,我们还要有个能够处理tcp和http的框架。我自己使用netty+spring+protostuff实现了一个名为Teresa的框架,并且还会加入quasar协程库,我会在另外一篇文章分析一个rpc框架和一套微服务系统的设计要领。

逻辑层

对于直播业务的逻辑层,分析一下最重要的三个系统。

直播间

直播当然需要有直播间了,基本上所有的直播场景都是围绕着直播间运转的。直播间有两块相互独立的系统,一个是音视频一个是直播间具体的业务,进入直播间是一个相对重的逻辑(白名单,黑名单,特效,排行榜等众多业务),进入直播间业务失败也不应该让用户看不到音视频流,因此音视频流和直播间应该是解耦的,直播间的开播和音视频的推流相互不影响,这样方便音视频流的测试而不影响直播间的具体业务。

直播间是整个直播业务的核心链路,平时明星活动时一个直播间上10w真实用户都有可能,挑战点有两个:

  1. 推还是拉。房间是一个消息内容的承载,消息的获取无非就是推push或者拉pull,push的好处是实时性强,缺点就是需要维护成员列表,还有需要关注linux单进程的连接数限制。pull的好处是没有成员列表,缺点是实施性差,请求可能是锯齿状的,错峰能力需要提前考虑,否则有可能瞬间所有客户端一起请求,压垮后台。一个复杂的系统往往是推拉结合的,push可以消息合并,pull可以兜底。那么一个问题就是成员列表,如何把10w+的用户成员列表维护好,mysql肯定不行,用redis、tair或者ckv之类的缓存?性能方面基本上已经到这类缓存的瓶颈了,况且有同时开播的直播间会有1k+,再者网络抖动带来的影响很大。那就只有内存了,内存的问题是怎么把同一个直播间的用户分配到一台机器上,一致性hash,使用内存的缺点就是数据易丢失,直播间的场景我们不需要考虑持久化,只需要在直播开始到直播结束保持稳定即可。但一台机器还是会有单点问题,那就多写,多机完全冗余,并且能够分担读请求压力。多机的问题就是一致性扩容,客户端在进入直播间之后需要定时发送业务心跳来维护在线状态,同时可以返回一些业务信息,1/min的业务心跳能够保证多机中成员列表多数情况一致。如果多机仍然扛不住读请求,那么就需要水平扩容,使用内存的另一个弊端就出现了,如何数据搬迁,搬迁时的变化又怎么处理?还是依赖于心跳,水平扩容先写,过2分钟后基本上就可以提供读了。在日常的直播场景中,小直播间(1w以下)占绝大多数,基本的业务都或多或少依赖成员列表。但是去年百万英雄之类的火爆答题(100w同时在线)条件下,成员列表就没必要存在了,另外那个场景另外再分析。
  2. 怎么推怎么拉。进/退直播间、直播间内的心跳、送礼、发言等等都是直播间内的消息,这多多消息怎么处理。肯定要合并写、合并读,合并是根据直播间id进行合并的,合并的载体依旧是内存,那就又需要一致性hash了。另外一个问题就是成员列表怎么传输,分页拉取,增量调整。

pk赛

pk就是两个主播比赛,通过送礼来加分,分数多的人胜出,是营收的主要来源,比赛方式多种多样,主要就是为了让用户看直播也有一种追星的仪式感。

PK的主要挑战是以下三点

  1. 匹配。玩过dota,lol的都知道这个流程,在当时12年左右11对战平台很火的时候,匹配效率最高的时候都能到毫秒级,那应该是一个很牛逼的系统。匹配的算法我们使用非常经典的EL0,也可以根据场景再改变。当用户点击pk时,将用户放入redis队列,根据时间变化,动态调整匹配上下限,直到成功为止。很简单的问题就是多机情况下的事务性,即不能把一个人同时分配了两场pk。如果用户量小,你甚至可以两台机器抢一个用redis实现的锁,抢到锁去执行匹配流程,但是匹配的瓶颈也就是单机的计算能力了。两阶段提交,把匹配出来的用户,放到第二个redis set队列中,如果重复就把用户重新放到原本队列中继续匹配。但是极端情况下会出现一直冲突,进入死循环。那就将等待队列分级,匹配冲突之后放到优先级更高的队列中,主动减少冲突。这种实现方式也应该是dota2的实现方式。11对战平台肯定不会这么实现,redis队列能否抗住和在鱼塘(大多数菜鸟玩家)分数段的匹配冲突都是两个问题。那只能再次细分排队队列,然后直接使用内存存储用户分数信息。扯远了。
  2. 比赛。送礼事件通过mq旁路到专门的分数计算服务,分数在通过直播间广播到用户,在依赖于直播间的合并读写push时,业务也需要主动合并消息,减少网络流量,推送分数要推送全量而不是增量。实现时通过进程缓存能cache住大部分的请求,收益很高。
  3. 结算。粉丝喜欢搞大事情,总是喜欢在最后几秒钟送大礼物,结算时就会有很多问题,比如服务器的时钟漂移,解决方案依旧是延后处理,两阶段提交。首先页面上展示结算中,给后台主动争取一些时间,然后将结算时间向后+buffer。胜利之后还会给粉丝一些礼物可以抢,这就是一个类似秒杀的场景了,限频、限流、过载保护非常重要。

答题

17年年末答题火爆,只要是直播产品就一定会来蹭一波热度。答题的场景和特点很明了,人多,钱多。人多动辄100w+,钱多也是100w+。答题场景我们放弃了所有其他边缘业务,只做一件事就是答题,但还是有以下问题:

  1. 人数众多。这么多人怎么搞,依然是一致性hash,但是每台机器是单点,没有备机,因为业务心跳也没了。如果答题时宕机就会影响一部分用户飘逸到其他机器上,这个用户的资料就丢失了,我们通过把用户资料传给客户端,客户端请求时主动带上来,这样我们就有一份兜底数据。安全吗?相对安全,因为只有飘逸时才使用兜底数据,并且对数据加密(非对称)。基本上不可能用户一直在多台机器漂移。那么用户会不会有ABA问题,即宕机的服务恢复了,然后又飘回来了,因为原有机器上数据存在,但是之前的老数据,会不会有影响。解决方案:时间戳。
  2. 峰值。8点开始的答题,不可能在一瞬间完成,业务需要主动的通过提前通知用户,引导错峰进入直播间,八点主持人再叨叨一会儿,给业务多点时间。
  3. 拉。没有了成员列表,push变得不可能,拉的问题就凸显了,pull不能集中(后台可以控制请求频率,将请求打散),2000-3000ms。
  4. 时间。答题一般10s,音视频延时时间+网络延时时间,计算一个最大的答题时间。
  5. 题目。题目混在音视频流中容易跟着一起卡,因此需要题目单独拿出来。
  6. 异地部署,就近接入。上海、深圳和天津依照公司的组件完成就近接入。
  7. 结算,在结束后需要将得奖用户写入redis,最终在将三地的redis中用户汇总(mb级别),再通过mq异步发奖。

存储层

存储层在2c业务方面起到一个很重要的角色,mysql这种传统的关系型数据库有可能在性能方面扛不住,redis在性能方面没有什么问题,但是需要考虑缓存击穿问题,而且这个问题还不太好处理,需要考虑的问题还很多。腾讯的ckv在这方面做得很好,一主一备,自动扩容,lru冷备,完全就当做能落地的持久层用。redis会受到单机容量限制,codis虽然搞定了这个问题,但是key的分片是一个坑,用不好坑自己。同时redis在容量满时会有丢弃策略。想用好需要下点功夫。

产品方面

直播是一个变现十分可观的业务,相比于游戏直播,mm直播收入更高,同时带宽要求更低。但是直播也需要大流量一直在养,像抖音通过短视频养,momo通过陌生人社交的基数养。
但是直播也能带来更多的玩法,比如答题、抓娃娃、k歌房、1v1、桌游(谁是卧底、狼人杀)等。做产品也要大胆的给新兴业务一些浅入口,高曝光,而不是藏在角落,这可能涉及到产品册的一些思路。仅仅通过pk,各种活动来榨干用户的血是一种竭泽而渔的做法。要么就是看似直接但是套路很深的红包只能带来一些表象的DAU上升。
直播间是一种能力,它其实赋予了我们原本在线下开展的活动到线上的能力,就比如答题活动。在开放思路,原本的《幸运52》,是不是也能改变一下,或者非诚勿扰。玩法的升级,使得自身能够有能力吸引更多流量。

写在后面

业务到了技术永远都是万变不离其宗,对于后台,客户端,web都有很多的通用之处。分析其中的关键点

设计艺术

  • 能力收敛,以接口形式提供服务
  • 责任划分,整个流程清晰可见
  • 前端保护后端,上游保护下游,各端互不信任

如何实现一个直播APP相关推荐

  1. iOS动手做一个直播app开发(代码篇)

    iOS动手做一个直播app开发(代码篇) ###开篇 好久没写简书,因为好奇的我跑去学习直播了,今天就分享一下我的感慨. 目前为止直播还是比较热点的技术的,简书,git上有几篇阅读量和含金量都不错的文 ...

  2. 开发一个完整的iOS直播app必须技能

    今年,直播行业火了,当然也诞生了一大批网红,甚至明星也开始直播了,因此现在都要搞直播了!由于第一次接触,花了很多时间了解直播,目前整理了直播的原理(因为项目汇报的需要就整理了一下),现在只是展示一下从 ...

  3. (转)【如何快速的开发一个完整的iOS直播app】(原理篇)

    原文链接:https://www.jianshu.com/p/bd42bacbe4cc [如何快速的开发一个完整的iOS直播app](原理篇) [如何快速的开发一个完整的iOS直播app](原理篇) ...

  4. 广州品向:开发一个类似斗鱼的视频直播app的成本

    目前视频直播非常火爆,随着网红,傅园慧,张继科等等的明星加入了直播行业,使得视频直播app越来越受到大家的追捧,很多想进入该行业的创业者,都会咨询广州app定制开发公司品向科技做一个"视频直 ...

  5. 如何快速开发一个完整的ios直播app

    如何快速开发一个完整的iOS直播app 一.个人见解(直播难与易) 直播难:个人认为要想把直播从零开始做出来,绝对是牛逼中的牛逼,大牛中的大牛,因为直播中运用到的技术难点非常之多,视频/音频处理,图形 ...

  6. 超强教程:如何搭建一个 iOS 系统的视频直播 App?

    现今,直播市场热火朝天,不少人喜欢在手机端安装各类直播 App,便于随时随地观看直播或者自己当主播.作为开发者来说,搭建一个稳定性强.延迟率低.可用性强的直播平台,需要考虑到部署视频源.搭建聊天室.优 ...

  7. 开发直播APP选择云服务器的优点

    开发者在开发直播app是都会用到服务器来辅助完成直播的相关业务.目前市场上,服务器的种类大致可以分为两种,一种是物理服务器,另一种是云服务器.但是目前适合直播业务的非云服务器不选. 首先,小编先来跟大 ...

  8. 完整的iOS直播app

    今年移动直播行业的兴起,诞生了一大批网红,甚至明星也开始直播了,因此不得不跟上时代的步伐,由于第一次接触的原因,因此花了很多时间了解直播,整理了直播的原理,希望能帮助到更多的人更快的了解直播. 一.个 ...

  9. iOS直播app原理

    一.个人见解(直播难与易) 直播难:个人认为要想把直播从零开始做出来,绝对是牛逼中的牛逼,大牛中的大牛,因为直播中运用到的技术难点非常之多,视频/音频处理,图形处理,视频/音频压缩,CDN分发,即时通 ...

最新文章

  1. 树言树语:谁动了苹果的弦
  2. netty 5 alph1源码分析(服务端创建过程)
  3. Xgboost实现GPU加速
  4. ”A page can have only one server-side Form tag“错误
  5. 03 | 事务隔离:为什么你改了我还看不见
  6. IDEA新建maven项目漏掉webapp目录解决方法
  7. Kafka 时间轮的原理和实现
  8. Dynamic Performance Tables not accessible Automatic Statistics disabled for this session
  9. EKF_SLAM一般过程
  10. 实验6 Matlab数值计算
  11. mysql免安装迁移_Mysql 免安装配置并迁移数据库
  12. elasticsearch 学习之 搭建简单的elasticsearch多节点服务器
  13. java乘法口诀表_java 输出乘法口诀表
  14. Navicat生成的.psc格式文件数据库导入
  15. ZigBee之帧结构
  16. 手机怎么修改视频的封面?这三个方法和步骤让你实现
  17. Java面试题全集(下)
  18. nginx重启报找不到nginx.pid的解决方法
  19. 扬名立万影评爬取与分析
  20. 租用哪一家服务器好呢?

热门文章

  1. 08年中报大幅预增股
  2. 《人月神话》(The Mythical Man-Month)3 外科手术队伍(The Surgical Team)
  3. 在java中的正则表达式基础
  4. TI AWR1642毫米波雷达学习笔记之理论基础(2)
  5. 全国考研计算机成绩排名,全国33所计算机考研名校跨考难度系数排名
  6. 【华为重启门】华为/荣耀手机一直自动重启原因解决方案(荣耀V10)
  7. 原生态水平和垂直拉伸的JQUERY插件
  8. 小白建网站,该如何入手?
  9. python底层是用什么语言实现的_我为何说Python是全栈式开发语言?
  10. SegmentFault Hackathon 文艺复兴今在沪举行