Rabbitmq的高级特性
消息如何保证100%投递成功?
什么是生产端的可靠性投递?
1.保障消息的成功发出
2.保障MQ节点的成功接收
3.发送端收到MQ节点(Broker)确认应答
4.完善的消息补偿机制
BAT互联网大厂的解决方案?
1.消息落库,对消息状态进行打标

2.消息的延迟投递,做二次确认,回调检查
优点是消息只持久化一次,对于数据量大的场景性能提升很大。

幂等性机制
海量订单如何避免重复消费问题?
消费端实现幂等性,就意味着,即使我们收到多条一样的消息,最后都会得到同样的结果
1.我们可以借鉴数据库乐观锁机制;
2.比如我们执行一条更新数据库的语句
3.update t_reps set count = count - 1,version = version + 1
where version = 1 业界主流的幂等性操作:
1.唯一ID+指纹码机制,利用数据库主键去重
select count(1) from t_order where id =唯一ID+指纹码
好处:实现简单
坏处:高并发下有数据库写入性能瓶颈
解决方案:根据id进行分库分表进行算法路由
2.利用Redis的原子性去实现
使用redis进行幂等,需要考虑的问题
一、我们是否要进行数据入库,关键解决的问题是数据库和缓存如何做到原子性
二、如果不进行入库,都存到缓存中,如何设置定时同步策略
Confirm消息确认机制
1.消息的确认,是指生产者投递消息后,如果broker收到消息,则会给生产者一个应答
2.生产者进行接收应答,用来确定这条消息是否正常的发送到broker,这种方式也是消息的可靠性投递的核心保障
确认机制流程图:

如何实现confirm确认消息?
1.第一步:在channel上开启确认模式:channel.confirmSelect(),
2.第二步:在channel上添加监听:addConfirmListener,监听成功和失败的返回结果,根据具体的结果对消息进行重新发送、或记录日志等后续处理。
创建生产者
package com.dwz.rabbitmq.confirm; import java.io.IOException;
import java.util.concurrent.TimeoutException; import com.dwz.rabbitmq.util.ConnectionUtils;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.ConfirmListener;
import com.rabbitmq.client.Connection; public class Producer {
public static void main(String[] args) throws IOException, TimeoutException {
Connection connection = ConnectionUtils.getConnection();
Channel channel = connection.createChannel();
//指定我们的消息投递模式:消息确认模式
channel.confirmSelect(); String exchangeName = "test_confirm_exchange";
String routingkey = "confirm.abc";
String msg = "Hello rabbit confirm message!";
channel.basicPublish(exchangeName, routingkey, null, msg.getBytes());
//添加一个确认监听
channel.addConfirmListener(new ConfirmListener() {
//deliveryTag 消息投递标识, multiple 是否批量
@Override
public void handleNack(long deliveryTag, boolean multiple) throws IOException {
System.err.println("-------------no ack--------------");
} @Override
public void handleAck(long deliveryTag, boolean multiple) throws IOException {
System.err.println("-------------ack--------------");
}
}); channel.close();
connection.close();
}
}
创建消费者
package com.dwz.rabbitmq.confirm; import java.io.IOException;
import java.util.concurrent.TimeoutException; import com.dwz.rabbitmq.util.ConnectionUtils;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.rabbitmq.client.AMQP.BasicProperties; public class Consumer {
public static void main(String[] args) throws IOException, TimeoutException {
Connection connection = ConnectionUtils.getConnection();
Channel channel = connection.createChannel(); String exchangeName = "test_confirm_exchange";
String queueName = "test_confirm_queue";
String routingkey = "confirm.#"; channel.exchangeDeclare(exchangeName, "topic", true);
channel.queueDeclare(queueName, true, false, false, null);
channel.queueBind(queueName, exchangeName, routingkey); DefaultConsumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body)
throws IOException {
super.handleDelivery(consumerTag, envelope, properties, body);
System.err.println("消费者收到消息:" + new String(body));
}
}; channel.basicConsume(queueName, consumer);
}
}
Return消息机制
1.Return Listener用于处理一些不可路由的消息!
2.我们的消息生产者,通过指定一个Exchange和Routingkey,把消息送达到某一个队列中去,然后我们的消费者监听队列,进行消费处理操作
3.但是在某些情况下,如果我们在发送消息的时候,当前的Exchange不存在或者指定的路由key路由不到,这个时候如果我们需要监听这种
不可达的消息,就要使用Return Listener。
4.Mandatory:如果为true,则监听器会接受到路由不可达的消息,然后进行后续处理,如果为false,那么broker自动删除该消息
return消息机制流程

