如何构建支持百万并发量的企业级聊天架构
聊天模型的标准架构
总的说来,标准的聊天体系架构包括两个主要部分:聊天服务器引擎和客户端聊天部件。
- 聊天服务器引擎 - 它是负责中继消息操作的多台服务器组合。
- 客户端聊天部分 - 它是被安装在台式机、移动设备上的聊天应用程序。
在令牌的协助下,聊天服务器引擎掌控着消息从服务器端发送、并传递到客户端设备上的整个操作过程。该引擎通常由如下组件构成:
- 聊天WebSocket服务器
- 聊天WebSocket客户端库
- 聊天REST API
- 聊天媒体存储服务器
对于一定数量的用户和消息来说,标准版本是足以应对的;但是当涉及到不同通信信道(如:文本、视频和语音呼叫),数百万个的用户连接,以及需要根据企业项目进行应用定制时,该标准架构就需要升级了。
在此,我们引入MirrorFly聊天类API架构,它采用的是基于Erlang的XMPP协议 + ejabberd服务器 + Mnesia数据库。
企业级聊天应用的架构
Ejabberd可以被分为三层:
- 接口层:如上所述,它处理所有与客户端往来的数据。
- 逻辑层:这是最为复杂的一层。它处理所有与XMPP相关的逻辑、以及诸如:HTTP绑定、访问控制、可扩展模块、以及钩子(hooks)等其他功能。
- 数据层:它处理如何将数据存储到数据库中,并确保数据的完整性和满足相应的约束。
接口层
该层的主要功能是侦听并等待客户端连接到本地端口上,然后按需建立客户端与服务器的连接,交换通信数据。由于支持TCP与TLS方式的连接、以及UDP的传输形式,因此它充当了外部世界与ejabberd服务器之间的接口。
逻辑层
作为Ejabberd系统中最主要、也是最重要的部分,逻辑层具有如下功能:
- Jabber逻辑(Logics):
客户端与服务器的连接由模块ejabberd_c2s来控制,通常走的是TCP的5222号端口。服务器与服务器之间的连接由模块ejabberd_s2s、ejabberd_s2s_in、以及ejabber_s2s_out来控制,通常走的是TCP的5269号端口。而HTTP的绑定,则由模块ejabberd_http来控制。
- 路由器(Router):
路由器处理的是各种消息之间的路由,以保证消息能够最终到达正确的目的地。例如:当Jabber客户端向另一个实体发送消息时,第一个ejabberd通过查看“to”的属性,来判断该属性所隐含的主机是否由自己所托管。如果该消息属于本地消息,那么应当交由ejabberd_local来处理,否则属于远程消息,应当将其视为s2s消息。
- 模块(Modules):
除了上述核心的Jabber与路由器逻辑之外,我们将ejabberd的绝大部分称为模块。由于这些模块可以随时被动态地启动或停止,因此ejabberd服务器即使在运行时(runtime)也具有高度的可扩展性。通常,这些模块被广泛地使用在各种扩展的场景中(也就是所谓的“XEP”)。
- 钩子(Hooks):
在某些场景下,您可能需要修改ejabberd服务器中的核心逻辑。此时钩子正好能够派上用场。钩子是一种在无需更改任何现有代码的基础上,通过将新代码注入目标系统,进而更改ejabberd行为的方法。例如:如果您希望通过消息过滤器,以过滤掉不需要的消息,那么就可以将模块钩子添加到“filter_packet/3”钩子中。而如果您想跟踪客户端发送的所有消息,则可以编写一个函数,并链接到“user_send_packet/3”中。
- l访问控制(Access Control):
所有用户(包括真正的jabber客户端用户和管理员)信息都是以相同的方式存储在ejabberd中。他们的所有权限完全取决于其所属的组群。因此,ejabberd中的访问控制模块,使我们能够按组区分用户,从而为不同的用户提供不同的服务。
- 工具与库(Utils and Libraries):
出于通用目的,在ejabberd中还存在着其他类型的工具与库,例如:XML处理、SASL身份验证、编码、日志记录器等。其中,值得注意的是ejabberd_logger。它是一个非常实用的日志模块,可以被用在各种项目的场景中。
数据层
Ejabberd主要使用mnesia作为其“数据库”。实际上,mnesia是内置在erlang库中的一种高性能的键值对(key-value)存储系统。它具有如下功能:
- 复制。不同的表可以在多个节点间进行复制。
- 交易原子性。可以将一系列表的操作分组为单个的原子事务。
- 位置透明。可以在未知数据真实位置的情况下,编写各种程序。
- 极快的实时数据搜索能力。
另外,作为一种可扩展的数据库系统,它还提供了复制和实时搜索等功能。当然,ejabberd并未强制用户使用该数据库。它也提供了各种ODBC接口,方便用户使用其他的数据库。例如:用户可以使用存储在现有数据库服务器中的数据,进行身份验证;或者出于某种目的使用其他关系型数据库。
通常情况下,mnesia适合于快速的键值对搜索。因此,我们不建议您将其用于“关系型”数据的查找场景中。
使用企业型聊天架构的好处
- 可重用性 - 可以轻松地为其他任何项目重新设计聊天组件。
- 可扩展性 - 当聊天应用(或称项目)变得更复杂、需要服务于更多的用户时,此类架构能够应对大量的并发用户数。
- 定制与集成 - 可以根据业务需求,轻松地将该架构进行集成与定制。
- 迁移 - 可以轻松地实现组件之间的迁移,而不会干扰到其他的服务器或组件。
总结