服务端IM消息处理经验

   I M的业务场景中消息是最核心且最频繁使用到的,很容易影响客户端的体验,也是通信处理的瓶颈和系统性能瓶颈之处,因此设计好消息的处理方案对IM系统至关重要。在此根据自身的经验和遇到的问题,总结下IM消息的处理思路,希望对读者有所启发。

服务端IM消息功能

单聊消息转发;

群组消息转发;

多终端消息同步;

单聊消息入库存档;

群组消息入库存档;

消息检索;

离线消息;

消息回执;

消息撤回;

消息的扩展及业务类型(群组管理消息、文件消息、公告消息、投票消息等更多的业务类型消息);

移动终端的消息推送等等

关键性问题

消息转发

消息转发延迟问题。消息转发要在耗时的业务逻辑操作之前处理掉,否则得等耗时操作处理完会造成时延。同时,业务处理中耗时的操作会占用业务线程,导致在并发负载高的时候,获取不到空闲的业务线程,消息得不到及时转发。尤其消息入库存档操作,如果消息存档规模达到百万千万级,要进行异步方式进行存档。

如果其它业务(非消息业务)的处理也有比较耗时的操作,不能和消息使用同一个线程池进行处理,因为也会造成获取不到空闲的业务线程来转发消息。这就是及时业务(消息转发)要有线程隔离的机制。

客户端的时钟是不能保证正确的,也是不统一的,所以转发消息要处理消息时间的同步问题,在消息到达服务端时要给消息打上时间戳,这样所有客户端的上展示的消息的时间才能同步。

相同账号登录的多个终端,不管是消息的发送方还是接收方要转发消息。

 

消息存档

消息的存档记录数和占用的磁盘空间都是很大的,如何在不影响查询性能的前提下尽量节约空间是消息存档面临最大的挑战。查询消息很常见都是按用户来,所以按用户来分表是很常见的方案,来降低查询的规模,提高性能。群组消息是一对多的映射,一些协议中(比如xmpp)消息体数据量比较多,如果直接冗余,会给存储空间带来比较大的负担,这并非一定不可行,要根据实际的业务进行评估。另一种方案可以将消息主体和消息的接收者(可带冗余字段)拆开存储,接收者记录做用户映射的分表,主体表可以按其他方式进行分表(比如时间段分表)。

消息检索

消息检索肯定要建索引,但要避免or索引(在实际项目中最早采用or索引造成很大的查询性能问题)。消息查询和离线消息的实现方案有关系,用户登录后,可以由服务端推送离线消息也可以由客户端主动来检索离线消息,这种业务场景下,客户端主动来检索离线消息,如果并发太高,即使在分表和索引优化之后,检索历史消息也可能是非常耗时的操作,有可能会阻塞业务线程池,造成其它业务不能处理,所以这时候检索历史消息也应该要采用异步方式来响应。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章