你所不知道的直播平台IM系统搭建全攻略 | 恺英网络张皓聪分享

分享 | 张皓聪(恺英网络程序经理)php

整理 | 西北前端

2016年10月29日,由又拍云举办的Open Talk No.26在“魔都”上海3W空间成功举办,这次活动主要邀请直播领域开发一线的技术大神们聊一聊直播平台的架构与优化,看他们化解项目选型、开发上线、迭代过程、性能优化中遇到的挑战与经验。node

恺英网络程序经理张皓聪在Open Talk No.26上,作了“直播平台IM系统实战”的主题分享,介绍了直播平台“IM系统”的搭建过程。redis

张皓聪:2010年加入恺英网络,前后负责过多款手游页游项目,对NodeJS和ZeroMQ有深刻研究。目前负责恺英网络“板栗直播”IM系统的相关开发工做。后端

图片描述

△ Open Talk No.26现场照片性能优化

如下是张皓聪的分享全文服务器

今天我要跟你们分享的是如今很是流行的直播平台里的“IM系统”。“板栗直播”IM系统从立项初期,到发展致今,已经成为一个功能复杂,拥有必定稳定性的系统。网络

1.0版本——速度要快

咱们作IM系统1.0版本时,有如下几个需求:架构

  • 一周出 Demo并发

  • 差很少能用

  • 演示的时候不能忽然崩溃

  • 万一崩溃了不能被发现

  • 性能无所谓

  • 总之,要快速作出来

因为只有一周的时间,初版的架构搭建得很是简单:
服务端由 PHP 和 NodeJS 组成。PHP 负责用户帐户,注册和登陆。NodeJS 负责长连以及进出房间和推送,作成简单的交互。
第一个版本的前端服务器的结构很是简单,功能不多,仅仅负责联接客户端,负责全部客户端的联接。为了保证 H5 也可使用,所以在长连上选择了WebSocket。

图片描述
△ IM系统1.0版本架构图

为了确保客户端演示的时候,万一崩溃了也不能被察觉,咱们使用 pm2 守护了 node进程。同时让客户端同窗作了个自动断线重连。
而后登陆流程是这样的,先从PHP获取一个token,而后带着这个token和node 创建链接,node 会在内网向php验证 token 是否有效,而后创建链接。
而后广播方面,使用了我称做组的形式进行广播,全部的房间和私信都是经过组的形式进行广播。

图片描述

首先,用户在房间里发言的时候,其实是往特定组发送广播。组的名字是用特定字符开头来归类的。
举例来讲,须要向10000房间发送聊天信息时,其实是向 r:10000 这个组发送信息。此时服务端会遍历该组里全部链接,并发送消息。
当须要进行全服广播的时候,咱们使用一个写死特殊的 0 号房间,转换成 gid 也就是 r:0 发送消息。这将遍历全部链接,向他们发送消息。
接下来是推送私聊,这里我为每一个用户都设置了一个私有的 gid,这样发送私信的时候也至关于发送了广播,服务端能够用相同逻辑处理。打个比方向 uid 20000 用户发送私信,至关于向 u:20000 广播。之后扩展成多进程多主机模式时,也没必要知道这个用户目前在哪台服务器上,推送私信就会很方便。
在这个设计中,一位用户是容许加入多个组的。就像群聊同样,一开始就使用这样的设计,之后能够很容易的进行扩展。
因为采用了单点链接的形式,并不须要每次进房间都创建新链接,客户端只要首次进行链接,以后发送请求就能够进出房间,也节省了客户端的开发工做。

2.0版本——更高的可用性

2.0版本需求:

  • 内测版本

  • 支持扩容

  • 更高的可用性

  • 礼物信息比聊天优先级高

  • 特定消息要发送回执

当1.0版本完成以后,接下来就是要开发 2.0 版本。
这个版本里增长了一些必要的需求。
首先,这是一个内测版本。在内测版本中会邀请用户使用,并进行测试。
期间可能因为用户数增多,也可能由于咱们代码自己的缘由或是 bug 形成服务器压力增长,此时会有扩容方面的需求。
第二个是要增长广播优先级的功能,这个很简单,礼物确定是比普通讯息优先级更高的。
最后是特定消息的回执发送,这个咱们目前也尚未实现,可是需求一直是在的。

