默认
打赏 发表评论 52
想开发IM:买成品怕坑?租第3方怕贵?找开源自已撸?尽量别走弯路了... 找站长给点建议
现代IM系统中聊天消息的同步和存储方案探讨
阅读(443034) | 评论(52 收藏35 淘帖2 3
微信扫一扫关注!

本文原作者:木洛,阿里云高级技术专家,内容有优化和修订,感谢原作者。


1、前言


IM全称是『Instant Messaging』,中文名是即时通讯。在这个高度信息化的移动互联网时代,生活中IM类产品已经成为必备品,比较有名的如钉钉、微信、QQ等以IM为核心功能的产品。当然目前微信已经成长为一个生态型产品,但其核心功能还是IM。还有一些非以IM系统为核心的应用,最典型的如一些在线游戏、社交应用,IM也是其重要的功能模块。可以说,带有社交属性的应用,IM功能一定是必不可少的。

IM系统在互联网初期即存在,其基础技术架构在这十几年的发展中更新迭代多次,从早期的CS、P2P架构,到现在后台已经演变为一个复杂的分布式系统,涉及移动端、网络、安全和存储等技术的方方面面。其支撑的规模也从早期的少量日活,到现在微信这个巨头最新公布的达到9亿的日活的体量。

IM系统中最核心的部分是消息系统,消息系统中最核心的功能是消息的同步和存储:

  • 1)消息的同步:将消息完整的、快速的从发送方传递到接收方,就是消息的同步。消息同步系统最重要的衡量指标就是消息传递的实时性、完整性以及能支撑的消息规模。从功能上来说,一般至少要支持在线和离线推送,高级的IM系统还支持『多端同步』;
  • 2)消息的存储:消息存储即消息的持久化保存,这里不是指消息在客户端本地的保存,而是指云端的保存,功能上对应的就是『消息漫游』。『消息漫游』的好处是可以实现账号在任意端登陆查看所有历史消息,这也是高级IM系统特有的功能之一。

本文内容主要涉及IM系统中的消息系统架构,探讨一种适用于大用户量的消息同步以及存储系统的架构实现,能够支持消息系统中的高级特性『多端同步』以及『消息漫游』。在性能和规模上,能够做到全量消息云端存储,百万TPS以及毫秒级延迟的消息同步能力。

2、相关资料


浅谈IM系统的架构设计
浅谈移动端IM的多点登陆和消息漫游原理
移动端IM登录时拉取数据如何作到省流量?
简述移动端IM开发的那些坑:架构设计、通信协议和客户端
一套海量在线用户的移动端IM架构设计实践分享(含详细图文)
一套原创分布式即时通讯(IM)系统理论架构方案
从零到卓越:京东客服即时通讯系统的技术架构演进历程
蘑菇街即时通讯/IM服务器开发之架构选择
移动端IM中大规模群消息的推送如何保证效率、实时性?
IM消息送达保证机制实现(一):保证在线实时消息的可靠投递
IM消息送达保证机制实现(二):保证离线消息的可靠投递
如何保证IM实时消息的“时序性”与“一致性”?
一个低成本确保IM消息时序的方法探讨
>> 更多同类文章 ……

3、架构设计


本章主要会介绍基于TableStore的现代IM消息系统的架构设计,在详细介绍架构设计之前,会先介绍一种Timeline逻辑模型,来抽象和简化对IM消息同步和存储模型的理解。理解了Timeline模型后,会介绍如何基于此模型对消息的同步以及存储进行建模。基于Timeline模型,在实现消息同步和存储时还会有各方面的技术权衡,例如如何对消息同步常见的读扩散和写扩散两种模型进行对比和选择,以及针对Timeline模型的特征如何来选择底层数据库。

现代IM系统中聊天消息的同步和存储方案探讨_1.png
▲ 上图是消息系统传统架构与现代架构的简单对比

传统架构下,消息是先同步后存储:

对于在线的用户,消息会直接实时同步到在线的接收方,消息同步成功后,并不会进行持久化。而对于离线的用户或者消息无法实时同步成功时,消息会持久化到离线库,当接收方重新连接后,会从离线库拉取所有未读消息。当离线库中的消息成功同步到接收方后,消息会从离线库中删除。传统的消息系统,服务端的主要工作是维护发送方和接收方的连接状态,并提供在线消息同步和离线消息缓存的能力,保证消息一定能够从发送方传递到接收方。服务端不会对消息进行持久化,所以也无法支持消息漫游。


