IM开发干货分享:浅谈IM系统中离线消息、历史消息的最佳实践

简介: 本文将基于IM消息系统的技术实践,分享关于离线消息和历史消息的正确理解,以及具体的技术配合和实践,希望能为你的离线消息和历史消息技术设计带来最佳实践灵感。

本文由融云技术团队原创分享,原题“IM 消息数据存储结构设计”,内容有修订。

1、引言

在如今的移动互联网时代,IM类产品已是我们生活中不可或缺的组成部分。像微信、钉钉、QQ等是典型的以 IM 为核心功能的社交产品。另外也有一些应用虽然IM功能不是核心,但IM能力也是其整个应用极其重要的组成部分,比如在线游戏、电商直播等应用。

在IM技术应用场景越来越广泛的前提下,对即时通讯IM技术的学习和掌握就显的越来越有必要。

在IM庞大的技术体系中,消息系统无疑是最核心的,而消息系统中,最关键的部分是消息的分发和存储,而离线消息和历史消息又是这个关键环节中不可回避的技术要点。

本文将基于IM消息系统的技术实践,分享关于离线消息和历史消息的正确理解,以及具体的技术配合和实践,希望能为你的离线消息和历史消息技术设计带来最佳实践灵感。

cover-opti.png

学习交流:

- 移动端IM开发入门文章:《新手入门一篇就够:从零开发移动端IM

- 开源IM框架源码:https://github.com/JackJiang2011/MobileIMSDK

本文同步发布于:http://www.52im.net/thread-3887-1-1.html

2、相关文章

技术相关文章:

  1. 什么是IM系统的可靠性?
  2. 闲鱼IM的在线、离线聊天数据同步机制优化实践
  3. 闲鱼亿级IM消息系统的可靠投递优化实践
  4. 一套亿级用户的IM架构技术干货(下篇):可靠性、有序性、弱网优化等
  5. IM消息送达保证机制实现(二):保证离线消息的可靠投递
  6. 我是如何解决大量离线消息导致客户端卡顿的

融云技术团队分享的其它文章:

  1. 融云安卓端IM产品的网络链路保活技术实践
  2. 全面揭秘亿级IM消息的可靠投递机制
  3. 解密融云IM产品的聊天消息ID生成策略
  4. 万人群聊消息投递方案的思考和实践
  5. 基于WebRTC的实时音视频首帧显示时间优化实践
  6. 融云IM技术分享:万人群聊消息投递方案的思考和实践

3、IM消息投递的一般做法

在通常的IM消息系统中,对于实时消息、离线消息、历史消息大概都是下面这样的技术思路。

对于在线用户:消息会直接实时发送到在线的接收方,消息发送完成后,服务器端并不会对消息进行落地存储。

而对于离线的用户:服务器端会将消息存入到离线库,当用户登录后,从离线库中将离线消息拉走,然后服务器端将离线消息删除。

这样实现的缺点就是消息不持久化,导致消息无法支持消息漫游,降低了消息的可靠性。

PS:实际上,这其实也不能算是缺点,因为一些场景下存储历史消息并不是必须的,所谓的消息漫游能力也不是必备的,比如微信。

而在我们设计的消息系统中,服务器只要接收到了发送方发上来的消息,在转发给接收方的同时也会在离线数据库及历史消息库中进行消息的落地存储,而历史消息的落地也就能支持消息漫游等相关功能了。

4、什么是离线消息和历史消息?

关于离线消息和历史消息,在技术上,我们是这样定义。

1)离线消息:

离线消息就是用户(即接收方)在离线过程中收到的消息,这些消息大多是用户比较关心的消息,具有一定的时效性。

以我们的系统经验来说,我们的离线消息默认只保存最近七天的消息。

用户(即接收方)在下次登录后会全量获取这些离线消息,然后在客户端根据聊天会话进行离线消息的UI展示(比如显示一个未读消息气泡等)。

