RabbitMQ死信队列
Config:
import java.util.HashMap;
import java.util.Map; import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component; //Fanout 类型 发布订阅模式
@Component
public class FanoutConfig { /**
* 定义死信队列相关信息
*/
public final static String deadQueueName = "dead_queue";
public final static String deadRoutingKey = "dead_routing_key";
public final static String deadExchangeName = "dead_exchange";
/**
* 死信队列 交换机标识符
*/
public static final String DEAD_LETTER_QUEUE_KEY = "x-dead-letter-exchange";
/**
* 死信队列交换机绑定键标识符
*/
public static final String DEAD_LETTER_ROUTING_KEY = "x-dead-letter-routing-key"; // 邮件队列
private String FANOUT_EMAIL_QUEUE = "fanout_email_queue"; // 短信队列
private String FANOUT_SMS_QUEUE = "fanout_sms_queue";
// fanout 交换机
private String EXCHANGE_NAME = "fanoutExchange"; // 1.定义邮件队列
@Bean
public Queue fanOutEamilQueue() {
// 将普通队列绑定到死信队列交换机上
Map<String, Object> args = new HashMap<>(2);
args.put(DEAD_LETTER_QUEUE_KEY, deadExchangeName);
args.put(DEAD_LETTER_ROUTING_KEY, deadRoutingKey);
Queue queue = new Queue(FANOUT_EMAIL_QUEUE, true, false, false, args);
return queue;
} // 2.定义短信队列
@Bean
public Queue fanOutSmsQueue() {
return new Queue(FANOUT_SMS_QUEUE);
} // 2.定义交换机
@Bean
FanoutExchange fanoutExchange() {
return new FanoutExchange(EXCHANGE_NAME);
} // 3.队列与交换机绑定邮件队列
@Bean
Binding bindingExchangeEamil(Queue fanOutEamilQueue, FanoutExchange fanoutExchange) {
return BindingBuilder.bind(fanOutEamilQueue).to(fanoutExchange);
} // 4.队列与交换机绑定短信队列
@Bean
Binding bindingExchangeSms(Queue fanOutSmsQueue, FanoutExchange fanoutExchange) {
return BindingBuilder.bind(fanOutSmsQueue).to(fanoutExchange);
} /**
* 创建配置死信邮件队列
*
* @return
*/
@Bean
public Queue deadQueue() {
Queue queue = new Queue(deadQueueName, true);
return queue;
}
/*
* 创建死信交换机
*/
@Bean
public DirectExchange deadExchange() {
return new DirectExchange(deadExchangeName);
}
/*
* 死信队列与死信交换机绑定
*/
@Bean
public Binding bindingDeadExchange(Queue deadQueue, DirectExchange deadExchange) {
return BindingBuilder.bind(deadQueue).to(deadExchange).with(deadRoutingKey);
} }
生产者 timestamp 设置为0
package com.itmayiedu.rabbitmq; import java.util.UUID; import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import com.alibaba.fastjson.JSONObject; @Component
public class FanoutProducer {
@Autowired
private AmqpTemplate amqpTemplate; public void send(String queueName) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("email", "xx@163.com");
jsonObject.put("timestamp", 0);
String jsonString = jsonObject.toJSONString();
System.out.println("jsonString:" + jsonString);
// 设置消息唯一id 保证每次重试消息id唯一
Message message = MessageBuilder.withBody(jsonString.getBytes())
.setContentType(MessageProperties.CONTENT_TYPE_JSON).setContentEncoding("utf-8")
.setMessageId(UUID.randomUUID() + "").build(); //消息id设置在请求头里面 用UUID做全局ID
amqpTemplate.convertAndSend(queueName, message);
}
}

此时的消费者:
@RabbitListener(queues = "fanout_email_queue")
public void process(Message message, @Headers Map<String, Object> headers, Channel channel) throws Exception {
// 获取消息Id
String messageId = message.getMessageProperties().getMessageId();
String msg = new String(message.getBody(), "UTF-8");
System.out.println("邮件消费者获取生产者消息msg:"+msg+",消息id"+messageId); JSONObject jsonObject = JSONObject.parseObject(msg);
Integer timestamp = jsonObject.getInteger("timestamp"); try {
int result = 1/timestamp;
System.out.println("result"+result);
// // 手动ack
Long deliveryTag = (Long) headers.get(AmqpHeaders.DELIVERY_TAG);
// 手动签收
channel.basicAck(deliveryTag, false);
} catch (Exception e) {
//拒绝消费消息(丢失消息) 给死信队列
channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
} System.out.println("执行结束....");
}
异常状况:

添加死信队列的消费者,并启动后:
package com.itmayiedu.rabbitmq; import java.util.Map; import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.stereotype.Component; import com.rabbitmq.client.Channel; //死信队列
@Component
public class FanoutDeadEamilConsumer { @RabbitListener(queues = "dead_queue")
public void process(Message message, @Headers Map<String, Object> headers, Channel channel) throws Exception {
// 获取消息Id
String messageId = message.getMessageProperties().getMessageId();
String msg = new String(message.getBody(), "UTF-8");
System.out.println("死信邮件消费者获取生产者消息msg:"+msg+",消息id"+messageId);
// // 手动ack
Long deliveryTag = (Long) headers.get(AmqpHeaders.DELIVERY_TAG);
// 手动签收
channel.basicAck(deliveryTag, false); System.out.println("执行结束....");
} }

