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 ...
随机推荐
- mongodb启动命令与端口设置
一.mongodb安装和配置 1.创建tools目录,用于存放安装包 cd /usr/local mkdir -p tools cd tools 2.下载mongodb包(其它版本请自行下载) wge ...
- Server concepts 详解
server status 是由 vm_state和task_state 计算出来的,vm_state是虚机当前的稳定状态(例如Active, Error),task_state是虚机当前的瞬间状态( ...
- Python将print输出内容保存到指定文件中
#!/usr/bin/python # -*- coding: utf- -*- import sys import os class Logger(object): def __init__(sel ...
- 025_Excel知识汇总
一.Excel相对引用和绝对应用的区别 加上了绝对地址符“$”的列标和行号为绝对地址,在公式向旁边复制时不会发生变化,没有加上绝对地址符号的列标和行号为相对地址,在公式向旁边复制时会跟着发生变化. 具 ...
- 2018 python获取动态User-Agent
from fake_useragent import UserAgent ua = UserAgent() headers = {'User-Agent': ua.random} print(ua.r ...
- Conv2d常设置参数意义-继续扩展
记录下一些常用设置: 1.下采样 当设置为: nn.Conv2d(nc,ndf,,,,bias=False) kernel_size = 4, stride = 2, padding = 1,就是将特 ...
- 一起学习epoll
epoll 是Linux内核中的一种可扩展IO事件处理机制,最早在 Linux 2.5.44内核中引入,可被用于代替POSIX select 和 poll 系统调用,并且在具有大量应用程序请求时能够获 ...
- [LeetCode] 139. Word Break 单词拆分
Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, determine ...
- [LeetCode] 207. Course Schedule 课程安排
There are a total of n courses you have to take, labeled from 0 to n - 1. Some courses may have prer ...
- [LeetCode] 245. Shortest Word Distance III 最短单词距离 III
This is a follow up of Shortest Word Distance. The only difference is now word1 could be the same as ...