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条 ...
随机推荐
- gitlab报错收集
登录502报错 一般是权限问题,解决方法: /var/log/gitlab 如果还不行,请检查你的内存,安装使用GitLab需要至少4GB可用内存(RAM + Swap)! 由于操作系统和其他正在运行 ...
- Android自定义Button字体颜色和背景颜色
http://blog.csdn.net/breeze666/article/details/7747649
- [Noip2016]天天爱跑步 LCA+DFS
[Noip2016]天天爱跑步 Description 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.?天天爱跑步?是一个养成类游戏,需要玩家每天按时上线,完成打卡任 ...
- SharePoint服务器端对象模型 之 序言
对于刚刚开始接触SharePoint的开发人员,即使之前有较为丰富的ASP.NET开发经验,在面对SharePoint时候可能也很难找到入手的方向.对于任何一种开发平台而言,学习开发的过程大致会包括: ...
- 时间格式化输出strtime
The format argument consists of one or more codes; as in printf, the formatting codes are preceded b ...
- 通过margin负值去除padding
.pay-type { // 图片布局前通过margin负值去除padding margin: 0 -@page-padding-horizontal; display: inline-flex; } ...
- redis add 'vm.overcommit_memory = 1' to /etc/sysctl.conf
w root@well:/etc# vim sysctl.conf #kernel.domainname = example.com # # /etc/sysctl.conf - Configurat ...
- 使用jquery获取单选按钮radio的值
<input type="radio" name="gender" value="男" >男</input> < ...
- Unity字体文件放Resources和打成ab对比
情况一:公共字体打成ab的时候,加载A界面的时候加载了font的ab,卸载A和font的ab后,接着加载B界面,加载了font的ab,卸载B和font的ab,这时候字体对应的asset会在内存里有两份 ...
- 从SignalTap II中获取“最真实”的仿真测试向量(ZZ)
在实际工作中,经常会遇到这样的情况:在硬件调试中采用SignalTap II反复多次编译并最终捕获到问题的原因时,才会发现,原来这个问题是逻辑问题,是可以在仿真环境下发现并快速解决的.先前没 ...