赞
踩
消费者在消费MQ中的消息时,消费者在ack时网络中断,因此MQ没有接收到确认消息,你们这条消息就会从新发给消费者,但是实际上该消息已经被消费了,故而造成重复消费。
使用全局ID或者UUID每次消费时先判断该消息是否已经消费过。
业务高峰期,生产端可能重复发送了消息,那么消费端就需要实现幂等性来确保一条消息不会被消费多次。
指纹码:根据一定规则生成或者拼接成的唯一信息码,需要保证唯一性,在消费时判断数据库中是否存在当前指纹码,缺点是高并发影响效率。
利用Redis执行setnx。
具有更高优先级的队列具有较高的优先权,优先级高的消息具备优先被消费的特权。
优先级值为0~255
队列和消息都需要设置优先级。只有将多条不同优先级的消息发送到队列中之后才能进行排序。
队列优先级:
Map<String ,Object> argument = new HashMap<>();
argument.put("x-max-priority",10);
channel.queueDeclare(QUEUE_NAME,false,false,false,argument);
消息优先级:
AMQP.BasicProperties properties =
new AMQP.BasicProperties().builder().priority(6).build();
channel.basicPublish("",QUEUE_NAME,properties, msg.getBytes(StandardCharsets.UTF_8));
生产者:
/** * @Description 优先级队列消费者 * @date 2022/3/14 15:16 */ public class Producer { private static final String QUEUE_NAME = "priority_queue"; public static void main(String[] args) throws Exception { Channel channel = RabbitMQUtils.getChannel(); Map<String ,Object> argument = new HashMap<>(); argument.put("x-max-priority",10); channel.queueDeclare(QUEUE_NAME,false,false,false,argument); int priorityVal = 2; for (int j = 0; j < 10; j++) { String msg = "优先队列发送消息,顺序:" + j ; if (j % 2 == 0){ msg += "优先级:" + priorityVal; AMQP.BasicProperties properties = new AMQP.BasicProperties().builder().priority(priorityVal).build(); channel.basicPublish("",QUEUE_NAME,properties, msg.getBytes(StandardCharsets.UTF_8)); priorityVal ++; }else{ channel.basicPublish("",QUEUE_NAME,null, msg.getBytes(StandardCharsets.UTF_8)); } System.out.println("发送成功:" + msg); } System.out.println("----------==========发送完毕==========----------"); } }
接收消息:
显然优先级高的消息先接收到。
惰性队列是RabbitMQ在3.6.0版本提出的,是将消息保存在磁盘中,通常只有在MQ中堆积了大量的消息的时候才会使用惰性队列。
设置方式:
代码:
Map<String,Object> arg = new HashMap<String,Object>();
arg.put("x-queue-mode","lazy");
channel.queueDeclare("quque_name",false,false,false,arg);
端口:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。