• 如何打造一个语音聊天室


    语音聊天室这个名词可能有点陌生,实际上相关的产品还是很多的,例如游戏里的开黑语音、在线课堂等。语音聊天室可以认为视频直播的前身,很多音视频平台的架构是从语音聊天室演进为视频直播室的。本文主要介绍语音聊天室的架构设计,后面的文章会逐步介绍从语音到视频的演进历程。

    语音聊天室怎么实现呢?互联网产品设计万变不离其宗,一套QQ的架构设计可以走遍天下。QQ群聊是怎么实现的,那么把群聊中的文字消息换成语音数据就是语音聊天室了。

     

    如图所示,ABC进入房间101,服务器会维护一个房间信息表记录每个房间的用户信息。当某个用户说话的时候,客户端将采集到的语音数据发给服务器,服务器就把语音数据发给101的每一个用户。客户端收到语音数据就可以播放出来。

    但是实际生产中肯定不会使用这么简单的架构,为什么呢?首先一个服务器实现所有功能是不可行的,因为一方面服务器的性能不可能满足,另一方面大型软件的复杂度和维护成本是非常高的,因此软件工程一直都强调高内聚低耦合,把功能拆解可以使系统更容易维护。

    拆解有两个方向,一个是按功能拆分,即把不同功能放到不同服务器完成;另一种是平行扩展,即相同功能的服务分布到多台机器上。

    首先按功能拆分。按功能拆分又称为垂直拆分,与平行扩展是一个相对的概念。比较常见的拆分方法是分层,一般分接入层、逻辑层和数据层。接入层是整个系统对外的窗口,除了基本的数据加解密和透传功能外,还起到保护内部服务器的作用;逻辑层包含实际的业务服务器;数据层主要是存储数据的存储介质和相关服务器。

    接着是平行扩展。为什么需要平行扩展?一方面单机性能有限,即使增加机器配置,性能也是有上限的,因此分布式才是根本解决的方案;另一方面平行扩展可以实现服务高可用,即使部分机器宕机,服务仍然可用。

    简单地说,平行扩展就是增加备机。而备机有冷热之分:热备是指多台机器同时对外提供服务,当其中一台机器故障,其他机器可以正常提供服务;冷备指同时只有一台机器(主机)对外提供服务,其他机器(备机)不提供服务,当主机发生故障时,备机需要切换成主机提供服务。

    还有一个概念,有状态服务和无状态服务。网上有很多解释,大多都比较专业,不再赘述。我只说一下自己的理解,有状态服务是指本地存储需要持久化数据的服务,例如数据库服务;无状态服务是指本地不存储持久化数据的服务,例如WEB服务器。

    有状态和无状态一般是跟冷备和热备对应起来的:有状态服务使用冷备,无状态服务使用热备。这是由它们的特点决定的,有状态服务因为存储数据,一般不支持多点写入,因为数据在服务器之间同步是非常复杂的(CAP理论和Paxos算法了解一下),所以冷备是最简单的容灾策略;无状态服务不存储数据,用户的请求发到哪一台机器都返回一样的结果,因此所有机器可以同时提供服务。

    经过垂直拆分和平行扩展,语音聊天室的架构可以分解成下面的形式:

     

    图中接入层包括目录服务器和语音服务器,逻辑层包括房间服务器,存储层包括数据库。其中接入层和逻辑层服务都是无状态服务,至少有两台机器热备,数据库一般是主从冷备。

    目录服务器是用户访问系统的地图,用户通过它可以找到要连接的服务器的IP和端口。语音服务器是处理语音数据上传和转发的服务。房间服务器维护房间-语音服务器-用户的映射关系。映射关系类似下图,一个房间的用户可能分布在多个语音服务器,另外还有没有画出来的关系:一个语音服务器上可以有多个房间的用户。

     

    业务流程如图所示:用户A点击进入101聊天室,首先请求目录服务器获得101房间所在语音服务器的IP列表;然后,A连接某台语音服务器请求进入101房间。如果进房成功,房间服务器会把信息写入DB,用户A可以在房间开始语音聊天。

     

    这已经是一个比较完备的系统了。

    总结一下,本篇主要介绍了一个简单的语音聊天室的设计方案和一些基础概念。方案设计可以沿着先简单再完备的思路进行推演。例如最开始的一台服务器扛不住,就要平行扩展,一个房间的用户分布到多台服务器,然后就要有一个更高层次的服务器(房间服务器)提供全局视野,如此类推。

    限于篇幅,上述系统还有很多细节没有讨论。例如语音服务器是怎么转发语音数据的?目录服务器是否有点多余?等等。我们在接下来的文章中将一一解答,敬请期待。

  • 相关阅读:
    谷歌浏览器慎用有道词典插件(<audio></audio>) (转载)
    Python函数-4 迭代器
    {v: k for k, v in myArray.items()}
    Python函数-3 推导式
    Java面向对象编程 -6.5
    Java面向对象编程 -6.8
    Java面向对象编程 -6.7
    Java面向对象编程 -6.6
    Java面向对象编程 -6.4
    Java面向对象编程 -6.3
  • 原文地址:https://www.cnblogs.com/htkfsy/p/11957073.html
Copyright © 2020-2023  润新知