rabbitmq 消息确认机制
来源:互联网 发布:爰淘宝 编辑:程序博客网 时间:2024/05/22 14:42
rabbitmq的消息确认机制分两部分
一部分是生产端,一部分是消费端
以下都是经过本人亲测得出的结论
环境版本:
RabbitMQ 3.6.3, Erlang 19.0 rabbitmq-java-client-bin-3.6.3
生产端
有两种选择,transaction 和 confirm。
transaction机制
//transaction 机制 channel.txSelect();String msg = "msg test !!!";for(int i=0;i<10000;i++){msg = i+" : msg test !!!";channel.basicPublish(EXCHAGE, QUEUE_NAME,null,msg.getBytes()); System.out.println("publish msg "+msg); if (i>0&&i%100==0){ //批量提交 channel.txCommit(); } } // 若出现异常 进行 channel.txRollback(),对相应批次的msg进行重发或记录 channel.txCommit();
confirm机制
// confirm 机制 异步 通过注册listener,实现异步ack,提高性能 channel.confirmSelect(); // 可以考虑将要发送到MQ的msg记录到SortedSet(TreeSet)中 channel.addConfirmListener(new ConfirmListener() { @Override public void handleAck(long deliveryTag, boolean multiple) throws IOException { System.out.println("+++++++++++++handleAck deliveryTag: " + deliveryTag + ", multiple: " + multiple); if (multiple) { // sortedSet.headSet(deliveryTag + 1).clear(); } else { // sortedSet.remove(deliveryTag); } } @Override public void handleNack(long deliveryTag, boolean multiple) throws IOException { System.out.println("------------handleNack deliveryTag: " + deliveryTag + ", multiple: " + multiple); if (multiple) { // sortedSet.headSet(deliveryTag + 1) toDo 进行重新发送,或记录下来,后续再统一发送; } else { // sortedSet.first(); 进行重新发送,或记录下来,后续再统一发送; } } });
// confirm 机制 同步 channel.confirmSelect();String msg = "msg test !!!";for(int i=0;i<10000;i++){msg = i+" : msg test !!!";channel.basicPublish(EXCHAGE, QUEUE_NAME,null,msg.getBytes()); System.out.println("publish msg "+msg); //此处的 if 是为了实现批量confirm 能比较好的提高性能 if (i>0&&i%100==0){ if(channel.waitForConfirms()){ System.out.println("success publish msg " + (i-100)+" to "+i); }else{ System.out.println("failed publish msg " + (i-100)+" to "+i); i-=100;//此处-100是为了重发,也可以先记录下,之后再进行重发 } }}
confirm 的性能要好于transaction
消费端
首先通过producer往mq中放置了10个msg
然后通过debug断点方式consumer进行消费,但是先不ack,如下
可以看到已经被消费掉了,但是状态还是unacked
后面若一直不执行basicAck,则状态就一直保持不变
再如果我将consumer关掉,则unacked的msg又回到了ready。
这就是consumer的确认机制,来保证把消息真正的处理完后,告诉MQ,让其删除。
若consumer没有ack,则MQ就不会删除,即使consumer死掉,MQ又会把消息发给其他consumer(如果有其他consumer的话)
如下我将consumer干掉,MQ中的消息变成了
我再启动consumer,并进行2个msg的ack后,结果如下图
下图是10msg的ack后
代码中的关键的两处如下,其中注释的两行
private static void revieve() {try {ConnectionFactory factory = new ConnectionFactory();factory.setHost(HOST);factory.setUsername(USERNAME);factory.setPassword(PASSWORD);Connection connection = factory.newConnection();final Channel channel = connection.createChannel();channel.queueDeclare(QUEUE_NAME, false, false, false, null);QueueingConsumer consumer = new QueueingConsumer(channel);//消费消息,其中的false表示需要后面显示的调用basicAck,告诉MQ将msg删除channel.basicConsume(QUEUE_NAME, false, consumer);while (true) {QueueingConsumer.Delivery delivery = consumer.nextDelivery();String msg = new String(delivery.getBody());System.out.println("recieve " + msg);//显示发送ack,只有在前面进行启用显示发送ack机制后才奏效。 false代表是否multiplechannel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);}} catch (Exception e) {e.printStackTrace();}}
上面代码basicAck中的第二个参数若是true,则表示小于等于这个tag的全部发ack,类似于批量ack。本以为这个功能能够提高ack的性能,类似于批量。
但结果不是很明显,我设的批量值是100,我的ack能达到1000/s 左右。不知是我批量值设置问题,还是本身性能就这样。
0 0
- RabbitMQ消息确认机制
- rabbitmq 消息确认机制
- RabbitMQ集群和消息传递确认机制
- RabbitMQ消息队列(九):Publisher的消息确认机制
- RabbitMQ消息队列(九):Publisher的消息确认机制
- RabbitMQ消息队列(九):Publisher的消息确认机制
- RabbitMQ消息队列(九):Publisher的消息确认机制
- RabbitMQ消息队列(九):Publisher的消息确认机制
- RabbitMQ 消息持久化、事务、Publisher的消息确认机制
- RabbitMQ消息队列(九):Publisher的消息确认机制
- RabbitMQ消息队列(九):Publisher的消息确认机制
- RabbitMQ 消息轮询和消息确认机制
- RabbitMQ 消息轮询和消息确认机制
- RabbitMQ消息队列(九):Publisher的消息确认机制
- RabbitMQ消息队列(九):Publisher的消息确认机制
- RabbitMQ消息队列(九):Publisher的消息确认机制
- RabbitMQ(九):Publisher的消息确认机制
- spring rabbitmq 消息确认机制和事务支持
- springboot与jdbc
- 切换
- 数字反转(升级版)
- 解释器模式 详解
- 下拉列表小例子
- rabbitmq 消息确认机制
- numpy module 1 -- Numpy tutorial
- [Cloud Computing]Mechanisms: Endpoint Threat Detection and Response
- 最少硬币问题
- 返回数组最大值
- 排序
- thymeleaf 学习笔记
- php实现session入库操作例子
- 京东首页小例子