消息队列-如何保证消息没有重复消费?

面试题

如何保证消息没有重复消费?或者说,如何保证消息消费的幂等性?

考察缘由

消息消费,肯定就要考虑到消息是否被重复消费?能不能避免重复消费?或者重复消费了也别造成系统异常可以吗?这个是 MQ 领域的基本问题,其实本质上还是问你使用消息队列如何保证幂等性,这个是你架构里要考虑的一个问题。

面试题剖析

一、重复消费产生的问题描述

因为消息发送是基于网络发送的,假设网络延迟或者网络卡顿,消息发送机制多次重试,消息重复发送的问题不可避免的发生。要直接避免不重复发送基本太难,因为网络环境无法预知,还会使程序复杂度加大,因此默认允许消息重复发送。因此无论是点对点,还是发布/订阅模型,都可能出现生产者发送多条一样的数据到MQ,此时就会出现重复数据。

二、如何保证消息不被重复消费

基于以上问题描述, MQ 自己保证发送的消息不重复,这就需要我们开发来保证的。

2.1、ActiveMQ

消费者接收到消息时,将消息对象进行MD5加密,作为消息唯一性。如果发现messageObj(发送到mq的数据)已经存在,则忽略,进而保证消息不被重复消费。

String md5 = MD5.encrypt(t.getMessageObj());

List list =super.query("SELECT * FROM message_mq WHERE MD5=? AND STATUS>=? AND STATUS<=? ",this, md5, MessageMq.MessageStatus.MESSAGE_STATUS_NORMAL, MessageMq.MessageStatus.MESSAGE_STATUS_HANDLE);

if (list !=null && list.size() >0) {

log.info("已经有相同消息存在,忽略此消息!!! 【MESSAGE_ID】=" + t.getMessageId() +",【MESSAGE_TYPE】=" + t.getMessageType());

return 0;// 已经有相同的消息

}

幂等性:联想到之前数学学习的幂等性,即使公式:f(x)=f(f(x)) 能够成立的数学性质。用在编程领域,则意为对同一个系统,使用同样的条件,一次请求和重复的多次请求对系统资源的影响是一致的。而计算机幂等性,直白讲就是,就一个数据,或者一个请求,给你重复来多次,你得确保对应的数据是不会改变的,不能出错。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容