IM类系统中,都需要考虑消息时序问题,如果后发送的消息先显示,可能严重扰乱聊天消息所要表达的意义。
消息时序是分布式系统架构设计中非常难的问题,一个分布式的IM系统必须要解决这个问题。
IM系统中主要有两类消息
(1)单聊消息,两个人之间的聊天。需要确保发送方和接收方消息时序展示一致。
(2)群聊消息,一群人在一起聊天。需要确保所有接收方消息顺序一致。
一、为什么会出现时序问题
1、时间不一致。
IM系统存在大量的客户端、IM服务器集群、长连接接入层集群、短连接接入层集群、数据库集群,这些应用分布在不同的机器上,时间很可能不一致,时区也可能不一致。
2、网络传输
网络传输延迟不同。同一用户后发送的消息可能早与先发送的消息到达服务器;不同用户的发送的消息到达服务器的延时差异可能更大。如下图,msg1先发送,msg2后发送。由于网络原因,可能msg2先到达消息服务器
3、服务集群时差
由于IM服务器分布式部署,不同的消息可能路由到不同的逻辑层处理。路由到不同logic的时延不同(尤其是跨机房),且不同logic之间存在微量时差。
4、消息处理速度不一致
服务器收到消息后,不同logic,不同线程对消息的处理速度可能不同,导致投递消息的时序出现错乱。
二、解决办法
以下内容是成本较低的解决办法,在产品快速开发迭代的场景下能够求得质量和效率的平衡。
1、时间同步
确保服务器端各个服务器之间通过NTP协议实现时间同步,确保各个操作系统时区一致。NTP协议基本可以保证各个服务器的时间误差在毫秒级,并且在误差较大时能够出发报警(感谢运维团队)。
2、单聊时序
单聊消息可能出现时序问题如下图
用户1发送消息时,确保每条消息的seq号递增(如果系统重装,需要客户端将seq写成文件保存,重装后能够继续seq递增)。
消息发送到服务器后,因为网络及分布式原因,可能造成服务器接收消息时序错乱
服务器推送消息给用户2,可能因为网络原因再次出现时序错乱。用户2,需要根据seq对消息显示时序进行修正。
注:对于seq归0的情况(比如,记录seq的文件被删除),用户2需要结合timestamp时间及seq,共同判断消息时序
3、群聊消息
群聊不能再利用发送方的seq来保证时序,因为发送方不单点,时间也不一致。
群聊消息以服务器收到发送消息的顺序为准,服务器为每条消息生成时间有序的msgid,客户端以msgid大小顺序来排序即可。
以上是生产环境中的一些实践,该方法在较低成本下,确保了消息时序的一致性。
相关阅读
《一个海量在线用户即时通讯系统(IM)的完整设计》