8、RabbitMQ-消息的确认机制(生产者)
RabbitMQ 之消息确认机制(事务+Confirm)
https://blog.csdn.net/u013256816/article/details/55515234
概述:
生产者:
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.util.ConnectionUtils;
public class TXsend {
private static final String QUEUE_NAMW = "test_tx_queue"; public static void main(String[] args) throws IOException, TimeoutException {
Connection conn = ConnectionUtils.getConnection();
Channel channel = conn.createChannel(); channel.queueDeclare(QUEUE_NAMW, false, false, false, null); String msg = "tx"; try {
//开启事务模式、
channel.txSelect();
channel.basicPublish("", QUEUE_NAMW, null, msg.getBytes());
//模拟事故
int i = /;
//提交
channel.txCommit();
} catch (Exception e) {
//进行事务回滚
channel.txRollback();
System.out.println("TxRollback...");
}
channel.close();
conn.close();
}
}
消费者:
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.util.ConnectionUtils;
public class TxReceive { private static final String QUEUE_NAMW = "test_tx_queue";
public static void main(String[] args) throws IOException, TimeoutException { Connection conn = ConnectionUtils.getConnection(); Channel channel = conn.createChannel(); //队列声明
channel.queueDeclare(QUEUE_NAMW, false, false, false, null); channel.basicQos(); //绑定队列到交换机转发器 //channel.queueBind(QUEUE_NAMW, "", ""); //定义一个消费者
Consumer consumer = new DefaultConsumer(channel){
//收到消息就会触发这个方法
@Override
public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body)
throws IOException {
String msg = new String(body,"utf-8");
System.out.println("消费者1接收到的消息" + msg); try {
Thread.sleep();
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
System.out.println("消费者1处理完成!");
//手动回执
channel.basicAck(envelope.getDeliveryTag(), false);
}
}
};
//监听队列
//自动应答false
boolean autoAck = false;
channel.basicConsume(QUEUE_NAMW, autoAck, consumer);
}
}
此时消费者不会接收到消息

此种模式还是很耗时的,采用这种方式 降低了 Rabbitmq 的消息吞吐量
Confirm模式
概述
producer 端 confirm 模式的实现原理

开启 confirm 模式的方法 已经在 transaction 事务模式的 channel 是不能再设置成 confirm 模式的,即这两种模式是不能共存的。 生产者通过调用 channel 的 confirmSelect 方法将 channel 设置为 confirm 模式 核心代码:
编程模式
普通模式:
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.util.ConnectionUtils;
public class confirm{
private static final String QUEUE_NAMW = "test_tx_confirm1"; public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
Connection conn = ConnectionUtils.getConnection();
Channel channel = conn.createChannel(); channel.queueDeclare(QUEUE_NAMW, false, false, false, null); //生产者调用confirmSelect,将channel设置为confirm模式
channel.confirmSelect();
String msg = "confirm";
channel.basicPublish("", QUEUE_NAMW, null, msg.getBytes());
if(!channel.waitForConfirms()){
System.out.println("send failed");
}else{
System.out.println("send ok");
}
channel.close();
conn.close();
}
}