图片描述
△ IM系统2.0版本的架构

上图中能够看到模块数增长了,可是总的来讲客户端需求并无变化,基本流程的链接流程仍然是先问 PHP 要 token,再去链接 WS。因为咱们容许把 WS 部署在多个主机上,在这中间增长了一步就是访问 LB 得到 WS 地址。LB 会轮询的告知客户端本次应使用哪一个 WS,并把 IP 返回给客户端。确保全部 WS 的压力是平均的。
另外还有一处增长的功能是,因为 WS 已经分离到多个进程了,那么须要一个地方能够用来处理广播。这边咱们选择了 redis 的进行广播。
同时另外还部署了一台 redis 是专门用来保存在线列表等数据。

图片描述
△ 带有优先级的推送消息

上图是一个带有优先级的推送消息。
你们可注意到,咱们为每一个组的gid增长了一个后缀,这个后缀是用来区分优先级的。
好比说用户进入房间 10000,那么我会把他放到 2 个组,分别是 r:10000._ 和 r:10000.n。
同时 node 也会向 redis 订阅两个同名频道,此时服务端就能够从 2 个频道收到推送消息,分别是 _(普通) 和 n (优先)。
后端会有聊天信息要推送,会根据优先级,是使用普通频道仍是优先频道进行广播。
node 这边会开一个主循环,好比设置 12fps ,每一帧会优先转发优先组(频道)中的消息,而后才是普通消息,根据当时压力,将会选择抛弃普通消息。

3.0版本——业务量增大

3.0版本需求:

  • 业务逻辑愈来愈多,须要拆分

  • 须要支持热更

  • 更好的广播性能

  • 优化与其余服务的通讯

  • 日志系统

  • 部署脚本

到了3.0版本时,需求愈来愈多,须要拆分。
线上有时候会有bug和作活动,会有热更的需求。
redis 广播有可能出现瓶颈,在这以前须要须要更好的广播性能。
同时还须要优化与其余服务器之间的通讯。
最后还须要须要有一个简单的日志搜集器。

图片描述
△ IM系统3.0版本架构

这是3.0版本的架构。你们能够看到下面有大量的服务了。其实这些服务原来是在WebSocket里面的,如今把它拆成不一样的进程。
客户端链接这块没有变化,客户端仍然须要问 PHP 要 token,问 LB 要地址,最后再链接。
这个版本的 WS 功能上更加单一,只负责消息转发。
在这个版本里,咱们作了一套 RPC 框架,用来方便调用内网各服务的接口。
增长了日志搜集器和API的服务。以及IM系统(私聊)。用户之间能够聊天和查看聊天记录等。
总的来讲,功能上没有特别大的变化,尤为是接口方面是向前兼容的。

图片描述
△ 经过RPC中转的推送消息

下面我介绍一下RPC服务框架。
咱们的 RPC 框架是基于 ZeroMQ 的。利用他的里的Dealer和Router 进行消息的收发。
ZeroMQ 自带自动重连和负载均衡功能,这方面也不用太操心,节省了开发时间。
数据交换格式是JSON,明文传输,调试也会很方便。

ZeroMQ 性能
-E5-2630,8G 内存,千兆网卡的测试结果
#local_thr tcp://*:5555 100 10000000
message size: 100 [B]
message count: 10000000
mean throughput: 1097051 [msg/s]
mean throughput: 877.641 [Mb/s]

还有就是咱们再也不使用 redis 作广播,而改用 ZeroMQ 的 pub 和 sub 作广播服务。这样广播性能就有了很大提高。

4.0版本——更高要求

IM系统4.0版本的需求

  • 广播和业务分离

  • 优化PRC协议

  • 针对个别地区进行网络优化

到了这个阶段,咱们遇到了一些个别地区网络较慢的问题。

图片描述

咱们把 WS 和 LB 放到了代理服务器后面。LB 能够根据不一样运营商用户,返回代理了的 WS 地址。

图片描述
△ RPC服务路由

同时还优化了RPC 服务,咱们为 RPC 服务增长了路由器,全部的 Worker 都隐藏在他后面,这样客户端调用的时候并不须要知道具体 Worker 的地址。Worker 的更新重启也不会影响其余客户端。

图片描述

广播服务也获得了业务和广播分离,同时集群化。

相关文章
相关标签/搜索