现代架构下,消息是先存储后同步:

先存储后同步的好处是,如果接收方确认接收到了消息,那这条消息一定是已经在云端保存了。并且消息会有两个库来保存,一个是消息存储库,用于全量保存所有会话的消息,主要用于支持消息漫游。另一个是消息同步库,主要用于接收方的多端同步。

消息从发送方发出后,经过服务端转发,服务端会先将消息保存到消息存储库,后保存到消息同步库。完成消息的持久化保存后,对于在线的接收方,会直接选择在线推送。但在线推送并不是一个必须路径,只是一个更优的消息传递路径。

对于在线推送失败或者离线的接收方,会有另外一个统一的消息同步方式。接收方会主动的向服务端拉取所有未同步消息,但接收方何时来同步以及会在哪些端来同步消息对服务端来说是未知的,所以要求服务端必须保存所有需要同步到接收方的消息,这是消息同步库的主要作用。对于新的同步设备,会有消息漫游的需求,这是消息存储库的主要作用,在消息存储库中,可以拉取任意会话的全量历史消息。


以上是传统架构和现代架构的一个简单的对比,现代架构上整个消息的同步和存储流程,并没有变复杂太多,但是其能实现多端同步以及消息漫游。现代架构中最核心的就是两个消息库『消息同步库』和『消息存储库』,是消息同步和存储最核心的基础。而本篇文章接下来的部分,都是围绕这两个库的设计和实现来展开。

4、Timeline模型


在分析『消息同步库』和『消息存储库』的设计和实现之前,在本章会先介绍一个逻辑模型-Timeline。Timeline模型会帮助我们简化对消息同步和存储模型的理解,而消息库的设计和实现也是围绕Timeline的特性和需求来展开。

现代IM系统中聊天消息的同步和存储方案探讨_2.png
▲ Timeline模型

如图是Timeline模型的一个抽象表述,Timeline可以简单理解为是一个消息队列,但这个消息队列有如下特性:

  • 每个消息拥有一个顺序ID(SeqId),在队列后面的消息的SeqId一定比前面的消息的SeqId大,也就是保证SeqId一定是增长的,但是不要求严格递增;
  • 新的消息永远在尾部添加,保证新的消息的SeqId永远比已经存在队列中的消息都大;
  • 可根据SeqId随机定位到具体的某条消息进行读取,也可以任意读取某个给定范围内的所有消息。

有了这些特性后,消息的同步可以拿Timeline来很简单的实现。图中的例子中,消息发送方是A,消息接收方是B,同时B存在多个接收端,分别是B1、B2和B3。A向B发送消息,消息需要同步到B的多个端,待同步的消息通过一个Timeline来进行交换。A向B发送的所有消息,都会保存在这个Timeline中,B的每个接收端都是独立的从这个Timeline中拉取消息。每个接收端同步完毕后,都会在本地记录下最新同步到的消息的SeqId,即最新的一个位点,作为下次消息同步的起始位点。服务端不会保存各个端的同步状态,各个端均可以在任意时间从任意点开始拉取消息。

消息漫游也是基于Timeline,和消息同步唯一的区别是,消息漫游要求服务端能够对Timeline内的所有数据进行持久化。

基于Timeline,从逻辑模型上能够很简单的理解在服务端如何去实现消息同步和存储,并支持多端同步和消息漫游这些高级功能。落地到实现的难点主要在如何将逻辑模型映射到物理模型,Timeline的实现对数据库会有哪些要求?我们应该选择何种数据库去实现?这些是接下来会讨论到的问题。

5、消息存储模型


现代IM系统中聊天消息的同步和存储方案探讨_3.png
▲ 基于Timeline的消息存储模型

如图是基于Timeline的消息存储模型,消息存储要求每个会话都对应一个独立的Timeline。如图例子所示,A与B/C/D/E/F均发生了会话,每个会话对应一个独立的Timeline,每个Timeline内存有这个会话中的所有消息,服务端会对每个Timeline进行持久化。服务端能够对所有会话Timeline中的全量消息进行持久化,也就拥有了消息漫游的能力。

6、消息同步模型


消息同步模型会比消息存储模型稍复杂一些,消息的同步一般有读扩散和写扩散两种不同的方式,分别对应不同的Timeline物理模型。

