IM系统如何保证消息顺序性?

文章探讨了在分布式环境中保证消息发送和接收顺序的难点,如时钟不一致和网络延迟。对于单对单聊天,可以通过发送方生成的单调递增序列号或时间戳来标记消息顺序,接收方则根据这些信息按顺序展示。在群聊场景下,建议以服务器接收时间为基准,使用一致性哈希和向量时钟同步时间,处理消息顺序。同时,文章提到了故障恢复和幂等处理策略来应对服务器故障和消息丢失问题。
摘要由CSDN通过智能技术生成

保证消息发送顺序难点来自于

  • 分布式系统下,时钟不一致,没有全局时钟

    多个客户端、服务器之间的时钟可能大相径庭

  • 多客户端,导致接收顺序不一定

    在绝对时序上,若client1先发出msg1,而后client2发出msg2,那么是无法保证msg1一定先于msg2到达

  • 服务集群,难以协调消息顺序

    在绝对时序上,若client发出msg1,而后client发出msg2,那么由于服务器集群存在,是无法保证msg1一定先被接收处理

  • 网络传输与多线程,不保证传输和处理顺序

    在绝对时序上,若client发出msg1,而后client发出msg2,可能网络原因导致msg2反而先到,或者由于多线程处理的存在,导致msg2先被处理

单对单聊天,保证发送与接收顺序一致

发送方标记消息顺序

发送方可以根据发送顺序生成标识来区分顺序,该标识可以是

  • 生成的单调递增序列号

    可以为每个单对单会话生成递增id,唯一的问题可能就是会溢出,但一般也不会溢出,即使溢出处理之后还是能保证顺序性

  • 本地时间戳

保证接收展示顺序

在集群中最关键的是保证尽量按照顺序发送消息给接收方,以及配合接收方保证展示顺序

而接收方要根据传输过来数据去保证展示顺序

  • 保证发送方与集群机器匹配,集群机器保证前一条展示正确后发送后一条

    消息只能一条发完,再发下一条,性能损耗过大

  • 基于每个会话单调递增序列号的情况下,集群不做额外处理直接发给接收方,接收方严格按照顺序展示消息

    比如接收方收到了1、3,那么消息1可以展示,而消息3在消息2没有接收到之前都不可以展示

  • 接收方纠错。若新接收消息顺序早于展示的消息,那么就刷新展示顺序

    给用户展示的消息不具有一致性,这可能会引发误解,但若用户能理解,那么也不失为一个好的解决方法

  • 接收方每条消息等待一定时间后展示。也就是说如果一条消息在一定时间内没有其他消息顺序在其前,那么就直接展示

    时效性较差,并且也无法充分保证顺序

群聊:以服务器接收时间为准

  • 发送者对群聊会话hash到特定服务器x,由x进行统一处理

    由x推送到接收者更好还是发送者拉取?

    个人认为接收者客户端情况可能已经下线了,会产生很多不必要的推送以及维护很多不必要的连接

    如果x出现故障呢?

    那么为了防止消息丢失,只有在所有接收者收到消息后才确定该条消息消费完成,否则在等待一定时间后发现仍未完成,则会重试其他服务器或者直接提示发送失败,并且在接收端做好幂等处理

    但这样做,在存在客户端长期下线的情况下等待周期过长。如果发送者客户端不等待,又容易丢失消息

  • 发送方对群聊会话一致性hash到特定集群group ga中,然后由ga首位服务器s统一处理

    ga中机器如何按照接收时间标记顺序?

    通过比如向量时钟来同步集群中时间,然后通过该时间来标记接收顺序

    s什么时候将消息发送或者被拉取给群聊其他成员?

    • 等待一定时间,按照时间戳进行排序,进行发送

    • 询问ga其他机器是否有更早于已经收到的最晚消息,若没有就推送消息给群聊其他成员

    • 等待客户端拉取消息,将最新消息列表发送过去。若原本最先发送给集群的消息由于网络原因晚同步给s,那么s仍然以s接收到的时间为准

      也就是如果没有任何客户端主动拉取消息,那么s将根据收到消息的时间戳进行排序,但一旦拉取过了,就以s收到消息的时间为准

    如果s出现故障怎么办?

    若服务器x发现s心跳异常,则询问其他集群机器是否认为s异常,如果多数认为异常,标记s下线,交由新首位s1服务器处理(此时还是要求接收客户端进行幂等处理)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值