PS:用户离线的可能性在技术上其实是由很多种情况组成的,比如对方不在线、对方网络断掉了、对方手机崩溃了、服务器发送时出错了等等,严格来讲——只要无法实时发送成的消息,都算“离线消息”。

2)历史消息:

历史消息存储了用户所有的聊天消息,这些消息包括发出的消息以及接收到的消息。

在客户端获取历史消息时,通常是按照会话进行分页获取的。

以我们的系统经验来说,历史消息的存储时间我们设计默认为半年,当然这个时间可以按实际的产品运营规则来定,没有硬性规定。

5、IM消息的发送及存储流程

以下是我们系统整体的消息发送及存储流程:

1.png

如上图所示:当用户发送聊天消息到服务器端后,首先会进入到消息系统中,消息系统会对消息进行分发以及存储。

这个过程中:对于在线的接收方,会选择直接推送消息。但是遇到接收方不在线或者是消息推送失败的情况下,也会有另外的消息获取方式,比如接收方会主动向服务器拉取未收到的消息。但是接收方何时来服务器拉取消息以及从哪里拉取是未知的,所以消息存入到离线库的意义也就在这里。

消息系统存储离线的过程中,为了不影响整个系统的更为平稳,我们使用了MQ消息队列进行IO解偶,所以聊天消息实际上是异步存入到离线库中的(通过MQ进行慢IO解偶,这其实也是惯常做法)。

在分发完消息后:消息服务会同步一份消息数据到历史消息服务中,历史消息服务同样会对消息进行落地存储。

对于新的客户端设备:会有同步消息的需求(所谓的消息漫游能力),而这也正是历史消息的主要作用。在历史消息库中,客户端是可以拉取任意会话的全量历史消息的。

6、IM离线消息、历史消息在存储逻辑上的区别

6.1 概述

通过上面的图中能清晰的看到:

  • 1)离线消息我们存储介质选用的是 Redis
  • 2)历史消息我们选用的是 HBase

对于为什么选用不同的存储介质,其实我们考虑的是离线消息和历史消息不同的业务场景和读写模式。

下面我们重点介绍一下离线消息和历史消息存储的区别。

6.2 离线消息存储模式——“扩散写”

离线消息的存储模式我们用的是扩散写。

2.png

如上图所示:每个用户都有自己单独的收件箱和发件箱:

  • 1)收件箱存放的是需要向这个接收端同步的所有消息;
  • 2)发件箱里存放的是发送端发出的所有消息。

以单聊为例:聊天中的两人会话中,消息会产生两次写,即发送者的发件箱和接收端的收件箱。

而在群的场景下:写入会被更加的放大(扩散),如果群里有 N 个人,那一条群消息就会被扩散写 N 次。

小结一下:

  • 1)扩散写的优点是:接收端的逻辑会非常清晰简单,只需要从收件箱里读取一次即可,大大降低了同步消息所需的读的压力;
  • 2)扩散写的缺点是:写入会被成指数地放大,特别是针对群这种场景。

6.3 历史消息存储模式——“扩散读”

历史消息的存储模式我们用的是扩散读。

因为历史消息中,每个会话都保存了整个会话的全量消息。在扩散读这种模式下,每个会话的消息只保存一次。

对比扩散写模式,扩散读的优点和缺点如下:

  • 1)优点是:写入次数大大降低,特别是针对群消息,只需要存一次即可;
  • 2)缺点是:接收端接收消息非常的复杂和低效,因为这种模式客户端想拉取到所有消息就只能每个会话同步一次,读就会被放大,而且可能会产生很多次无效的读,因为有些会话可能根本没有新消息。

3.png

6.4 小结

在 IM 这种应用场景下,通常会用到扩散写这种消息同步模型,一条消息产生一条,但是可能会被读多次,是典型的读多写少的场景。

一个优化好的IM系统,必须从设计上平衡读写压力,避免读或者写任意一个维度达到天花板。

当然扩散写这种模式也有其弊端,比如万人群,会导致一条消息,写入了一万次。

