文档章节

rabbitmq 之 ack

zhu_kai1
 zhu_kai1
发布于 01/14 21:41
字数 772
阅读 4
收藏 0

场景1:对于消息处理失败,有可能有由于网络波动导致的数据处理异常,待网络稳定时消息就会正常处理,对于这种处理失败,应该继续尝试去处理消息

场景2:消息重复处理,例如我们通过消息队列向数据库中添加数据,由于数据库网络波动,导致数据库连接超时,而我们的系统认为消息处理失败,就会把消息回滚到消息队列,继续尝试处理,这时就会造成消息重复处理的现象,对于重要的消息,我们可以每处理一条消息,就记录一下,处理新的消息时,进行判断消息是否已经处理,如果已经处理,就丢弃消息 设置firstQueue队列为手动ack处理

   @Bean
    public SimpleMessageListenerContainer simpleMessageListenerContainer_one(){
        SimpleMessageListenerContainer simpleMessageListenerContainer = new SimpleMessageListenerContainer(connectionFactory);
        simpleMessageListenerContainer.addQueues(queueConfig.firstQueue());
        simpleMessageListenerContainer.setExposeListenerChannel(true);
        simpleMessageListenerContainer.setMaxConcurrentConsumers(5);
        simpleMessageListenerContainer.setConcurrentConsumers(1);
        simpleMessageListenerContainer.setAcknowledgeMode(AcknowledgeMode.MANUAL); //设置确认模式手工确认
        simpleMessageListenerContainer.setMessageListener(firstConsumer);
        return simpleMessageListenerContainer;
    }


 生产者

 public void send(String uuid,Object message) {
        CorrelationData correlationId = new CorrelationData(uuid);
        for (int i = 0; i < 5; i++) {
            rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE, RabbitMqConfig.ROUTINGKEY1,
                    (Object) (String.valueOf(message)+i), correlationId);
        }
    }


未确认ack的消费者 

@Component
public class FirstConsumer implements ChannelAwareMessageListener {
    @Override
    public void onMessage(Message message, Channel channel) throws Exception {

        String msg = new String(message.getBody());
       
        // 处理消息
        System.out.println("FirstConsumer {} handleMessage :"+msg);
    }
}

执行结果,发现只消费了一条(但是未ack)

由于未确认ack,故在rabbitmq的界面上看到的firstQueue队列的信息见下图

从图中看到队列中有5个消息,unacked(表示未ack确认的有一个),还有四个准备中,消息就算程序收到了 但是未确认ACK导致消息服务器以为他是未成功消费的 后续还会再发。

此时发现程序重启,有接受到了ss0的这条数据。

手动确认ack消费者

@Component
public class FirstConsumer implements ChannelAwareMessageListener {
    @Override
    public void onMessage(Message message, Channel channel) throws Exception {

        // 每次只接收一个信息
        channel.basicQos(1);
        String msg = null;
        try {
             msg = new String(message.getBody());
            //告诉服务器收到这条消息 已经被我消费了 可以在队列删掉 这样以后就不会再发了 否则消息服务器以为这条消息没处理掉 后续还会在发
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
            if (msg.equals("ss1")){
                channel.basicPublish(message.getMessageProperties().getReceivedExchange(), message.getMessageProperties().getReceivedRoutingKey(),
                        MessageProperties.PERSISTENT_TEXT_PLAIN, "重新放入队列中的数据".getBytes());
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("FirstConsumer  consumer fail");
            // 丢弃信息
            channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,false);
        }
        // 处理消息
        System.out.println("FirstConsumer {} handleMessage :"+msg);
    }
}

打断点查看下

 

此时有断点,再次去rabbitmq的界面查看如图

此时会发现,队列中只有2个消息了,还有一个未ack(因为打断点了),故需要手动调用channel.basicAck告知服务器,消费者已经消费了可以从队列中删除了。

© 著作权归作者所有

共有 人打赏支持
zhu_kai1
粉丝 5
博文 33
码字总数 30110
作品 0
私信 提问
RabbitMQ死循环-延长ACK时间

一、应用背景   今天做一个需求,要将RabbitMQ中的任务取出并执行,为防止任务执行期间出错,设置NO_ACK=FALSE标志,这样、一旦任务没有应答的话,相应的任务就会被RabbitMQ自动Re-Queue,...

ITACHl
2018/08/08
0
0
【转载】关于RabbitMQ的消息确认

RabbitMQ 将消息投递到客户端后,客户端如果没处理完这个消息就死掉了,这个消息还会不会存在?这取决于 RabbitMQ 的消息确认机制(Message acknowledgment)是否打开。 为了确保消息不会丢失...

摩云飞
2012/11/27
0
0
(六)RabbitMQ消息队列-消息任务分发与消息ACK确认机制(PHP版)

在前面一章介绍了在PHP中如何使用RabbitMQ,至此入门的的部分就完成了,我们内心中一定还有很多疑问:如果多个消费者消费同一个队列怎么办?如果这几个消费者分任务的权重不同怎么办?怎么把...

Super_RD
2017/04/26
0
0
请教有关RabbitMQ消息确认的问题!

@摩云飞 你好,想跟你请教个问题: 下面是RabbitMQ的消息确认机制: “为了确保消息不会丢失,RabbitMQ支持消息确认机制。客户端在接受到消息并处理完后,可以发送一个ack消息给RabbitMQ,告...

庆沉
2014/01/02
8.8K
4
rabbitmq——prefetch count

消费者在开启acknowledge的情况下,对接收到的消息可以根据业务的需要异步对消息进行确认。 然而在实际使用过程中,由于消费者自身处理能力有限,从rabbitmq获取一定数量的消息后,希望rabbi...

hncscwc
2014/01/24
0
1

没有更多内容

加载失败,请刷新页面

加载更多

看过上百部片子的这个人教你视频标签算法解析

本文由云+社区发表 随着内容时代的来临,多媒体信息,特别是视频信息的分析和理解需求,如图像分类、图像打标签、视频处理等等,变得越发迫切。目前图像分类已经发展了多年,在一定条件下已经...

腾讯云加社区
25分钟前
0
0
2. 红黑树

定义:红黑树(Red-Black Tree,简称R-B Tree),它一种特殊的二叉查找树(Binary Search Tree)。 要理解红黑树,先要了解什么是二叉查找树。在上一章中,我们学习了什么是二叉树,以及二叉树...

火拳-艾斯
26分钟前
0
0
input的button类型,点击页面跳转

一、input type=button 不做任何操作 例如: <input type="button" class="btn btn-primary" style="width: 30%" value="返回" onclick="window.location.href='/users/list'"></input> onc......

Sunki
32分钟前
0
0
踩坑:js 小数运算出现精度问题

背景 在学习小程序商城源码时发现了这个问题,单价可能出现小数,小数之间运算结果会莫名其妙多出一大串数字,比如下面这样👇。 在此之前我是知道 js 中著名的 0.1 + 0.2 != 0.3 的问题的,...

dkvirus
37分钟前
0
0
zookeeper和HBASE总结

zookeeper快速上手 zookeeper的基本功能和应用场景 zookeeper的整体运行机制 zookeeper的数据存储机制 数据存储形式 zookeeper中对用户的数据采用kv形式存储 只是zk有点特别: key:是以路径...

瑞查德-Jack
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部