订阅者视角的消息重复的产生及应对

一、消息重复产生的原因

消息重复产生主要有两大类原因:

1、消息发送端应用的消息重复发送:

  • 消息发送端发送消息给消息中间件,消息中间件收到消息并成功存储,而这时消息中间件出现问题,导致应用端没有收到消息发送成功的原因,导致消息重复发送。
  • 消息中间件因负载高响应变慢,成功把消息存储到消息存储中后,返回“成功”结果超时。
  • 消息中间件接收消息后成功写入消息存储中,但是在返回结果时网络出现问题,消息发送方重试时,网络恢复,造成消息重复

小结:此类问题都是消息中间件成功将消息写入消息存储中后,返回结果时出现问题,因为有重试机制,造成消息重复

解决方法:重试发送消息时,发送同样的信息,通过幂等避免此类问题

2、消息成功到达消息存储中,消息中间件向外投递消息时重复

  • 消息被投递到消费者应用中进行处理,当处理完毕后,出现问题,处理结果没有通知给消息中间件,消息重复发送
  • 消息被投递到消费者应用中进行处理,当处理完毕后,网络出现问题,处理结果没有通知给消息中间件,消息重复发送
  • 消息被投递到消费者应用中进行处理,因为处理时间较长,超出消息中间件等待时间,消息重复发送
  • 消息被投递到消费者应用中进行处理,当处理完毕后,消息中间件出现问题,造成没有收到处理结果并处理,消息重复发送
  • 消息被投递到消费者应用中进行处理,当处理完毕后,消息中间件收到处理结果,但是消息存储出现问题,造成消息状态未成功更新,消息重复发送

总结:此类问题是消费者接收消息并处理成功后,消息中间件未能及时更改消息状态所造成的。

解决方法:

1)、通过分布式事务进行解决;成本较高

2)、通过幂等避免

 

二、什么是幂等

幂等是一个数学概念,常见于抽象代数中,有两个含义

1、在某二元运算下,幂等元素被自己重复运算(或对于函数是为复合)的结果等于自身结果

2、某一元运算为幂等的时,其两次作用在任一元素后会和其作用一次的结果相同。例:高斯符号

 

例子:

执行一条update sql

update user set age = 18 where user_id = 100;

这个sql无论执行几次user_id 为100 的用户age字段一直都是18,因此这个操作就是幂等的。

下面这条sql

update user set age = age + 1 where user_id = 100;

这个sql每次执行后 age的值都会进行改变,因为这个操作就不是幂等的

因此对消息重复的方法就是,使消费者的处理是一个幂等操作。这种做法降低了消息中间件的整体复杂性,但是也给消费者带来了一定的限制和门槛

 

三、JMS的消息确认方式与消息重复的关系

在JMS中,消费者对收到的消息进行确认,有以下几种方式:

  1. AUTO_ACKNOWLEDGE:自动确认,当消费者接受到消息后,会自动进行确认。这个确认时,有可能处理还没开始或尚未完成,因此这种确认方式是不可靠的。
  2. CLIENT_ACKNOWLEDGE:消费者自己确认,如果需要确认消息消费成功,需要主动调用Message接口的acknowledge()方法进行确认。
  3. DUPS_OK_ACKNOWLEDGE:在消费者的消息处理函数执行结束后进行确认,一方面保证了消息一定是处理结束后进行确认,另一方面是不需要主动调用acknowledge()方法进行确认

从上面几种方式可以看出,消费者对消息的接收会出现以下两种情况:

  1. at least once (至少一次) 也就是消息传递给消费者至少一次,也有可能多次,这种情况类型消息重复发送,采用CLIENT_ACKNOWLEDGE和DUPS_OK_ACKNOWLEDGE这两种方式在处理消息前没有确认的话,有可能会碰见这种情况
  2. at most once (最多一次)当消费者采用AUTO_ACKNOWLEDGE或CLENT_ACKNOWLEDGE方式并在接收消息后就立即确认时会产生的情况,消费者不会再接收到这个消息

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值