综合来讲:我们需要根据自己的业务场景做相应设计选择,以我们的IM系统为例,就是是根据了离线和历史消息的不同场景选择了写扩散和读扩散的组合模式。适合的才是最好的,没有必要死搬硬套理论。

7、IM客户端的拉取消息逻辑

7.1 离线消息拉取逻辑

对于IM客户端而言,离线消息的获取针对的是自己的整个离线消息,包括所有的会话(直白了说,就是上线时拉取此次离线过程中的所有未收取的离线消息)。

离线消息的获取是自上而下的方式(按时间序),我们的经验是一次获取 200 条(PS:如果离线消息过多,会分页多次拉取,拉取1“次”可以理解为拉取1“页”)。

在客户端拉取离线消息的信令中,需要带上当前客户端缓存的消息的最大时间戳。

通过上节的图我们应该知道,离线消息我们存储的是一个线性结构(指的是按时间顺序),Server 会根据这个时间戳向下查找离线消息。当重装或者新安装 App 时,客户端的“当前客户端缓存的消息的最大时间戳”可以传 0 上来。

Server 也会缓存客户端拉取到的最后一条消息的时间戳,然后根据业务场景,客户端类型等因素来决定从哪里开始拉取,如果没有拉取完 Server 会在拉取消息的应答中带相应的标记位,告诉客户端继续拉取,客户端循环拉取,直到所有离线消息拉完。

7.2 历史消息拉取逻辑

历史消息的获取通常针对的是单一会话。

在拉取过程中,需要向服务端提交两个参数:

  • 1)对方的 ID(如果是单聊的话就是对方的 UserID,如果是群则是群组ID);
  • 2)当前会话的最前面消息的时间戳(即当前会话最老一条消息的时间戳)。

Server据这两个参数,可以定位到这个客户端的此会话,然后一次获取 20 条历史消息。

消息的拉取时序上采用的是自下而上的方式(也就是时间序逆序),即从最后面往前翻。只要有消息,客户端可以一直向前翻,手动触发获取会话的历史消息。

上面的拉取逻辑,在IM界面功能上通常对应的是下拉或点击“加载更多”,比如这样:

4.jpg

8、本文小结

本文主要分享了IM中有关离线消息和历史消息的正确,主要包括离线消息和历史消息的区别,以及二者在存储、分发、拉取逻辑方面的最佳践等。如对文中内容有异议,欢迎留言讨论。

9、参考资料

[1] 一套海量在线用户的移动端IM架构设计实践分享(含详细图文)

[2] 一套原创分布式即时通讯(IM)系统理论架构方案

[3] 从零到卓越:京东客服即时通讯系统的技术架构演进历程

[4] 一套亿级用户的IM架构技术干货(上篇):整体架构、服务拆分等

[5] 闲鱼亿级IM消息系统的架构演进之路

[6] 闲鱼亿级IM消息系统的可靠投递优化实践

[7] 闲鱼亿级IM消息系统的及时性优化实践

[8] 基于实践:一套百万消息量小规模IM系统技术要点总结

[9] IM消息送达保证机制实现(一):保证在线实时消息的可靠投递

[10] 理解IM消息“可靠性”和“一致性”问题,以及解决方案探讨

[11] 零基础IM开发入门(一):什么是IM系统?

本文同步发布于:http://www.52im.net/thread-3887-1-1.html