现代IM系统中聊天消息的同步和存储方案探讨_4.png
▲ 读扩散和写扩散两种不同同步模式下对应的不同的Timeline模型

如图是读扩散和写扩散两种不同同步模式下对应的不同的Timeline模型,按图中的示例,A作为消息接收者,其与B/C/D/E/F发生了会话,每个会话中的新的消息都需要同步到A的某个端,看下读扩散和写扩散两种模式下消息如何做同步。

读扩散:

消息存储模型中,每个会话的Timeline中保存了这个会话的全量消息。读扩散的消息同步模式下,每个会话中产生的新的消息,只需要写一次到其用于存储的Timeline中,接收端从这个Timeline中拉取新的消息。

优点是消息只需要写一次,相比写扩散的模式,能够大大降低消息写入次数,特别是在群消息这种场景下。但其缺点也比较明显,接收端去同步消息的逻辑会相对复杂和低效。接收端需要对每个会话都拉取一次才能获取全部消息,读被大大的放大,并且会产生很多无效的读,因为并不是每个会话都会有新消息产生。


写扩散:

写扩散的消息同步模式,需要有一个额外的Timeline来专门用于消息同步,通常是每个接收端都会拥有一个独立的同步Timeline,用于存放需要向这个接收端同步的所有消息。

每个会话中的消息,会产生多次写,除了写入用于消息存储的会话Timeline,还需要写入需要同步到的接收端的同步Timeline。在个人与个人的会话中,消息会被额外写两次,除了写入这个会话的存储Timeline,还需要写入参与这个会话的两个接收者的同步Timeline。而在群这个场景下,写入会被更加的放大,如果这个群拥有N个参与者,那每条消息都需要额外的写N次。

写扩散同步模式的优点是,在接收端消息同步逻辑会非常简单,只需要从其同步Timeline中读取一次即可,大大降低了消息同步所需的读的压力。其缺点就是消息写入会被放大,特别是针对群这种场景。


在IM这种应用场景下,通常会选择写扩散这种消息同步模式

IM场景下,一条消息只会产生一次,但是会被读取多次,是典型的读多写少的场景,消息的读写比例大概是10:1。若使用读扩散同步模式,整个系统的读写比例会被放大到100:1。

一个优化的好的系统,必须从设计上去平衡这种读写压力,避免读或写任意一维触碰到天花板。所以IM系统这类场景下,通常会应用写扩散这种同步模式,来平衡读和写,将100:1的读写比例平衡到30:30。

当然写扩散这种同步模式,还需要处理一些极端场景,例如万人大群。针对这种极端写扩散的场景,会退化到使用读扩散。一个简单的IM系统,通常会在产品层面限制这种大群的存在,而对于一个高级的IM系统,会采用读写扩散混合的同步模式,来满足这类产品的需求。采用混合模式,会根据数据的不同类型和不同的读写负载,来决定用写扩散还是读扩散。

7、典型架构设计


现代IM系统中聊天消息的同步和存储方案探讨_xxx.jpg

如上图所示,是一个典型的消息系统架构。

该典型的消息系统架构中包含几个重要组件:

  • 1)端:作为消息的发送和接收端,通过连接消息服务器来发送和接收消息。
  • 2)消息服务器:一组无状态的服务器,可水平扩展,处理消息的发送和接收请求,连接后端消息系统。
  • 3)消息队列:新写入消息的缓冲队列,消息系统的前置消息存储,用于削峰填谷以及异步消费。
  • 4)消息处理:一组无状态的消费处理服务器,用于异步消费消息队列中的消息数据,处理消息的持久化和写扩散同步。
  • 5)消息存储和索引库:持久化存储消息,每个会话对应一个 Timeline 进行消息存储,存储的消息建立索引来实现消息检索。
  • 6)消息同步库:
    写扩散形式同步消息,每个用户的收件箱对应一个 Timeline,同步库内消息不需要永久保存,通常对消息设定一个生命周期。

    新消息会由端发出,通常消息体中会携带消息 ID(用于去重)、逻辑时间戳(用于排序)、消息类型(控制消息、图片消息或者文本消息等)、消息体等内容。

    消息会先写入消息队列,作为底层存储的一个临时缓冲区。消息队列中的消息会由消息处理服务器消费,可以允许乱序消费。消息处理服务器对消息先存储后同步,先写入发件箱 Timeline(存储库),后写扩散至各个接收端的收件箱(同步库)。

    消息数据写入存储库后,会被近实时的构建索引,索引包括文本消息的全文索引以及多字段索引(发送方、消息类型等)。

