赞
踩
什么是消息重复消费?首先我们来看一下消息的传输流程。消息生产者–>MQ–>消息消费者;消息生产者发送消息到MQ服务器,MQ服务器存储消息,消息消费者监听MQ的消息,发现有消息就消费消息。
所以消息重复也就出现在 两个阶段
1 :生产者多发送了消息给MQ;
2 :MQ的一条消息被消费者消费了多次。
具体场景如下:
@RabbitListener(queues = "queueName4")//发送的队列名称 @RabbitListener注解到类和方法都可以 @RabbitHandler public void receiveMessage1(Message message) throws UnsupportedEncodingException { //获取唯一id String messageId = message.getMessageProperties().getMessageId(); String msg = new String(message.getBody(),"utf-8"); //获取redis中该队列名称对应的value值 String messageRedisValue = redisUtil.get("queueName4",""); //检验唯一id是否存在 if (messageRedisValue.equals(messageId)) { //存在 return; } System.out.println("消息:"+msg+", id:"+messageId); //以队列为key,id为value redisUtil.set("queueName4",messageId); }
@RabbitListener(queues = "queueName4")//发送的队列名称 @RabbitListener注解到类和方法都可以
@RabbitHandler
public void receiveMessage2(Message message) throws UnsupportedEncodingException {
String messageId = message.getMessageProperties().getMessageId();
String msg = new String(message.getBody(),"utf-8");
//获取
List<String> messageRedisValue = redisUtil.lrange("queueName4");
if (messageRedisValue.contains(messageId)) {
return;
}
System.out.println("消息:"+msg+", id:"+messageId);
redisUtil.lpush("queueName4",messageId);//存入list
}
以消息id为key,消息内容为value存入string中,设置过期时间( 可承受的redis服务器异常时间,比如设置过期时间为10分钟,如果redis服务器断了20分钟,那么未消费的数据都会丢了)
@RabbitListener(queues = "queueName4")//发送的队列名称 @RabbitListener注解到类和方法都可以
@RabbitHandler
public void receiveMessage2(Message message) throws UnsupportedEncodingException {
String messageId = message.getMessageProperties().getMessageId();
String msg = new String(message.getBody(),"utf-8");
String messageRedisValue = redisUtil.get(messageId,"");
if (msg.equals(messageRedisValue)) {
return;
}
System.out.println("消息:"+msg+", id:"+messageId);
//以id为key,消息内容为value,过期时间10分钟
redisUtil.set(messageId,msg,10L);
}
该篇文章介绍了消息重复消费问题及解决方案,问题可能产生的两个阶段(生产消息多发、消费者重复消息);解决方案:将消息发送时携带一个唯一id,消费方拿到消息时先去reids/db中有没有该数据,若没有则可以消费,否则不可以消费;并介绍了基于Redsi解决消息重复消费问题,①以队列名称为key,消息id为value,且value为string类型(适合只有一个消费方)②以队列名称为key,消息id为value,且value为list类型(适合有多个消费方场景)③以消息id为key,内容为value,并设置过期时间
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。