标签:throws 数据库 有一个 tco 返回值 sys str ons 告诉
1.Rabbitmq是如何在接收消息之后将队列中的消息删除呢?
channel.basicConsume("myQueue",true,new DefaultConsumer(channel){})//第二个参数是true,代表的就是接收消息之后自动删除队列中的消息。
手动确认消息是怎么实现的呢?
channel1.basicAck(messageNo,false); //messageNo是消息的队列号。
为什么要使用手动确认消息呢?
这是因为在自动情况下,我们的消费者出现了异常,并没有将消息写入到数据库,但是此时我们队列中的消息就已经删除了,就会出现丢失消息的的情况。
手动确认消息有会有什么危害呢?
队列向消费者重复发送数据,我们需要对重复消息进行处理。插入数据一般使用的是唯一约束,更改数据使用的是版本号。
2.Rabbitmq的重复处理包括哪些方面呢?
1)生产者向队列中重复发送消息。主要原因是网络延迟,导致队列给生产者的响应信息ok没有收到,生产者再次向队列发送一个消息(使用的是发送者确认模式),但是对于这个重复的消息我们是不处理的。
2)消费者从队列中监听到重复消息。对列中的消息被消费者确认后才能删除,手动模式需要消费者告诉队列我已经将消息确认了,可以进行删除了。但是由于网络问题,消费者的响应信息没有按时到达队列,这时队列会在此将消息发送到消息者,(消费者确认模式)这时我们就要进行消息的重复处理了。
3.消息确认模式confrim有什么作用呢?
这个可以保证我们的消息最大可能性的发送到队列中。有漏掉的消息会自动进行补发。
队列接收到消息后,会给生产者一个ok值,如果生产者接收不到这个值,就会再次进行补发。所以队列中可能会有重复的消息。
我们使用的是第三种监听模式,可以根据返回值调用不同的回调函数。
channel.addConfirmListener(new ConfirmListener() {
//handleAck 方法用于消息确认成功后的回调方法
public void handleAck(long l, boolean b) throws IOException {
System.out.println("消息确认成功 消息编号----"+l+" 是否确认多条----"+b);
}
//消息确认失败的回调方法
public void handleNack(long l, boolean b) throws IOException {
System.out.println("消息确认失败----需要补发消息");//这里就是导致队列中出现了重复消息。
}
}
4.什么引起了消息的重复?
想要又重复的消息,前提是我们使用了消息确认模式。要不然只会有漏发的消息,根本不会又重复的消息。
1)是生产者向队列中发送了重复消息,进而导致消费者监听到了两个重复消息。
2)是生产者没有发送重复消息,但是队列却向消费者发送了两个重复消息。
5.如何解决消息的重复呢?
1)使用手动确认消息。
2)根据版本号与唯一约束是重复消息的处理失效。
3)进行消息确认,删除重复的消息。每个消息都有一个序列号,可以根据这个来确定队列总的消息。
标签:throws 数据库 有一个 tco 返回值 sys str ons 告诉
原文地址:https://www.cnblogs.com/pogusanqian/p/13042734.html