对于在线的设备,可以由消息服务器主动推送至在线设备端。对于离线设备,登录后会主动向服务端同步消息。每个设备会在本地保留有最新一条消息的顺序 ID,向服务端同步该顺序 ID 后的所有消息。

8、消息库设计


基于Timeline模型,以及Timeline模型在消息存储和消息同步的应用,我们看下消息同步库和消息存储库的设计。

现代IM系统中聊天消息的同步和存储方案探讨_5.png
▲ 基于Timeline的消息库设计

消息同步库:

消息同步库用于存储所有用于消息同步的Timeline,每个Timeline对应一个接收端,主要用作写扩散模式的消息同步。

这个库不需要永久保留所有需要同步的消息,因为消息在同步到所有端后其生命周期就可以结束,就可以被回收。但是如前面所介绍的,一个实现简单的多端同步消息系统,在服务端不会保存有所有端的同步状态,而是依赖端自己主动来做同步。

所以服务端不知道消息何时可以回收,通常的做法是为这个库里的消息设定一个固定的生命周期,例如一周或者一个月,生命周期结束可被淘汰。


消息存储库:

消息存储库用于存储所有会话的Timeline,每个Timeline包含了一个会话中的所有消息。这个库主要用于消息漫游时拉取某个会话的所有历史消息,也用于读扩散模式的消息同步。

消息同步库和消息存储库,对数据库有不同的要求,如何对数据库做选型,在下面会讨论。


9、数据库选型


消息系统最核心的两个库是消息同步库和消息存储库,两个库对数据库有不同的要求:
现代IM系统中聊天消息的同步和存储方案探讨_6.png

总结下来,对数据库的要求有如下几点:

  • 1)表结构设计能够满足Timeline模型的功能要求:不要求关系模型,能够实现队列模型,并能够支持生成自增的SeqId;
  • 2)能够支持高并发写和范围读,规模在十万级TPS;
  • 3)能够保存海量数据,百TB级;
  • 4)能够为数据定义生命周期。

10、本文小结


本文主要介绍了现代IM系统中消息推送和存储架构的实现,基于逻辑的Timeline模型,我们可以很清晰明了的理解整个消息推送和存储的架构。而基于Timeline的消息存储和推送模型,其实不光可以应用在IM消息系统中,还可应用在例如Feeds流、实时消息同步、直播弹幕等场景。

(原文链接:点此进入,有删节和改动)

附录:更多即时通讯技术资料


[1] 网络编程基础资料:
TCP/IP详解 - 第11章·UDP:用户数据报协议
TCP/IP详解 - 第17章·TCP:传输控制协议
TCP/IP详解 - 第18章·TCP连接的建立与终止
TCP/IP详解 - 第21章·TCP的超时与重传
技术往事:改变世界的TCP/IP协议(珍贵多图、手机慎点)
通俗易懂-深入理解TCP协议(上):理论基础
通俗易懂-深入理解TCP协议(下):RTT、滑动窗口、拥塞处理
理论经典:TCP协议的3次握手与4次挥手过程详解
理论联系实际:Wireshark抓包分析TCP 3次握手、4次挥手过程
计算机网络通讯协议关系图(中文珍藏版)
UDP中一个包的大小最大能多大?
Java新一代网络编程模型AIO原理及Linux系统AIO介绍
NIO框架入门(一):服务端基于Netty4的UDP双向通信Demo演示
NIO框架入门(二):服务端基于MINA2的UDP双向通信Demo演示
NIO框架入门(三):iOS与MINA2、Netty4的跨平台UDP双向通信实战
NIO框架入门(四):Android与MINA2、Netty4的跨平台UDP双向通信实战
P2P技术详解(一):NAT详解——详细原理、P2P简介
P2P技术详解(二):P2P中的NAT穿越(打洞)方案详解
P2P技术详解(三):P2P技术之STUN、TURN、ICE详解
通俗易懂:快速理解P2P技术中的NAT穿透原理
高性能网络编程(一):单台服务器并发TCP连接数到底可以有多少
高性能网络编程(二):上一个10年,著名的C10K并发连接问题
高性能网络编程(三):下一个10年,是时候考虑C10M并发问题了
高性能网络编程(四):从C10K到C10M高性能网络应用的理论探索
不为人知的网络编程(一):浅析TCP协议中的疑难杂症(上篇)
不为人知的网络编程(二):浅析TCP协议中的疑难杂症(下篇)
不为人知的网络编程(三):关闭TCP连接时为什么会TIME_WAIT、CLOSE_WAIT
不为人知的网络编程(四):深入研究分析TCP的异常关闭
不为人知的网络编程(五):UDP的连接性和负载均衡
不为人知的网络编程(六):深入地理解UDP协议并用好它
网络编程懒人入门(一):快速理解网络通信协议(上篇)
网络编程懒人入门(二):快速理解网络通信协议(下篇)
网络编程懒人入门(三):快速理解TCP协议一篇就够
网络编程懒人入门(四):快速理解TCP和UDP的差异
>> 更多同类文章 ……