目录
相关文章
|
14天前
|
机器学习/深度学习 自然语言处理 搜索推荐
深度分析 | 2024主流的智能客服系统有哪些?他们是怎么实现的?
本文深入探讨了智能客服系统的使用方法和相关技术实现逻辑,涵盖前端交互、服务接入、逻辑处理、数据存储四大层面,以及自然语言处理、机器学习、语音识别与合成、数据分析与挖掘、知识库管理和智能推荐系统等核心技术,帮助企业更好地理解和应用智能客服系统,提升服务效率和客户满意度。
81 1
|
2月前
|
存储 自然语言处理 机器人
实战揭秘:当RAG遇上企业客服系统——从案例出发剖析Retrieval-Augmented Generation技术的真实表现与应用局限,带你深入了解背后的技术细节与解决方案
【10月更文挑战第3天】随着自然语言处理技术的进步,结合检索与生成能力的RAG技术被广泛应用于多个领域,通过访问外部知识源提升生成内容的准确性和上下文一致性。本文通过具体案例探讨RAG技术的优势与局限,并提供实用建议。例如,一家初创公司利用LangChain框架搭建基于RAG的聊天机器人,以自动化FAQ系统减轻客服团队工作负担。尽管该系统在处理简单问题时表现出色,但在面对复杂或多步骤问题时存在局限。此外,RAG系统的性能高度依赖于训练数据的质量和范围。因此,企业在采用RAG技术时需综合评估需求和技术局限性,合理规划技术栈,并辅以必要的人工干预和监督机制。
166 3
|
4月前
|
数据采集 监控 测试技术
大型IM稳定性监测实践:手Q客户端性能防劣化系统的建设之路
本文以iOS端为例,详细分享了手 Q 客户端性能防劣化系统从0到1的构建之路,相信对业界和IM开发者们都有较高的借鉴意义。
169 2
|
24天前
|
存储 人工智能 运维
最新榜单 | 盘点2024年10大主流工单系统
随着互联网的发展,工单系统因其多样化功能和高效管理能力,成为企业运营的重要工具。本文介绍了10大主流工单系统,包括合力亿捷、阿里云服务中台、华为云ROMA ServiceCore等,它们各具特色,帮助企业提升服务质量和运营效率,实现数字化转型。
45 7
|
26天前
|
存储 自然语言处理 关系型数据库
基于阿里云通义千问开发智能客服与问答系统
在企业的数字化转型过程中,智能客服系统已成为提高客户满意度和降低运营成本的重要手段。阿里云的通义千问作为一款强大的大语言模型,具有自然语言理解、对话生成、知识检索等能力,非常适合用来开发智能客服与问答系统。 通过本博客,我们将演示如何基于阿里云的通义千问模型,结合阿里云相关产品如函数计算(FC)、API网关、RDS等,搭建一个功能齐全的智能客服系统。
83 5
|
2月前
|
人工智能 自然语言处理 搜索推荐
AI技术在智能客服系统中的应用与挑战
【9月更文挑战第32天】本文将探讨AI技术在智能客服系统中的应用及其面临的挑战。我们将分析AI技术如何改变传统客服模式,提高服务质量和效率,并讨论在实际应用中可能遇到的问题和解决方案。
330 65
|
1月前
|
自然语言处理 数据可视化 搜索推荐
构建一个基于通义千问的智能客服系统
公司开发一个智能客服系统,帮助用户快速找到他们需要的商品信息、解决问题,并提供个性化的购物建议。系统需要能够处理大量的用户提问,并以自然语言的形式给出准确的回答。
77 1
|
1月前
|
人工智能 自然语言处理 搜索推荐
选型攻略 | 智能客服系统该怎么选?(好用的智能客服系统推荐)
智能客服系统的选型需要综合考虑渠道功能、系统性能、客服工作管理、客户管理以及成本效益等因素。目前合力亿捷推出的智能知识库,梳理海量知识,根据不同主题对知识进行分类,使其结构更清晰。
69 0
|
1月前
|
人工智能 自然语言处理 安全
AI技术在智能客服系统中的应用与挑战
【10月更文挑战第28天】本文将深入探讨人工智能(AI)技术在智能客服系统中的应用及其面临的挑战。我们将通过实例分析,了解AI如何改善客户服务体验,提高效率和降低成本。同时,我们也将关注AI在实际应用中可能遇到的问题,如语义理解、情感识别和数据安全等,并提出相应的解决方案。
|
2月前
|
存储 安全 开发工具
百度公共IM系统的Andriod端IM SDK组件架构设计与技术实现
本文主要介绍了百度公共IM系统的Andriod端IM SDK的建设背景、IM SDK主要结构和工作流程以及建设过程遇到的问题和解决方案。
62 3

热门文章

最新文章