import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.util.ConnectionUtils;
public class TXsend {
private static final String QUEUE_NAMW = "test_tx_confirm1";
public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
Connection conn = ConnectionUtils.getConnection();
Channel channel = conn.createChannel();
channel.queueDeclare(QUEUE_NAMW, false, false, false, null);
//1
//生产者调用confirmSelect,将channel设置为confirm模式
channel.confirmSelect();
//2
String msg = "confirm";
//批量发送
for(int i=1;i<=10;i++){
channel.basicPublish("", QUEUE_NAMW, null, msg.getBytes());
}
//3
//确认
if(!channel.waitForConfirms()){
System.out.println("send failed");
}else{
System.out.println("send ok");
}
channel.close();
conn.close();
}
}
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.ConfirmListener;
import com.rabbitmq.client.Connection;
import com.rabbitmq.util.ConnectionUtils;
public class TXsend {
private static final String QUEUE_NAMW = "test_tx_confirm3"; public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
Connection conn = ConnectionUtils.getConnection();
Channel channel = conn.createChannel(); channel.queueDeclare(QUEUE_NAMW, false, false, false, null); //生产者调用confirmSelect,将channel设置为confirm模式
channel.confirmSelect(); //未确认的消息标识
final SortedSet<Long> confirmSet = Collections.synchronizedSortedSet(new TreeSet<Long>()); //频道加一个监听
channel.addConfirmListener(new ConfirmListener() { //回调/重发重试 可以1s之后再发 10s之后再发
@Override
public void handleNack(long deliveryTag, boolean multiple) throws IOException {
if(multiple){
System.out.println("handleNack-----multiple =1");
confirmSet.headSet(deliveryTag+1).clear();;
}else{
System.out.println("handleNack-----multiple =0");
confirmSet.remove(deliveryTag);
}
} //没问题的handleAck
@Override
public void handleAck(long deliveryTag, boolean multiple) throws IOException {
if(multiple){
System.out.println("handleAck-----multiple =1");
confirmSet.headSet(deliveryTag+1).clear();;
}else{
System.out.println("handleAck-----multiple =0");
confirmSet.remove(deliveryTag);
} }
}); String msg = "confirm";
//模拟插入数据
while(true){
long seqNo = channel.getNextPublishSeqNo();
channel.basicPublish("", QUEUE_NAMW, null, msg.getBytes());
confirmSet.add(seqNo);
}
}
}
8、RabbitMQ-消息的确认机制(生产者)的更多相关文章
- (六)RabbitMQ消息队列-消息任务分发与消息ACK确认机制(PHP版)
原文:(六)RabbitMQ消息队列-消息任务分发与消息ACK确认机制(PHP版) 在前面一章介绍了在PHP中如何使用RabbitMQ,至此入门的的部分就完成了,我们内心中一定还有很多疑问:如果多个消 ...
- RabbitMQ消息队列(六)-消息任务分发与消息ACK确认机制(.Net Core版)
在前面一章介绍了在.Net Core中如何使用RabbitMQ,至此入门的的部分就完成了,我们内心中一定还有很多疑问:如果多个消费者消费同一个队列怎么办?如果这几个消费者分任务的权重不同怎么办?怎么把 ...
- JStorm源代码阅读——消息的确认机制
Acker //Acker相当于一个bolt,用于处理事件 public class Acker implements IBolt { private RotatingMap<Object, A ...
- RabbitMQ消息发布和消费的确认机制
前言 新公司项目使用的消息队列是RabbitMQ,之前其实没有在实际项目上用过RabbitMQ,所以对它的了解都谈不上入门.趁着周末休息的时间也猛补习了一波,写了两个窗体应用,一个消息发布端和消息消费 ...
- 十五、.net core(.NET 6)搭建RabbitMQ消息队列生产者和消费者的简单方法
搭建RabbitMQ简单通用的直连方法 如果还没有MQ环境,可以参考上一篇的博客,在windows系统上的rabbitmq环境搭建.如果使用docker环境,可以直接百度一下,应该就一个语句就可以搞定 ...
- 学习ActiveMQ(六):JMS消息的确认与重发机制
当我们发送消息的时候,会出现发送失败的情况,此时我们需要用到activemq为我们提供了消息重发机制,进行消息的重新发送.那么我们怎么知道消息有没有发送失败呢?activemq还有消息确认机制,消费者 ...
- 【转】RabbitMQ基础——和——持久化机制
这里原来有一句话,触犯啦天条,被阉割!!!! 首先不去讨论我的日志组件怎么样.因为有些日志需要走网络,有的又不需要走网路,也是有性能与业务场景的多般变化在其中,就把他抛开,我们只谈消息RabbitMQ ...
- RabbitMQ消息可靠性分析和应用
RabbitMQ流程简介(带Exchange) RabbitMQ使用一些机制来保证可靠性,如持久化.消费确认及发布确认等. 先看以下这个图: P为生产者,X为中转站(Exchange),红色部分为消息 ...
- JMS确认机制
JMS中为数不多的重点就是消息的确认机制,下面分别介绍J2EE和Spring的MessageListenerContainer的确认机制 J2EE中JMS确认机制 在JMS规范中一共4种确认方式 AU ...
- (转)RabbitMQ消息队列(九):Publisher的消息确认机制
在前面的文章中提到了queue和consumer之间的消息确认机制:通过设置ack.那么Publisher能不到知道他post的Message有没有到达queue,甚至更近一步,是否被某个Consum ...
随机推荐
- 字符串匹配问题(lfyzoj)
问题描述 字符串中只含有括号 (),[],<>,{},判断输入的字符串中括号是否匹配.如果括号有互相包含的形式,从内到外必须是<>,(),[],{},例如.输入: [()] 输 ...
- [javaSE] 网络编程(浏览器客户端-自定义服务端)
获取ServerSocket对象,new出来构造参数:int类型端口号 调用ServerSocket对象的accept()方法,得到Socket对象 获取PrintWriter对象,new出来,构造参 ...
- MySQL建表语句的一些特殊字段
这里的字段会不断更新 unsigned 这个字段一般在建表的时候写在Id上,用来表示不分正负号 tinyint 这个字段如果设置为UNSIGNED类型,只能存储从0到255的整数,不能用来储存负数. ...
- 您必须先调用“WebSecurity.InitializeDatabaseConnection”方法,然后再调用"WebSecurity"类的任何其他方法。
今天调试程序的时候出现了这个是,可惜没截图! 您必须先调用“WebSecurity.InitializeDatabaseConnection”方法,然后再调用"WebSecurity&quo ...
- java加载redis以及基本操作
前言: Redis是一款开源的.高性能的键-值存储(key-value store).它常被称作是一款数据结构服务器(data structure server).Redis的键值可以包括字符串(st ...
- C# 调用C/C++动态链接库,结构体中的char*类型
用C#掉用C++的dll直接import就可以之前有不同的类型对应,当要传递结构体的时候就有点麻烦了,这里有一个结构体里边有char*类型,这个类型在C#中调用没法声明,传string是不行的默认st ...
- 牛客Wannafly挑战赛11E 白兔的刁难
传送门 如果大力推单位根反演就可以获得一个 \(k^2logn\) 的好方法 \[ans_{t}=\frac{1}{k}\sum_{i=0}^{k-1}(w_k^{-t})^i(w_k^i+1)^n\ ...
- JavaScript中各存在性函数
JavaScript中有很多表示存在性和从属关系的函数,本文介绍如下几个: 1)有关实例与构造函数原型之间的关系:isPrototypeOf(),Object.getPrototypeOf(); 2) ...
- css,js移动资源
随着移动市场的逐步扩大及相关技术的日趋完善,对前端开发提出了新的岗位要求,在继承前人成果的基础上需要在新的历史条件下有新的创新.移动端的开发,虽然没有IE6众多问题的折磨,但是多平台,多设备的兼容,也 ...
- Ubuntu16.04 安装redis
1. 保证网络畅通,选定好下载工作路径,执行以下命令下载redis-3.2.6: sudo wget http://download.redis.io/releases/redis-3.2.6.tar ...