[2] 有关IM/推送的通信格式、协议的选择:
简述传输层协议TCP和UDP的区别
为什么QQ用的是UDP协议而不是TCP协议?
移动端即时通讯协议选择:UDP还是TCP?
如何选择即时通讯应用的数据传输格式
强列建议将Protobuf作为你的即时通讯应用数据传输格式
全方位评测:Protobuf性能到底有没有比JSON快5倍?
移动端IM开发需要面对的技术问题(含通信协议选择)
简述移动端IM开发的那些坑:架构设计、通信协议和客户端
理论联系实际:一套典型的IM通信协议设计详解
58到家实时消息系统的协议设计等技术实践分享
详解如何在NodeJS中使用Google的Protobuf
>> 更多同类文章 ……

[3] 有关IM/推送的心跳保活处理:
应用保活终极总结(一):Android6.0以下的双进程守护保活实践
应用保活终极总结(二):Android6.0及以上的保活实践(进程防杀篇)
应用保活终极总结(三):Android6.0及以上的保活实践(被杀复活篇)
Android进程保活详解:一篇文章解决你的所有疑问
Android端消息推送总结:实现原理、心跳保活、遇到的问题等
深入的聊聊Android消息推送这件小事
为何基于TCP协议的移动端IM仍然需要心跳保活机制?
微信团队原创分享:Android版微信后台保活实战分享(进程保活篇)
微信团队原创分享:Android版微信后台保活实战分享(网络保活篇)
移动端IM实践:实现Android版微信的智能心跳机制
移动端IM实践:WhatsApp、Line、微信的心跳策略分析
>> 更多同类文章 ……

[4] 有关WEB端即时通讯开发:
新手入门贴:史上最全Web端即时通讯技术原理详解
Web端即时通讯技术盘点:短轮询、Comet、Websocket、SSE
SSE技术详解:一种全新的HTML5服务器推送事件技术
Comet技术详解:基于HTTP长连接的Web端实时通信技术
新手快速入门:WebSocket简明教程
WebSocket详解(一):初步认识WebSocket技术
WebSocket详解(二):技术原理、代码演示和应用案例
WebSocket详解(三):深入WebSocket通信协议细节
socket.io实现消息推送的一点实践及思路
LinkedIn的Web端即时通讯实践:实现单机几十万条长连接
Web端即时通讯技术的发展与WebSocket、Socket.io的技术实践
Web端即时通讯安全:跨站点WebSocket劫持漏洞详解(含示例代码)
开源框架Pomelo实践:搭建Web端高性能分布式IM聊天服务器
使用WebSocket和SSE技术实现Web端消息推送
详解Web端通信方式的演进:从Ajax、JSONP 到 SSE、Websocket
>> 更多同类文章 ……

[5] 有关IM架构设计:
浅谈IM系统的架构设计
简述移动端IM开发的那些坑:架构设计、通信协议和客户端
一套海量在线用户的移动端IM架构设计实践分享(含详细图文)
一套原创分布式即时通讯(IM)系统理论架构方案
从零到卓越:京东客服即时通讯系统的技术架构演进历程
蘑菇街即时通讯/IM服务器开发之架构选择
腾讯QQ1.4亿在线用户的技术挑战和架构演进之路PPT
微信后台基于时间序的海量数据冷热分级架构设计实践
微信技术总监谈架构:微信之道——大道至简(演讲全文)
如何解读《微信技术总监谈架构:微信之道——大道至简》
快速裂变:见证微信强大后台架构从0到1的演进历程(一)
17年的实践:腾讯海量产品的技术方法论
移动端IM中大规模群消息的推送如何保证效率、实时性?
现代IM系统中聊天消息的同步和存储方案探讨
>> 更多同类文章 ……

