【51CTO.com快译】无论是在医生与患者之间,还是在客户与支持代理之间,都需要通过交流来交换信息,进而解决问题。同样,企业也需要通过聊天应用来为用户排忧解难,并实现企业的服务价值。下面和我们一起来探讨如何设计并构建企业级的聊天应用架构,以承载数百万级的并发用户和消息。
总的说来,标准的聊天体系架构包括两个主要部分:聊天服务器引擎和客户端聊天部件。
在令牌的协助下,聊天服务器引擎掌控着消息从服务器端发送、并传递到客户端设备上的整个操作过程。该引擎通常由如下组件构成:
对于一定数量的用户和消息来说,标准版本是足以应对的;但是当涉及到不同通信信道(如:文本、视频和语音呼叫),数百万个的用户连接,以及需要根据企业项目进行应用定制时,该标准架构就需要升级了。
在此,我们引入 MirrorFly聊天类API架构 ,它采用的是基于Erlang的XMPP协议 + ejabberd服务器 + Mnesia数据库。
Ejabberd可以被分为三层:
该层的主要功能是侦听并等待客户端连接到本地端口上,然后按需建立客户端与服务器的连接,交换通信数据。由于支持TCP与TLS方式的连接、以及UDP的传输形式,因此它充当了外部世界与ejabberd服务器之间的接口。
作为Ejabberd系统中最主要、也是最重要的部分,逻辑层具有如下功能:
客户端与服务器的连接由模块ejabberd_c2s来控制,通常走的是TCP的5222号端口。服务器与服务器之间的连接由模块ejabberd_s2s、ejabberd_s2s_in、以及ejabber_s2s_out来控制,通常走的是TCP的5269号端口。而HTTP的绑定,则由模块ejabberd_http来控制。
路由器处理的是各种消息之间的路由,以保证消息能够最终到达正确的目的地。例如:当Jabber客户端向另一个实体发送消息时,第一个ejabberd通过查看“to”的属性,来判断该属性所隐含的主机是否由自己所托管。如果该消息属于本地消息,那么应当交由ejabberd_local来处理,否则属于远程消息,应当将其视为s2s消息。
除了上述核心的Jabber与路由器逻辑之外,我们将ejabberd的绝大部分称为模块。由于这些模块可以随时被动态地启动或停止,因此ejabberd服务器即使在运行时(runtime)也具有高度的可扩展性。通常,这些模块被广泛地使用在各种扩展的场景中(也就是所谓的“XEP”)。
在某些场景下,您可能需要修改ejabberd服务器中的核心逻辑。此时钩子正好能够派上用场。钩子是一种在无需更改任何现有代码的基础上,通过将新代码注入目标系统,进而更改ejabberd行为的方法。例如:如果您希望通过消息过滤器,以过滤掉不需要的消息,那么就可以将模块钩子添加到“filter_packet/3”钩子中。而如果您想跟踪客户端发送的所有消息,则可以编写一个函数,并链接到“user_send_packet/3”中。
所有用户(包括真正的jabber客户端用户和管理员)信息都是以相同的方式存储在ejabberd中。他们的所有权限完全取决于其所属的组群。因此,ejabberd中的访问控制模块,使我们能够按组区分用户,从而为不同的用户提供不同的服务。
出于通用目的,在ejabberd中还存在着其他类型的工具与库,例如:XML处理、SASL身份验证、编码、日志记录器等。其中,值得注意的是ejabberd_logger。它是一个非常实用的日志模块,可以被用在各种项目的场景中。
Ejabberd主要使用 mnesia 作为其“数据库”。实际上,mnesia是内置在erlang库中的一种高性能的键值对(key-value)存储系统。它具有如下功能:
另外,作为一种可扩展的数据库系统,它还提供了复制和实时搜索等功能。当然,ejabberd并未强制用户使用该数据库。它也提供了各种ODBC接口,方便用户使用其他的数据库。例如:用户可以使用存储在现有数据库服务器中的数据,进行身份验证;或者出于某种目的使用其他关系型数据库。
通常情况下,mnesia适合于快速的键值对搜索。因此,我们不建议您将其用于“关系型”数据的查找场景中。
如今,借助微服务架构、Kubernetes、S3 bucket storage、以及XMPP协议,Ejabberd开发了一整套具有可扩展性的企业级聊天API架构。该架构不但简单易用,而且能够支持百万用户的并发规模。您也去试试吧。
原文标题:Key Things to Know: Enterprise Chat Architecture That Connects Millions of Users,作者:Parthiba kumar
【51CTO译稿,合作站点转载请注明原文译者和出处为51CTO.com】
【责任编辑:庞桂玉 TEL:(010)68476606】