技术复杂度
对于一个直播间(头部主播):
那么服务端推送频率就是:100w * 1000条/秒 = 10亿条/秒
如果是N个直播间,那么推送频率是:10N亿条/秒
方案对比:拉 vs 推
(客户端)拉模式

(服务端)推模式:基于websocket协议,可以看Web端通信-websocket协议(已整理)了解ws协议。

语言技术选型
NodeJS:
- 单线程模型。需要遍历非常多的用户集合,性能有限,不适合做推送。
C/C++:
Go:
- 多线程,推送性能高
- 基于协程模型,能实现高并发
- websocket是标准库,无需要其他社区库
技术难点和解决方案
内核瓶颈与优化

优化方案:
锁瓶颈与优化

优化方案(GoLang下,可以利用多线程模型提高遍历性能):
- 大锁拆小锁,不上全局锁:将用户连接打散到多个用户集合中,每个集合有自己的锁
- 多线程并发推送多个用户集合,提高遍历性能,避免锁竞争
- 读写锁取代互斥锁:多个推送任务都可以同时获取某个用户集合的读锁,然后遍历它们进行推送
CPU瓶颈

优化方案:
- json编码前置:不用每次推送都推送json格式,在推送前,将json进行编码,之后的推送用编码后的数据,避免百万次重复编码
- 消息合并前置:N条消息合并成一条消息后,大包数据只需要编码一次
分布式架构
单机架构图:

单机瓶颈:

分布式架构图(这图画的是真丑):

gateway网关集群:就是前面实现的服务,他们负责将ws数据推到对应的连接上。
logic逻辑集群:用来接收自家客户端业务发来的ws数据,然后将他们广播给网关集群。
业务方和连接:业务方连接连的是gateway服务,用来接收数据;但是发送ws数据走的logic服务。
总体思想:接收消息和推送消息分为2个集群,不放在一个服务中。
弹幕系统前端设计
核心点
- 使用等待队列来存储弹幕消息,定时消费
- 使用Pool池化技术来避免多余dom节点浪费
- 对于过多的消息,直接丢弃
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| interface IDomContainer { dom: HTMLElement text: string }
class DM { private waitQueue: string[]; private queueSize: number; private interval: number;
private domPool: IDomContainer[]; private poolSize: number;
constructor() { this.waitQueue = []; this.queueSize = 10000; this.interval = 100; }
add(text: string) { if (this.waitQueue.length >= this.queueSize) { return; } this.waitQueue.push(text); }
time() { setInterval(() => { if (!this.waitQueue.length) { return; } const consumeList = this.waitQueue.splice(0, 10); consumeList.forEach(item => this.render(item)); }, this.interval); }
render(text: string) { if (this.domPool.length >= this.poolSize) { return; }
if (!this.domPool.length) { const c = { dom: document.createElement('div'), text, }; this.domPool.push(c); } const c = this.domPool.pop() as IDomContainer; this.drawDanMuEle(c); this.recover(c); }
drawDanMuEle(container: IDomContainer) { const { dom, text } = container; }
recover(container: IDomContainer) { container.text = ''; this.domPool.push(container); } }
|
参考
bookmark
bookmark
bookmark