Open-IM是由前微信技术专家打造的开源的即时通讯组件。Open-IM包括IM服务端和客户端SDK,实现了高性能、轻量级、易扩展等重要特性。开发者通过集成Open-IM组件,并私有化部署服务端,可以将即时通讯、实时网络能力快速集成到自身应用中,并确保业务数据的安全性和私密性。
【OpenIM原创】开源OpenIM:轻量、高效、实时、可靠、低成本的消息模型
【OpenIM原创】C/C++调用golang函数,golang回调C/C++函数
【OpenIM原创】简单轻松入门 一文讲解WebRTC实现1对1音视频通信原理
【OpenIM扩展】OpenIM服务发现和负载均衡golang插件:gRPC接入etcdv3
【开源OpenIM】高性能、可伸缩、易扩展的即时通讯架构
免责声明:这是设计WhatsApp等即时通讯系统的一种方法。然而,我们不能保证WhatsApp是以这种方式设计的。这是我们设计类似系统的想法。
设计一个即时通讯平台,如WhatsApp或Signal,用户可以利用该平台相互发送消息。应用程序的一个重要方面是聊天信息不会永久存储在应用程序中。
*有趣的事实:*一些聊天信使(如FB Messenger)存储聊天信息,除非用户明确删除它。然而,像WhatsApp这样的即时通讯工具不会将消息永久保存在服务器上。
instant messenger应用程序应满足以下要求。
我们需要建立一个高度可扩展的平台,能够支持WhatsApp规模的流量。此外,在进行容量规划时,我们需要确保考虑高峰流量的最坏情况。下面列出了我们可以用来估算应用程序容量的一些数字(如WhatsApp)。
-每月应用程序上的用户数:10亿
-高峰流量时每秒的活动用户数:650000
-高峰流量时每秒的邮件数:4000万
整个应用程序将由几个微服务组成,每个微服务执行特定的任务。处理聊天信息流量的数据平面(网站管理员包括到分布式系统章节的链接)(我们称之为chat microservice)中所需的服务器数量可以使用以下等式进行估计。
*#* ℎ = (#聊天信息/秒)__∗ 延迟)/#每台服务器的并发连接
假设每台服务器的并发连接数为100K,发送消息的延迟为20毫秒。在这种情况下,聊天服务器机队中所需的服务器的估计数量(使用上述等式)将为8(即4000万*20毫秒/100K)。在标准实践中,建议再添加几个服务器,以处理这些服务器可能的故障。在接下来的一节中,我们将看到这些聊天服务器对总体基础设施成本的影响。
有趣的事实:在本次演讲中,Rick Reed(软件工程师@WhatsApp)谈到了优化基于Erlang的服务器应用程序,以及调整FreeBSD内核以支持每台服务器数百万个并发连接。这在很大程度上帮助了他们保持尽可能小的服务器占用空间。
此即时通讯应用程序所需的功能可以使用两种微服务建模:聊天服务和临时服务。聊天服务将为活跃用户发送的在线聊天信息流量提供服务。该服务将检查接收消息的用户是否在线。如果用户在线,则消息将立即转发给该用户。否则,消息将由临时服务处理。此服务将负责维护发送给脱机用户的所有消息(文本或图像)。数据将暂时存储在临时存储器中,直到脱机用户恢复联机。我们将在后面的一节中提供有关各个组件的更多详细信息。
有趣的事实:WhatsApp实际上使用了一种非常类似的方法,正如同一位WhatsApp工程师(Rick Reed)在另一次演讲中所讨论的。
我们可以公开一个REST端点来与聊天服务交互。下面介绍了用于发送消息的API端点的定义。
sendMessage(String fromUser、String toUser、ClientMetaData ClientMetaData、String message)
请求:
_fromUser:\u发送请求的用户ID
_toUser:\u向其发送请求的用户ID
clientMetaData:用于存储客户端信息(如设备详细信息、位置等)的元数据。
消息:作为通信的一部分发送的消息。
我们将存储详细信息,例如用户连接到的服务器以及用户上次活动的时间。我们可以使用基于文档的数据库(如MongoDB)来存储用户信息,如用户的最后活动时间(也称为心跳时间)。数据模型将类似于下表。
用户ID(香港) | 心跳时间 | 已连接服务器 |
---|---|---|
表1:数据模型-用户信息
在本节中,我们将讨论在一对一通信中发送消息的两种不同场景。之后,我们将讨论需要支持的其他功能,例如推送通知和用户活动状态。最后,我们将研究进行优化和处理故障场景的不同机制。
这里,我们将讨论与向另一个用户发送消息相关的两种不同场景。第一种情况涉及向在线用户发送文本消息。在第二个场景中,我们描述了向脱机用户发送图像所涉及的操作序列。
下面介绍了向在线用户发送文本消息的序列图中每个步骤的详细信息。
下面介绍了序列图中向脱机用户发送图像的每个步骤的详细信息。
我们可以使用基于FIFO的策略实现基于队列的机制来存储和检索瞬态消息。为此,我们可以使用现有的基于云的技术,如AmazonSQS或WindowsAzure队列服务。我们可以使用这些队列来存储发送给脱机用户的临时消息。一旦消息传递给脱机用户,所有对这些临时消息的引用都将从系统中删除。
使用推送技术向用户传递消息有两种方法:客户端推送或服务器推送。如果我们沿着客户机请求的路线走下去,我们可以在长轮询和短轮询之间做出决定。另一方面,有两种方法可以实现服务器推送方法:WebSocket和服务器发送事件(SSE)。Websockets已经成为聊天应用程序事实上的通信协议。我们在下面的部分中提供了有关它的更多详细信息。
使用轮询技术,客户机定期向服务器请求新数据。选择轮询技术的权衡决定可以使用下面提到的数据点。
将服务器消息推送到客户端的方法主要有两种类型。第一种是WebSocket,它是一种通信协议。它通过单个TCP连接提供双工通信信道。由于双向通信,它非常适合聊天应用程序等场景。另一种称为服务器发送事件(SSE),它允许服务器在建立初始客户机-服务器连接后异步向客户机发送“新数据”。SSE更适合发布者-订阅者模型,如实时流式股票价格;twitter提供更新和浏览器通知。
用户最后一次处于活动状态是可以在即时消息中找到的标准功能。我们在上面的表1中展示了存储相关信息的数据模型
在图4中,我们展示了使用WebSocket在客户端和服务器之间维护连接的机制。一旦在客户端和服务器之间建立了初始连接,通信就会切换到双向二进制协议。客户端和服务器之间的连接使用心跳保持活动状态。我们将上次从用户接收心跳的时间存储在数据库中。然后可以查询数据存储以获取用户上次活动的时间。
我们可以使用下面列出的参数来建议系统中的优化。在本文中,我们提供了建议系统优化所应遵循的方法的详细信息。
解决瓶颈
系统中更容易发生故障的主要瓶颈是聊天服务器和临时存储解决方案。在下面的部分中,我们推荐了一些处理此类故障的方法。
我们希望确保我们的服务能够以高可用性和低延迟满足用户需求。我们可以为这些指标定义服务级别协议(SLA),并创建中度和重度监控器,当违反这些SLA时,这些监控器会触发警报。对于此应用程序,我们可以为sendMessage API定义以下SLA。
可用性SLA意味着,如果1000个请求中有1个以上失败,监控器将触发警报。同样,延迟SLA意味着,如果服务器对其接收的100个请求中超过1个请求的响应时间超过5毫秒,则会触发警报。
此外,我们可以在不同的错误场景中设置故障警报。当聊天服务器无法从临时存储的所有副本中为用户获取临时消息时,可能会出现这种情况。这映射到上面图3所示的步骤#10,其中聊天服务器#B请求临时服务器在Bob脱机时获取发送给Bob的消息。让我们假设我们在临时存储器中维护Bob消息的两个副本,以使系统更加健壮。但是,由于临时存储的临时问题,临时服务器无法从两个副本检索消息。这是一个需要调试的错误场景,因此需要足够的监控警报。
我们可以扩展系统以支持群组聊天,通过群组聊天我们可以将消息传递给多个用户。我们可以创建一个数据模型来存储组数据实体,该实体将由GroupChatID标识,并将用于维护属于该组的人员列表。上述系统可扩展以支持向在线和离线用户发送消息的场景。我们可以构建一个组件,该组件将负责确保根据组中所有用户的活动状态将消息传递给他们。
作为此问题的扩展,可以涵盖的另一个方面是安全性,特别是端到端加密,其中只有通信用户可以读取消息。每个用户都有一个公钥,该公钥与该用户正在通信的所有其他用户共享。例如,两个用户Alice和Bob正在相互通信。Alice拥有Bob的公钥,反之亦然;但是,它们的私钥不共享。当Alice向Bob发送消息时,该消息使用Bob的公钥加密并通过网络发送。服务器将加密的消息定向给Bob,Bob使用私钥解密消息。这样,服务器只能访问加密的消息,只有Alice和Bob才能读取他们交换的实际消息。
OpenIM github开源地址:
https://github.com/OpenIMSDK/Open-IM-Server
OpenIM官网 : https://www.rentsoft.cn
OpenIM官方论坛: https://forum.rentsoft.cn/
我们致力于通过开源模式,为全球企业/开发者提供简单、易用、高效的IM服务和实时音视频通讯能力,帮助开发者降低项目的开发成本,并让开发者掌控业务的核心数据。
IM作为核心业务数据,安全的重要性毋庸置疑,OpenIM开源以及私有化部署让企业能更放心使用。
如今IM云服务商收费高企,如何让企业低成本、安全、可靠接入IM服务,是OpenIM的历史使命,也是我们前进的方向。
如您有技术上面的高见请到我们的论坛联系沟通,用户也可与我们的技术人员谈讨使用方面的难题以及见解