最近入门 Go 语言,学习小鱼儿《GO 实现千万级 WebSocket 消息推送服务之弹幕推送》,实践并记录形成此文。
1. 弹幕系统复杂度
1 个直播间
在线人数:100 万
发送弹幕:1000 条/秒
推送频率:100 万 * 1000 条/秒 = 10 亿条/秒
N 个直播间
推送频率:N * 10 亿条/秒
挑战
天然大数据量,服务性能要求高。
2. 模式选择
拉模式
客户端 http 请求,服务端 http 响应。
优点:
逻辑相对简单。
缺点:
数据更新频率低时,请求无效率高。
在线用户多时,服务端负载高。
定时拉取不能满足时效性要求。
服务端无法主动推送消息。
推模式
服务端主动推送数据。
优点:
有数据才推送,不做无用功。
有更新就推送,不耽误时间。
服务端可以主动推送消息。
缺点:
逻辑稍显复杂。
需要维护大量在线长连接。
协议选择
基于 WebSocket 的消息推送。WebSocket 是基于 TCP 的一种新的网络协议,实现了浏览器和服务器之间的全双工通信,允许服务器主动发送信息给客户端。WebSocket 与 HTTP 不同,但包含 HTTP 协议,简单来说,WebSocket 通过 HTTP 三次握手建立连接,随后即升级为 WebSocket 专属的协议部分。WebSocket 通信流程:
优点:
持久化协议,节约资源,HTTP 是非持久协议。
服务器主动发消息。
缺点:
不支持低版本 IE。
3. 语言选择
NodeJS 缺点:单线程模型,推送能力有限。
C/C++ 缺点:WebSocket 实现成本高,轮子少。
Go 优点:多线程,天生支持高并发;自带轮子,WebSocket 标准库。
4. Show Code
本次学习通过客户端(小程序)+ 服务端(Go)进行代码实践,文中只展示部分代码,全部代码后面会给出 GitHub 项目地址。
简单 HTTP 服务
服务端(Go)
客户端(浏览器)
升级 WebSocket 服务
服务端(Go)
客户端(小程序)
交互展示
封装 WebSocket 服务
服务端(Go)
客户端(小程序)
交互展示
5. 技术难点
内核瓶颈
linux 内核发送 TCP 极限包频 $\approx$ 100 万/秒
锁瓶颈
维护在线用户连接字典,遍历推送消息时,可能遇到用户上下线修改字典,要加锁
CPU 瓶颈
json 格式通信要编码,耗时长
6. 优化方案
消息合并推送,多化少,优化内核瓶颈
用户分散存储,大化小,优化锁瓶颈
json 编码提前做,后提前,优化 CPU 瓶颈
7. 单机框架
8. 项目地址
Go 服务端:https://github.com/zlpk/Go_WebSocketStudy.git
小程序客户端:https://github.com/zlpk/MiniApp_WebSocketStudy.git
领取专属 10元无门槛券
私享最新 技术干货