创建生产者
package com.dwz.rabbitmq.returnListener; import java.io.IOException;
import java.util.concurrent.TimeoutException; import com.dwz.rabbitmq.util.ConnectionUtils;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ReturnListener; public class Producer {
public static void main(String[] args) throws IOException, TimeoutException {
Connection connection = ConnectionUtils.getConnection();
Channel channel = connection.createChannel(); String exchangeName = "test_return_exchange";
String routingkey = "return.save";
String routingkeyError = "save.abc";
String msg = "Hello rabbit return message!"; channel.addReturnListener(new ReturnListener() {
@Override
public void handleReturn(int replyCode, String replyText, String exchange, String routingKey,
AMQP.BasicProperties properties, byte[] body) throws IOException {
System.err.println("----------handle return-------------");
System.err.println("replyCode:" + replyCode);
System.err.println("replyText:" + replyText);
System.err.println("exchange:" + exchange);
System.err.println("routingKey:" + routingKey);
System.err.println("properties:" + properties);
System.err.println("body:" + new String(body));
}
});
channel.basicPublish(exchangeName, routingkeyError, true, false, null, msg.getBytes());
}
}
创建消费者
package com.dwz.rabbitmq.returnListener; import java.io.IOException;
import java.util.concurrent.TimeoutException; import com.dwz.rabbitmq.util.ConnectionUtils;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.rabbitmq.client.AMQP.BasicProperties; public class Consumer {
public static void main(String[] args) throws IOException, TimeoutException {
Connection connection = ConnectionUtils.getConnection();
Channel channel = connection.createChannel(); String exchangeName = "test_return_exchange";
String routingkey = "return.#";
String queueName = "test_return_queue"; channel.exchangeDeclare(exchangeName, "topic", true);
channel.queueDeclare(queueName, true, false, false, null);
channel.queueBind(queueName, exchangeName, routingkey); DefaultConsumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body)
throws IOException {
super.handleDelivery(consumerTag, envelope, properties, body);
System.err.println("消费者收到消息:" + new String(body));
}
}; channel.basicConsume(queueName, consumer);
}
}
Rabbitmq的高级特性的更多相关文章
- Rabbitmq之高级特性——百分百投递消息&消息确认模式&消息返回模式实现
rabbitmq的高级特性: 如何保障消息的百分之百成功? 要满足4个条件:生产方发送出去,消费方接受到消息,发送方接收到消费者的确认信息,完善的消费补偿机制 解决方案,1)消息落库,进行消息状态打标 ...
- RabbitMQ的高级特性概念理解
1.RabbitMQ中的消息如何保障百分之百的投递成功? 答:百分之百的投递成功,方案可以参考下面的2.3. 2.什么是生产者端的可靠性投递? 答:第一步,生产者保障消息的成功发出.第二步,保障Rab ...
- Rabbitmq之高级特性——实现消费端限流&NACK重回队列
如果是高并发下,rabbitmq服务器上收到成千上万条消息,那么当打开消费端时,这些消息必定喷涌而来,导致消费端消费不过来甚至挂掉都有可能. 在非自动确认的模式下,可以采用限流模式,rabbitmq ...
- RabbitMQ(二):RabbitMQ高级特性
RabbitMQ是目前非常热门的一款消息中间件,不管是互联网大厂还是中小企业都在大量使用.作为一名合格的开发者,有必要了解一下相关知识,RabbitMQ(一)已经入门RabbitMQ,本文介绍Rabb ...
- 消息中间件——RabbitMQ(七)高级特性全在这里!(上)
前言 前面我们介绍了RabbitMQ的安装.各大消息中间件的对比.AMQP核心概念.管控台的使用.快速入门RabbitMQ.本章将介绍RabbitMQ的高级特性.分两篇(上/下)进行介绍. 消息如何保 ...
- 消息中间件——RabbitMQ(八)高级特性全在这里!(下)
前言 上一篇消息中间件--RabbitMQ(七)高级特性全在这里!(上)中我们介绍了消息如何保障100%的投递成功?,幂等性概念详解,在海量订单产生的业务高峰期,如何避免消息的重复消费的问题?,Con ...
- RabbitMQ的基本使用到高级特性
简介 继上一篇 CentOS上安装RabbitMQ讲述RabbitMQ具体安装后,这一篇讲述RabbitMQ在C#的使用,这里将从基本用法到高级特性的使用讲述. 前序条件 这里需要增加一个用户,并且设 ...
- RabbitMQ实战(三)-高级特性
0 相关源码 1 你将学到 如何保证消息百分百投递成功 幂等性 如何避免海量订单生成时消息的重复消费 Confirm确认消息.Return返回消息 自定义消费者 消息的ACK与重回队列 限流 TTL ...
- 消息队列——RabbitMQ的基本使用及高级特性
文章目录 一.引言 二.基本使用 1. 简单示例 2. work queue和公平消费消息 3. 交换机 三.高级特性 1. 消息过期 2. 死信队列 3. 延迟队列 4. 优先级队列 5. 流量控制 ...
随机推荐
- lsof---列出当前系统打开的文件信息
lsof---list open file,一个列出当前系统打开文件的工具 1.lsof查找原理 在Linux系统中,系统为了方便管理进程,会在/proc下为每一个运行中的进程创建一个目录,目录名就是 ...
- C#中判断文件夹或文件是否存在的方法
一.根据虚拟路径获取文件物理路径: string savePath = Server.MapPath("~/Uploads/RemoteDatum/"); 二.判断文件夹是否存在 ...
- [转载]VS2005的工程用VS2010打开后,用VS2005不能打开的解决方法
首先,在“项目”菜单里,把项目属性“目标平台”改为框架2.0,保存退出. 然后,用记事本或用编辑文本文件的方式打开你的项目文件,后缀为.sln 第一行:把“Microsoft Visual Studi ...
- C# WPF集中引用图片等资源的路劲方式
第一内部资源: pack://application:,,,/images/my.jpg 第二 外部程序资源: pack://SiteOfOrigin:,,,/images/my.jpg 需要将资源放 ...
- node jade || ejs引擎模板
1.jade:破坏式2.ejs:保留式 -------------------------------------------------------------------------------- ...
- Vue-----this.$nextTick()
Vue-----this.$nextTick() $nextTick Vue.nextTick()是在下次 DOM 更新循环结束之后执行延迟回调,在修改数据之后使用 $nextTick,则可以在回调中 ...
- Cannot create OpenGL context for 'eglMakeCurrent'.
10.3.2编译的app,在小米手机上出这个问题,华为的正常. 解决方法: 窗口的Quality属性用SystemDefault,不要用HighQuality. 10.3.1也有此问题.
- 怎么处理U盘无法正常弹出的情况?
我们都知道U盘和移动硬盘在使用完毕后需要点击“安全删除硬件并弹出”后才能拔出,这样可以避免U盘还在工作时被拔出而造成的故障. 但有时我们点击“安全删除硬件并弹出”时,系统会提示U盘正在工作,没有办法停 ...
- Linux编译安装GCC
1. 下载gcc安装包 网址:http://ftp.gnu.org/gnu/gcc/ ,下载对应的安装包,我选择gcc-5.5.0.tar.gz 2. 下载依赖库 一个是mpc,一个是gmp,一个是m ...
- Java SE 核心 II【Collection 集合框架】
Collection集合框架 在实际开发中,需要将使用的对象存储于特定数据结构的容器中.而 JDK 提供了这样的容器——集合框架,集合框架中包含了一系列不同数据结构(线性表.查找表)的实现类.集合的引 ...