如何设计一个70w在先人数的弹幕系统
文章地址:https://mp.weixin.qq.com/s?__biz=MzkyNTI5NTQ1NQ==&mid=2247511614&idx=1&sn=4eb1147d87bd121ff62853e0adf60dc2&chksm=c1ca580ef6bdd1185fde9ee347ea6c0c669eee8afc0f8b8fdec52808745174b5b8fcb8e67e8b#rd

背景

业务需求:为了更好地支持东南亚直播业务,产品设计添加了弹幕
性能要求:能支持单房间百万用户同时在线
遇到问题:使用腾讯云支持的弹幕系统效果经常出现卡顿,弹幕偏少的问题
解决方案:开发自己的弹幕系统

问题分析

弹幕系统面临的问题
1.带宽压力

  • 一个请求由四个部分组成:请求行、请求头标、空行和请求数据

2.弱网导致的弹幕卡顿、丢失
3.性能与可靠性

  • qps即每秒查询率,是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准。
    QPS=并发量/平均响应时间。
    并发量=QPS*平均响应时间。

带宽优化

解决带宽压力的方案:
1.启用http压缩

  • http压缩:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Compression

2.Response结构简化
3.内容排列顺序优化

* 根据gzip的压缩的压缩原理可以知道,重复度越高,压缩比越高,因此可以将字符串和数字内容放在一起摆放

4.频率控制

  • 带宽控制:通过添加请求间隔参数(下次请求时间),保证客户端的请求频率服务端可控。以应对突发的流量增长问题,提供有损的服务。
  • 稀疏控制:在弹幕稀疏和空洞的时间段,通过控制下次请求时间,避免客户端的无效请求。

弹幕卡顿、丢失分析

条件:
1.在东南亚的弱网情况下,TCP长连接会经常性的断开
2.根据了解腾讯云的弹幕系统,在300人以下使用的是推送模式,300人以上则是采用的轮训模式。但是考虑到资源消耗情况,他们可能使用的是Websocket来实现的弹幕系统,所以才会出现弹幕卡顿、丢失的情况。

可选用技术:
Long Polling via AJAX,WebSockets,短轮训

  • Long Polling via AJAX
    客户端向服务器发送Ajax请求,服务器接到请求后保持住连接,直到有新消息才返回响应信息,客户端处理完响应信息后再向服务器发送新的请求
    优点:减少轮询次数,低延迟,浏览器兼容性较好。
    缺点:服务器需要保持大量连接。
  • WebSockets
    服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话。
    优点:较少的控制开销,在连接创建后,服务器和客户端之间交换数据时,用于协议控制的数据包头部相对较小。在不包含扩展的情况下,对于服务器到客户端的内容,此头部大小只有2至10字节(和数据包长度有关);对于客户端到服务器的内容,此头部还需要加上额外的4字节的掩码。相对于 HTTP 请求每次都要携带完整的头部,此项开销显著减少了。更强的实时性,由于协议是全双工的,所以服务器可以随时主动给客户端下发数据。相对于HTTP请求需要等待客户端发起请求服务端才能响应,延迟明显更少;即使是和Comet等类似的长轮询比较,其也能在短时间内更多次地传递数据。长连接,保持连接状态。
  • 短连接环境下,数据交互完毕后,主动释放连接。
    长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,客户端再次访问这个服务器时,会继续使用这一条已经建立的连接。
    在上文中,由于东南亚的弱网环境,tcp长连接也会因为网络问题断开,所以无论是Long Polling via AJAX还是WebSockets通信都不符合业务需要。

技术选用:短轮询

可靠与性能

方案:
服务拆分,在拉取弹幕服务的一端引入本地缓存,在发送弹幕的一端进行弹幕限流

  • 服务拆分主要考虑因素是为了不让服务间相互影响,对于这种系统服务,不同服务的QPS往往是不对等的,例如像拉取弹幕的服务的请求频率和负载通常会比发送弹幕服务高1到2个数量级,在这种情况下不能让拉弹幕服务把发弹幕服务搞垮,反之亦然,最⼤度地保证系统的可用性,同时也更更加方便对各个服务做Scale-Up和Scale-Out。服务拆分也划清了业务边界,方便协同开发。
  • 数据更新的策略是服务会定期发起RPC调⽤从弹幕服务拉取数据,拉取到的弹幕缓存到内存中,这样后续的请求过来时便能直接⾛走本地内存的读取,⼤大幅降低了调用时延。这样做还有另外一个好处就是缩短调⽤链路,把数据放到离⽤户最近的地⽅,同时还能降低外部依赖的服务故障对业务的影响,
  • 因为用户一定时间能看得过来弹幕总量是有限的,所以可以对弹幕进行限流,有选择的丢弃多余的弹幕。同时,采用柔性的处理方式,拉取用户头像、敏感词过滤等分支在调用失败的情况下,仍然能保证服务的核心流程不受影响,即弹幕能够正常发送和接收,提供有损的服务。

总结

1.在进行性能优化时,先对需求和问题进行分析
2.性能优化可以从多方面进行
3.在选择技术时,要充分了解技术的优缺点,现实问题的影响以及是否有相似的的系统使用过这个技术,使用后的结果是什么
4.对于复杂的业务可以将其进行服务拆分,最⼤度地保证系统的可用性,同时也更更加方便对各个服务做Scale-Up和Scale-Out。服务拆分也划清了业务边界,方便协同开发。