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 ...
随机推荐
- 【洛谷】P5024 保卫王国 (倍增)
前言 传送门 很多人写了题解了,我就懒得写了,推荐一篇博客 那就分享一下我的理解吧(说得好像有人看一样 对于每个点都只有选与不选两种情况,所以直接用倍增预处理出来两种情况的子树之内,子树之外的最值,最 ...
- 差分形式的牛顿插值法(c++)
本程序对cosx函数进行插值,取步长为0.1,因此x的值为0.00,0.10,0.20,0.30,对应的y值为cos(0.00),cos(0.10),cos(0.20),cos(0.30),其实本程序 ...
- 剑指offer:字符流中第一个不重复的字符
题目描述: 请实现一个函数用来找出字符流中第一个只出现一次的字符.例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g".当从该字符流中读 ...
- vue 创建监听,和销毁监听(addEventListener, removeEventListener)
最近在做一个有关监听scroll的功能, 发现我添加监听之后一直不起作用: 1 2 mounted() { window.addEventListener("scroll" ...
- 005 vue路由
一:元素的获取 1.ref元素获取 可以通过ref获取DOm,也可以获取组件的引用 <!DOCTYPE html> <html lang="en"> < ...
- 【原创】MongoDB安装配置详解(标注两个坑)
1.下载安装 3.4正式版([坑]不要最新版,有可能进度卡在这个位置不动,等了半个小时也没什么反映,) http://downloads.mongodb.org/win32/mongodb-win32 ...
- IfcWallStandardCase 构件吊装模拟
wall_node = (osg::Node*)(index_node->clone(osg::CopyOp::DEEP_COPY_ALL));vc_mobileCrane->tranMo ...
- WMS常用命令
- ---iOS开发 截取字符串中两个指定字符串中间的字符串---
例如,要截取一个字符串中,两个指定字符串中间的字符串,OC截取方法如下: // 要截取 "> 和 </ 之间的汉字内容: @implementationViewControlle ...
- EasyNVR摄像机网页直播之问题解决:Failed:SYSTEM\CurrentCont......\Application\EasyNVR_Service registry key already
背景分析 经常使用EasyNVR产品的用户都知道,作为音视频行业互联网直播产品,EasyNVR主要功能在于通过RTSP/ONvif协议,接入前端音视频采集设备,通过EasyNVR软硬件产品将拉取过来的 ...