RabbitMQ实战-死信队列
场景说明
场景: 当队列的消息未正常被消费时,如何解决?
- 消息被拒绝并且不再重新投递
- 消息超过有效期
- 队列超载
方案: 未被消费的消息,可通过"死信队列"重新被消费
死信队列含义,发生以上情况时,该队列上的消息,可通过配置转发到死信队列,被重新消费
模拟实现:
- 1个生产者,2个交换机和队列(普通和死信),1个消费者(死信消费者)
- 通过消息超时,模拟未正常消费场景
- 启动死信队列消费者,等待消息...
- 启动生产者,绑定死信队列并发送消息
- 消息超时后,由死信队列消费者消费
代码实现
简单的Util
package com.lyf.springboot.utils;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
public class MqUtil {
private static Connection connection = null;
private static Channel channel = null;
/**
* 获取channel
* @return
*/
public static Channel getChannel(){
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.37.200");
factory.setUsername("lyf");
factory.setPassword("123456");
factory.setVirtualHost("/lyf");
try {
connection = factory.newConnection();
channel = connection.createChannel();
} catch (IOException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
return channel;
}
/**
* 关闭channel和connection
*/
public static void close(){
try {
if(channel != null){
channel.close();
}
if(connection != null){
connection.close();
}
} catch (IOException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
}
}
生产者
package com.lyf.springboot.mq;
import com.lyf.springboot.utils.MqUtil;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class Sender {
private static String QUEUE_NAME="hello";
private static String EXCHANGE_NAME="exchange";
private static String DL_EXCHANGE_NAME="dl_exchange";
public static void main(String []args) throws IOException {
Channel channel = MqUtil.getChannel();
// 普通队列
channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.TOPIC);
Map<String, Object> arguments = new HashMap<>();
/*--------------↓↓↓最关键一步,设置队列的死信队列↓↓↓----------------*/
// x-dead-letter-exchange属性用于指定死信队列
arguments.put("x-dead-letter-exchange", DL_EXCHANGE_NAME);
channel.queueDeclare(QUEUE_NAME,false,false,false,arguments);
/*--------------↑↑↑最关键一步,设置队列的死信队列↑↑↑----------------*/
channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,"info");
// 设置超时时间5000ms
AMQP.BasicProperties properties = new AMQP.BasicProperties().builder().expiration("5000").build();
String msg = "hello";
channel.basicPublish(EXCHANGE_NAME, "info", properties, msg.getBytes());
System.out.println("Se: " + msg);
MqUtil.close();
}
}
消费者
package com.lyf.springboot.mq;
import com.lyf.springboot.utils.MqUtil;
import com.rabbitmq.client.*;
import java.io.IOException;
public class Dl_Reciver {
private static String DL_EXCHANGE_NAME="dl_exchange";
private static String DL_QUEUE_NAME="dl_hello";
public static void main(String []args) throws IOException {
Channel channel = MqUtil.getChannel();
channel.exchangeDeclare(DL_EXCHANGE_NAME, BuiltinExchangeType.TOPIC);
channel.queueDeclare(DL_QUEUE_NAME,false,false,false,null);
channel.queueBind(DL_QUEUE_NAME,DL_EXCHANGE_NAME,"#");
// 消费者
DefaultConsumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
String msg = new String(body, "utf-8");
System.out.println("DL_Re: " + msg);
}
};
channel.basicConsume(DL_QUEUE_NAME,false,consumer);
}
}
启动顺序: 先启动消费者监听,后启动生产者.消息5s后被死信队列消费
参考:
RabbitMQ实战-死信队列的更多相关文章
- RabbitMQ配置死信队列
死信队列 消息传输过程中难免会产生一些无法及时处理的消息,这些暂时无法处理的消息有时候也是需要被保留下来的,于是这些无法被及时处理的消息就变成了死信. 既然需要保留这些死信,那么就需要一个容器来存储它 ...
- RabbitMQ之死信队列
1:何为死信队列 死信队列也是一个正常的队列,可以被消费. 但是,死信队列的消息来源于其他队列的转发. 2:如何触发死信队列 1:消息超时 2:队列长度达到极限 3:消息被拒绝消费,并不再重进队列,且 ...
- 【RabbitMQ】一文带你搞定RabbitMQ死信队列
本文口味:爆炒鱿鱼 预计阅读:15分钟 一.说明 RabbitMQ是流行的开源消息队列系统,使用erlang语言开发,由于其社区活跃度高,维护更新较快,性能稳定,深得很多企业的欢心(当然,也包括我 ...
- RabbitMQ死信队列另类用法之复合死信
前言 在业务开发过程中,我们常常需要做一些定时任务,这些任务一般用来做监控或者清理任务,比如在订单的业务场景中,用户在创建订单后一段时间内,没有完成支付,系统将自动取消该订单,并将库存返回到商品中,又 ...
- 【RabbitMQ 实战指南】一 死信队列
1.死信队列 DLX,全称为 Dead-Letter-Exchange,可以称之为死信交换器.当消息在一个队列中变成死信(dead message)之后,它能被发送到另一个交换器中,这个交换器就是DL ...
- 【RabbitMQ 实战指南】一 延迟队列
1.什么是延迟队列 延迟队列中存储延迟消息,延迟消息是指当消息被发送到队列中不会立即消费,而是等待一段时间后再消费该消息. 延迟队列很多应用场景,一个典型的应用场景是订单未支付超时取消,用户下单之后3 ...
- RabbitMQ使用 prefetch_count优化队列的消费,使用死信队列和延迟队列实现消息的定时重试,golang版本
RabbitMQ 的优化 channel prefetch Count 死信队列 什么是死信队列 使用场景 代码实现 延迟队列 什么是延迟队列 使用场景 实现延迟队列的方式 Queue TTL Mes ...
- rabbitmq实现延时队列(死信队列)
基于队列和基于消息的TTL TTL是time to live 的简称,顾名思义指的是消息的存活时间.rabbitMq可以从两种维度设置消息过期时间,分别是队列和消息本身. 队列消息过期时间-Per-Q ...
- RabbitMQ 死信队列 延时
package com.hs.services.config; import java.util.HashMap; import java.util.Map; import org.springfra ...
随机推荐
- JavaScript中class类的介绍
class的概念 一.我们为什么要用到class类? 因为通过class类来创建对象,使得开发者不必写重复的代码,以达到代码复用的目的.它基于的逻辑是,两个或多个对象的结构功能类似,可以抽象出一个模板 ...
- Java中在时间戳计算的过程中遇到的数据溢出问题
背景 今天在跑定时任务的过程中,发现有一个任务在设置数据的查询时间范围异常,出现了开始时间戳比结束时间戳大的奇怪现象,计算时间戳的代码大致如下. package com.lingyejun.authe ...
- 20189220 余超《Linux内核原理与分析》第四周作业
构造一个简单的Linux系统MenuOS 第三章基础知识 计算机的三大法宝:存储计算机,函数调用堆栈,中断. 操作系统的两把宝剑:中断上下文,进程上下文. Linux内核源码的目录结构: arch目录 ...
- python复合数据类型以及英文词频统计
这个作业的要求来自于:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE1/homework/2753. 1.列表,元组,字典,集合分别如何增删改查及遍历. 列 ...
- Spring MVC JSON乱码问题
之前项目中也遇到过返回JSON时乱码问题,当时找到了一个方法解决了问题但是没有明白原因,今天这个项目又遇到了JSON乱码问题,用之前的方法不行,看了这篇博文才明白为什么 @RequestMapping ...
- openstack重设虚拟机实例密码
目录结构: 引出 采用 nova get-password 方式 采用 libvirt-set-admin-password 采用 nova rebuild instance 的方式 采用 cloud ...
- ActiveMQ消息中间件的作用以及应用场景
ActiveMQ消息中间件的作用以及应用场景 一.ActiveMQ简介 ActiveMQ是Apache出品,最流行的,能力强劲的开源消息总线.ActiveMQ是一个完全支持JMS1.1和J2EE1.4 ...
- 001 okhttp3的POST使用
继续使用上面的项目 1.被调用的项目 package com.jun.web2forokhttp.okhttp; import com.jun.web2forokhttp.bean.HttpDomai ...
- 带空格的 jquery ID 选择器
当 DOM ID有一个空格时,如何使用 jquery 的 ID 选择器? 例如,我的 DOM ID 是 <div id="content Module">Stuff&l ...
- [译]Pandas列数据展示不全解决方法?
Pandas数据展示列太多会显示...不显示具体数据. 设置参数可以显示全部数据: pd.set_option('display.expand_frame_repr', False)