融云首席架构师李淼:直播互动系统的设计与实践

Linroid 2017-04-15

直播互动系统的一些特性

融云首席架构师李淼:直播互动系统的设计与实践

李淼·融云首席架构师兼联合创始人

融云于14年成立之时,只提供聊天室这样的服务,国内直播平台还未大批兴起。15年,源于大量客户对直播互动的需求,融云预见直播平台未来会有很好的前景,开始与客户积极交流来挖掘需求,最终将聊天室转变为直播互动平台。经历了16年一个完整的直播元年,直播互动系统也正式步入了成熟期。

当问及直播互动系统的特性,李淼表示:

其一,直播互动平台的用户量实际上是没有上限的,因为不可能去限制一个主播加入观众的成员数量。

其二,通过把消息进行分级控制的方式来保证礼物、红包等消息传输的可靠性。

其三,瞬时消息吞吐量大,融云某个聊天室曾经一秒钟产生过近千万的消息。

其四,就是针对伸缩及稳定性方面的高要求。

消息平台的逻辑设计及这样做的原因

消息是直播互动系统最重要的元素,消息的处理做的好不好会直接影响用户的体验。融云的消息平台逻辑设计是怎样的呢?

融云首席架构师李淼:直播互动系统的设计与实践

如上图,李淼用一张时序图针对这个问题进行了解答。A客户端是发消息方、服务端是融云整个后端平台,B客户端是接收消息方。首先,客户端向服务端发送消息,服务端接收消息先进行消息验证,消息验证里面包含了高危词、敏感词的过滤,反垃圾系统对消息进行反垃圾的过滤,以及权限验证,当消息通过之后,对消息优先进行存储,之后会给A客户端返回应答,告知消息已经发送成功。这时服务端会遍历成员分发通知。值得注意的是,现在还没有向客户端发送消息实体,当接收客户端接收消息通知时,会从自己本地存储里面拿到当前直播间里面最新的消息版本号,同时向服务器发起同步请求,服务器获取客户提交的版本号之后,会以这个版本号为起点到最新版本号把所有消息全部拿回来返回给客户端,客户端收到这个消息进行消息展示以及存储这个最新版本号。整个通信流程,版本号获取方式,跟常用版本控制软件比较类似。

之所以把流程变得这么复杂,在发送完通知之后再同步消息,主要原因如下:

  • 通知的推送无需服务质量保证
  • 服务器端存储的消息顺序与到达的客户端顺序一致
  • 当消息密集时可以将多条消息进行合并
  • 可以控制下发的消息条数
  •  以存储分级实现消息分级

消息平台在服务端实现细节及最佳应用实践

当问及直播消息系统于服务端的实现细节,李淼主要从数据预处理、消息分级、消息存储和消息分发队列四方面进行了介绍,但在实际服务开发过程中,优化还有很多。

数据预处理。当服务端接收消息之后优先对数据进行序列化以及存储,序列化消息和要下发的客户端数据要保持一致,通过这种预处理的方式,CPU的使用率在当前基础上降低了30%。

消息分级存储。根据消息类型按照中、高、低序列进行分级存储。

Skiplist转化为环形队列存储。每条消息有唯一且递增版本号,消息按照版本号顺序存储。这样的数据在内存存储情况下,跳表是一种非常合适的数据结构。但是,跳表时间复杂度和空间复杂度比较大,同时往跳表中插入数据时使用的锁范围非常大,会对服务器产生一些额外的开销。之后,由跳表演进成一种类似环形队列的数据结构,对服务器性能开销提升很多。

Map与队列构建复合数据结构,降低无意义消费。服务端下发通知,对于通知来讲在这一时刻无论有多少条消息,每个用户只有一条通知,通过Map与队列构建这样的复合结构进行存储。队列里面存储是数据的指针,Map存储用于下发的通知实体,Map使用的key为用户标识,这样可以降低无意义的消费。

 

融云最新版线上直播互动平台的整体架构

 

融云首席架构师李淼:直播互动系统的设计与实践

直播互动平台的2.1架构

谈到直播平台的架构,李淼表示,如上图,融云目前正在使用的架构分为连接层、业务层和存储层等。连接层和业务层构建成整个大的集群,然后进行服务。连接层主要是负责客户端与服务器保持长连接,同时将客户端的协议与内部服务的协议进行相互转化。

业务层负责IM相关业务处理,业务层采用的是微服务架构,线上服务有40多个类型,但对于直播互动平台包含如下三项服务:

第一:上行控制服务,主要目的是用于处理接收的上行客户端的消息,进行敏感词和高危词的过滤。这个服务的负载方式采用的是随机分配的负载方式。

第二,直播服务,负责维护直播间成员关系和负责接收上行控制服务给它的消息,上行控制服务会先期进行消息抛弃,抛弃到直播服务可以接收的范围之内,将消息下发到直播服务,直播服务再广播到直播消息服务。

第三:直播消息服务,负责给用户进行分发通知,是以用户ID进行一致的哈希方式进行负载。每个服务节点包含部分用户关系。整个直播消息服务构建了一个整体成员关系,他等同于直播消息服务上的一个节点。这层除分发通知外,还负责客户端同步拉取获取的消息。