[6] 有关IM安全的文章:
即时通讯安全篇(一):正确地理解和使用Android端加密算法
即时通讯安全篇(二):探讨组合加密算法在IM中的应用
即时通讯安全篇(三):常用加解密算法与通讯安全讲解
即时通讯安全篇(四):实例分析Android中密钥硬编码的风险
即时通讯安全篇(五):对称加密技术在Android平台上的应用实践
即时通讯安全篇(六):非对称加密技术的原理与应用实践
传输层安全协议SSL/TLS的Java平台实现简介和Demo演示
理论联系实际:一套典型的IM通信协议设计详解(含安全层设计)
微信新一代通信安全解决方案:基于TLS1.3的MMTLS详解
来自阿里OpenIM:打造安全可靠即时通讯服务的技术实践分享
简述实时音视频聊天中端到端加密(E2EE)的工作原理
移动端安全通信的利器——端到端加密(E2EE)技术详解
Web端即时通讯安全:跨站点WebSocket劫持漏洞详解(含示例代码)
通俗易懂:一篇掌握即时通讯的消息传输安全原理
>> 更多同类文章 ……

[7] 有关实时音视频开发:
专访微信视频技术负责人:微信实时视频聊天技术的演进
即时通讯音视频开发(一):视频编解码之理论概述
即时通讯音视频开发(二):视频编解码之数字视频介绍
即时通讯音视频开发(三):视频编解码之编码基础
即时通讯音视频开发(四):视频编解码之预测技术介绍
即时通讯音视频开发(五):认识主流视频编码技术H.264
即时通讯音视频开发(六):如何开始音频编解码技术的学习
即时通讯音视频开发(七):音频基础及编码原理入门
即时通讯音视频开发(八):常见的实时语音通讯编码标准
即时通讯音视频开发(九):实时语音通讯的回音及回音消除概述
即时通讯音视频开发(十):实时语音通讯的回音消除技术详解
即时通讯音视频开发(十一):实时语音通讯丢包补偿技术详解
即时通讯音视频开发(十二):多人实时音视频聊天架构探讨
即时通讯音视频开发(十三):实时视频编码H.264的特点与优势
即时通讯音视频开发(十四):实时音视频数据传输协议介绍
即时通讯音视频开发(十五):聊聊P2P与实时音视频的应用情况
即时通讯音视频开发(十六):移动端实时音视频开发的几个建议
即时通讯音视频开发(十七):视频编码H.264、VP8的前世今生
实时语音聊天中的音频处理与编码压缩技术简述
网易视频云技术分享:音频处理与压缩技术快速入门
学习RFC3550:RTP/RTCP实时传输协议基础知识
简述开源实时音视频技术WebRTC的优缺点
良心分享:WebRTC 零基础开发者教程(中文)
开源实时音视频技术WebRTC中RTP/RTCP数据传输协议的应用
基于RTMP数据传输协议的实时流媒体技术研究(论文全文)
声网架构师谈实时音视频云的实现难点(视频采访)
浅谈开发实时视频直播平台的技术要点
还在靠“喂喂喂”测试实时语音通话质量?本文教你科学的评测方法!
实现延迟低于500毫秒的1080P实时音视频直播的实践分享
移动端实时视频直播技术实践:如何做到实时秒开、流畅不卡
如何用最简单的方法测试你的实时音视频方案
技术揭秘:支持百万级粉丝互动的Facebook实时视频直播
简述实时音视频聊天中端到端加密(E2EE)的工作原理
移动端实时音视频直播技术详解(一):开篇
移动端实时音视频直播技术详解(二):采集
移动端实时音视频直播技术详解(三):处理
移动端实时音视频直播技术详解(四):编码和封装
移动端实时音视频直播技术详解(五):推流和传输
移动端实时音视频直播技术详解(六):延迟优化
理论联系实际:实现一个简单地基于HTML5的实时视频直播
IM实时音视频聊天时的回声消除技术详解
浅谈实时音视频直播中直接影响用户体验的几项关键技术指标
如何优化传输机制来实现实时音视频的超低延迟?
首次披露:快手是如何做到百万观众同场看直播仍能秒开且不卡顿的?
实时通信RTC技术栈之:视频编解码
开源实时音视频技术WebRTC在Windows下的简明编译教程
Android直播入门实践:动手搭建一套简单的直播系统
>> 更多同类文章 ……