RabbitMQ死信队列的更多相关文章
- RabbitMQ死信队列另类用法之复合死信
前言 在业务开发过程中,我们常常需要做一些定时任务,这些任务一般用来做监控或者清理任务,比如在订单的业务场景中,用户在创建订单后一段时间内,没有完成支付,系统将自动取消该订单,并将库存返回到商品中,又 ...
- rabbitmq死信队列消息监听
#邮件通知并发送队列消息#!/bin/bash maillog="/var/log/mq.maillog" message_file="/tmp/mq_message&q ...
- RabbitMQ 死信队列 延时
package com.hs.services.config; import java.util.HashMap; import java.util.Map; import org.springfra ...
- 【RabbitMQ】一文带你搞定RabbitMQ死信队列
本文口味:爆炒鱿鱼 预计阅读:15分钟 一.说明 RabbitMQ是流行的开源消息队列系统,使用erlang语言开发,由于其社区活跃度高,维护更新较快,性能稳定,深得很多企业的欢心(当然,也包括我 ...
- springboot rabbitmq 死信队列应用场景和完整demo
何为死信队列? 死信队列实际上就是,当我们的业务队列处理失败(比如抛异常并且达到了retry的上限),就会将消息重新投递到另一个Exchange(Dead Letter Exchanges),该Exc ...
- 【MQ中间件】RabbitMQ -- RabbitMQ死信队列及内存监控(4)
1.RabbitMQ TTL及死信队列 1.1.TTL概述 过期时间TTL表示可以对消息设置预期的时间,在这个时间内都可以被消费者接收获取:过了之后消息将自动被删除.RabbitMQ可以对消息和队列设 ...
- rabbitmq死信队列和延时队列的使用
死信队列&死信交换器:DLX 全称(Dead-Letter-Exchange),称之为死信交换器,当消息变成一个死信之后,如果这个消息所在的队列存在x-dead-letter-exchange ...
- .Net Core&RabbitMQ死信队列
过期时间 RabbitMQ可以为消息和队列设置过期时间Time To Live(TTL).其目的即过期. 消息过期时间 消息存储在队列中时,如果想为其设置一个有限的生命周期,而不是一直存储着,可以为其 ...
- RabbitMq死信队列(接盘侠)
队列创建之后,后期对其修改或者参数添加会报错.需要把队列重新删除,重新创建线上环境不能把队列删除,优雅安全的方式是重新建一个队列,把死信队列相关的队列进行绑定 在有过期时间的队列中设定最大接收能力5条 ...
随机推荐
- cocos2d-x - android 学习(集成NDK、配置开发环境)
先来贴上一大神的博客:日月之明 --- http://www.cnblogs.com/lhming/tag/cocs2d-x/ 需要工具和软件包:Eclipse.Android SDK.Android ...
- Win下httpd+php+mysql环境集成
apache+php+mysql: php下载: VC6就是legacy Visual Studio 6 compiler,就是使用这个编译器编译的, VC9就是the Visual Studio ...
- Android无线测试之—UiAutomator编译与运行测试代码
一.创建build文件 android create uitest-project -n <jars> -t 1 -p <workspace path> 其中-n后面跟的是要发 ...
- 初探webpack之环境配置
先感叹一句,前端的发展真是太快了,ng和bb还没怎么学好就要过时了.现在感觉react当是未来的一个大方向. 以前一直用的grunt,不过前段时间作者已经停止更新了.正好webpack风头正盛,咱也不 ...
- Java类的加载、链接和初始化(个人笔记)
这里看到一篇比较好的文章:http://www.infoq.com/cn/articles/cf-Java-class-loader 这里只是针对什么时候会触发java类的初始化(注意:这里不是说的实 ...
- 【BZOJ2707】[SDOI2012]走迷宫 Tarjan+拓扑排序+高斯消元+期望
[BZOJ2707][SDOI2012]走迷宫 Description Morenan被困在了一个迷宫里.迷宫可以视为N个点M条边的有向图,其中Morenan处于起点S,迷宫的终点设为T.可惜的是,M ...
- 客户端-服务器通信安全 sign key
API接口签名校验,如何安全保存appsecret? - 知乎 https://www.zhihu.com/question/40855191 要保证一般的客户端-服务器通信安全,可以使用3个密钥. ...
- Java基础 - 获取随机数
使用方法 package com.demo5; import java.util.Random; /* * 使用步骤: * A:导包 * import java.util.Random; * B:创建 ...
- 微信小程序-学习总结(1)
微信小程序尺寸单位 rpx单位是微信小程序中css的尺寸单位,rpx可以根据屏幕宽度进行自适应.规定屏幕宽为750rpx. 设备 rpx换算成px(屏幕宽度/750) ...
- 高德地图API使用
1.根据地址找经纬度/修改经纬度 marker.setPosition(result.geocodes[0].location); map.setCenter(marker.getPosition() ...