im消息防重和防丢失以及时序的思路

3 篇文章 0 订阅
2 篇文章 0 订阅

以下六步完成后就能做到消息防丢失

 

案例:客户端A发送消息给客户端B,消息内容任意 如: 你好。交互流程如下图所示:

1.客户端A发送请求包到服务器

这个请求可能会导致丢包,所以前端需要维护一个消息发送队列,如果没有收到2的服务器ack包,则需要重发。这个队列应该是一个数组,多条消息都需要做同样的事

2.服务器给客户端A发送应答包

这个ack包同样可能会丢包,那么跟1丢包的操作一样,需要对消息进行重发。那么就会引起另外的问题,就是消息重复,因为是2丢包,对于服务器来说是收到了1中的消息,只是回复CA过程中因为各种原因丢失了,但是对于CA来说,跟1的请求包丢失得到的结果是一样的,所以需要重发。那么重发后,服务器就得到了两条一致的消息,需要去重,最简单的做法就是客户端来生成唯一的消息id,服务端通过消息id进行去重

3.服务器发送通知给客户端B

3中服务器会将CA的1请求转发给客户端B,同样需要维护消息队列,如果此消息没有确认被收到(也就是4中CB的应答包),也需要重新发送,那么同样的,这里也可能导致CB对于当前消息重复,需要根据消息id进行去重。

4.客户端发送应答包给服务器

这里将收到的通知回复给服务器,如果这个ack包被丢失,那么导致的结果也就是服务器会重新发送消息给CB,CB再重新发出应答ack。所以这里的ack不再需要服务器回复了

5.服务器发送应答包给客户端A

服务器将CB收到消息的回复给CA,目的也就是告诉CA,CB已经收到消息了,通过这个ack进行确认,那么这个时候,这个ack同样需要维护在队列中,等待CA的回复。如果CA在指定时间内没有回复,将重新发送这个ack

6.客户端A发送应答包给服务器

收到5后的ack后,同样发送一个ack给服务器进行确认,如果这条消息丢失,只会重复5的操作,也就是CA会收到重复的ack应答包,而CA再重复发送ack包给服务器即可。

通过上述6个交互流程后,一条消息的防丢失和防重复就做完了。我们也能知道一条消息的发送流程的开始者是客户端,但是最后结束,是在服务端结束的。

那么需要的设计应该是:Qos防丢失/防重复/时序策略

1. 客户端维护一个消息发送队列,队列中消息需要有状态标志

需要重发时:指定时间轮询重新发送

2. 服务端也需要维护一个消息队列,队列中消息同样有状态标志

思考:

1. 上述流程中5,6的目的是什么?能否删减这两个流程

仔细分析后发现,5,6的根本目的是让CA知道CB有没有接收到消息,但是对于服务器来说,是能够知道CB是否已经接收到了消息,如果业务不需要做到这么细致,我和同事认为是可以省略掉这两个步骤的。

2. 为什么让客户端生成id

个人思考:消息涉及到一个时序问题,如果让服务器来确认这个时序,那么可能会导致时序错误。什么是时序?

CA 发送了 "你好" 接着再发送 "我是微笑い一刀" 那么CB收到的消息需要与CA发送的消息顺序一致,这就是时序

那么如果让服务器生成消息id,可能会造成时序错误,理由场景: CA发送 "你好" 但是当前网络环境波动,再发送 "我是微笑い一刀" 时恢复,或者因为多线程问题 后一条消息先到了服务器,那么服务器如果按照顺序或者直接使用数据库来生成,就很有可能出现问题

当然,这个消息id字段并不是那么绝对,也就是不一定选择消息id(一般认为是数据库主键)来作为消息的唯一判断和时序判断,也可以是消息模型的其他的字段来作为去重和时序的判断,也可以把去重和时序判断分为两个不同的字段进行考虑。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

微笑い一刀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值