[8] IM开发综合文章:
移动端IM中大规模群消息的推送如何保证效率、实时性?
移动端IM开发需要面对的技术问题
开发IM是自己设计协议用字节流好还是字符流好?
请问有人知道语音留言聊天的主流实现方式吗?
IM消息送达保证机制实现(一):保证在线实时消息的可靠投递
IM消息送达保证机制实现(二):保证离线消息的可靠投递
如何保证IM实时消息的“时序性”与“一致性”?
一个低成本确保IM消息时序的方法探讨
IM单聊和群聊中的在线状态同步应该用“推”还是“拉”?
IM群聊消息如此复杂,如何保证不丢不重?
谈谈移动端 IM 开发中登录请求的优化
移动端IM登录时拉取数据如何作到省流量?
浅谈移动端IM的多点登陆和消息漫游原理
完全自已开发的IM该如何设计“失败重试”机制?
通俗易懂:基于集群的移动端IM接入层负载均衡方案分享
微信对网络影响的技术试验及分析(论文全文)
即时通讯系统的原理、技术和应用(技术论文)
开源IM工程“蘑菇街TeamTalk”的现状:一场有始无终的开源秀
QQ音乐团队分享:Android中的图片压缩技术详解(上篇)
QQ音乐团队分享:Android中的图片压缩技术详解(下篇)
腾讯原创分享(一):如何大幅提升移动网络下手机QQ的图片传输速度和成功率
腾讯原创分享(二):如何大幅压缩移动网络下APP的流量消耗(上篇)
腾讯原创分享(二):如何大幅压缩移动网络下APP的流量消耗(下篇)
如约而至:微信自用的移动端IM网络层跨平台组件库Mars已正式开源
基于社交网络的Yelp是如何实现海量用户图片的无损压缩的?
>> 更多同类文章 ……

[9] 有关推送技术的文章:
iOS的推送服务APNs详解:设计思路、技术原理及缺陷等
信鸽团队原创:一起走过 iOS10 上消息推送(APNS)的坑
Android端消息推送总结:实现原理、心跳保活、遇到的问题等
扫盲贴:认识MQTT通信协议
一个基于MQTT通信协议的完整Android推送Demo
IBM技术经理访谈:MQTT协议的制定历程、发展现状等
求教android消息推送:GCM、XMPP、MQTT三种方案的优劣
移动端实时消息推送技术浅析
扫盲贴:浅谈iOS和Android后台实时消息推送的原理和区别
绝对干货:基于Netty实现海量接入的推送服务技术要点
移动端IM实践:谷歌消息推送服务(GCM)研究(来自微信)
为何微信、QQ这样的IM工具不使用GCM服务推送消息?
极光推送系统大规模高并发架构的技术实践分享
从HTTP到MQTT:一个基于位置服务的APP数据通信实践概述
魅族2500万长连接的实时消息推送架构的技术实践分享
专访魅族架构师:海量长连接的实时消息推送系统的心得体会
深入的聊聊Android消息推送这件小事
基于WebSocket实现Hybrid移动应用的消息推送实践(含代码示例)
一个基于长连接的安全可扩展的订阅/推送服务实现思路
实践分享:如何构建一套高可用的移动端消息推送系统?
Go语言构建千万级在线的高并发消息推送系统实践(来自360公司)
腾讯信鸽技术分享:百亿级实时消息推送的实战经验
>> 更多同类文章 ……

[10] 更多即时通讯技术好文分类:
http://www.52im.net/forum.php?mod=collection&op=all

即时通讯网 - 即时通讯开发者社区! 来源: - 即时通讯开发者社区!

上一篇:移动端IM中大规模群消息的推送如何保证效率、实时性?下一篇:IM心跳检测时间间隔之间会丢消息怎么处理?

本帖已收录至以下技术专辑

推荐方案
评论 52
深入浅出,学习了
文章写得很好,消息同步库、消息存储库我这边也是这么搞的。模型和流程上也大致一样。 说说不同的点。
消息同步库作者是对每个人有一个Timeline,同一个人的各个端自己控制拉取哪些离线消息。而消息的seq又不是严格递增的。我在实际实施项目过程中,发现这个方式落地会有一些挑战。
1、主要的问题是用户在线情况下,收到一条消息(此时还有些离线消息没有同步),那客户端消息数据的最新seq就是这条在线消息。这可能导致有些离线消息不能同步到客户端。我个人感觉客户端设置一个同步消息的游标能解决这个问题,但是在线收到过的消息,会被重复同步(去重可解决)。
2、同步消息(拉离线)时机和策略问题。要保证这个模型不丢消息,这部分细节也很重要。
版主有作者联系方式吗?很想请教一下
实际项目中,我是为每个端(App,Web)写了一个Timeline,但这个方式在端很多的情况下性能不好。毕竟每个端都要写一份同步数据
引用:封宇_ynOMz 发表于 2017-11-29 11:42
文章写得很好,消息同步库、消息存储库我这边也是这么搞的。模型和流程上也大致一样。 说说不同的点。
消 ...

https://yq.aliyun.com/articles/253242 文中有原文链接,原文上有个钉钉群号码。
引用:封宇_ynOMz 发表于 2017-11-29 11:46
实际项目中,我是为每个端(App,Web)写了一个Timeline,但这个方式在端很多的情况下性能不好。毕竟每个端 ...

所以文中提到了最关键的是存储数据库的选型。
引用:封宇_ynOMz 发表于 2017-11-29 11:42
文章写得很好,消息同步库、消息存储库我这边也是这么搞的。模型和流程上也大致一样。 说说不同的点。
消 ...

原作者其实是在推介阿里云的TableStore这个NoSQL数据库,本文在引用时为了让阅读者不会因广告嫌疑而产生不适,所以把这部分文字删掉了(其实也只是简单介绍TableStore的使用而已,删去并不会影响文章内容的主体思想),你可以了解一下阿里云的TableStore,看看能否给你带来解决问题的灵感。
看了下阿里云的TableStore,解决IM消息推送和存储最核心的功能是 - 自增列。
这个功能解决了IM消息保序的要求,满足了文章中的Timeline中SeqId必须递增的要求,这个要求是最最关键的,现在很多系统都是通过一些约束来绕过去,往往方案效率都不高。
引用:Cap 发表于 2017-11-29 15:57
看了下阿里云的TableStore,解决IM消息推送和存储最核心的功能是 - 自增列。
这个功能解决了IM消息保序的 ...

说的很专业
好文章,收藏了
nice! nice
签名: 又来看看了
消息同步库,只用更新最新一条消息通知就可以了吧,不用把每个消息通知都更新了
学习了
签名: 大家好
很不错的分享,支持群主
引用:封宇_ynOMz 发表于 2017-11-29 11:42
文章写得很好,消息同步库、消息存储库我这边也是这么搞的。模型和流程上也大致一样。 说说不同的点。
消 ...

我个人感觉客户端设置一个同步消息的游标能解决这个问题      你好这个游标概念能传授下吗 我不是很懂啊 谢谢   文章中现在记录的消息是个人收到的消息的最新的timeline,您的意思是用户刚上线离线消息还没有拉取刚好收到一个最新的消息,timeline就是最新的了 再用这个timeline拉取消息是拉取不到的  游标又是怎么解决的呢   
楼主你好  文章感觉很棒  有写地方不是很了解求教下,消息推送库上的问题,当服务端接收到需要发送给A的消息的时候,服务端要检查下A用户是否在线,不在线写入消息推送库。但是如果用户在线情况下是直接推送过去,这个时候还需写入消息推送库吗,   每条消息都检查目标用户是否在线,感觉操作过于频繁 有更好的方法吗
引用:zhangkun 发表于 2018-01-24 11:33
楼主你好  文章感觉很棒  有写地方不是很了解求教下,消息推送库上的问题,当服务端接收到需要发送给A的消 ...

那肯定是要知道是否在线的,因为每个客户端对应一个socket通道,通信必须写入它的通道。
至于性能问题,可以在编码技巧和架构上下功夫,比如用户状态用redis来维护
不理解,10:1,读扩散变成100:1
引用:zhangkun 发表于 2018-01-24 11:25
我个人感觉客户端设置一个同步消息的游标能解决这个问题      你好这个游标概念能传授下吗 我不是很懂啊  ...

这个问题我这边已经解决了,我近期会在我公众号上放出方案。欢迎版主转过来
打赏楼主 ×
使用微信打赏! 使用支付宝打赏!

返回顶部