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条 ...
随机推荐
- PHP基础面试题(1-10)
1.什么是PHP? PHP是一个基于服务端来创建动态网站的脚本语言,可以通过PHP和HTML 生成网站主页. 2.什么是面向对象?主要特征是什么? 面向对象是程序的一种设计方式,利于提高程序的重用性, ...
- php读取xml的神器
<?xml version="1.0 encoding="UTF-8"?> <humans> <zhangying> <name ...
- Android开发:《Gradle Recipes for Android》阅读笔记1.3
想命令行执行gradle的构建,可以通过提供的gradle wrapper或者安装gradle. 构建android项目不需要安装gradle,因为android studio已经包含gradle.& ...
- 回溯法——n后问题
问题描述: 在n*n的棋盘上放置彼此不受攻击的n个皇后.按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子.n后问题等价于在n*n格的棋盘上放置n个皇后,任何2个皇后不放在同一行 ...
- 启发式搜索技术A*
开篇 这篇文章介绍找最短路径的一种算法,它的字我比较喜欢:启发式搜索. 对于入门的好文章不多,而这篇文章就是为初学者而写的,很适合入门的一篇.文章定位:非专业性A*文章,很适合入门. 有图有真相,先给 ...
- EasyNVR智能云终端接入AI视频智能分析功能,用户可自定义接入自己的分析算法
视频分析的需求 人工智能的发展和在行业中的作用就不用多说了,已经到了势在必行的一个程度了,尤其是对于流媒体音视频行业来说,这基本上是人工智能重中之重的领域,视频人工智能,也就是视频视觉分析的应用方式大 ...
- TFS二次开发-基线文件管理器(3)-源码文件的读取
TFS登录成功后,就可以开始读取源码目录树了. 一般来说,我不建议将整个树全部读取出来,因为这里不光存有项目文件,还有项目源码.如果全部读取出会是非常大的一棵树.因此我建议只读出根目录,每一次点击打开 ...
- _utf8_encode _utf8_decode base64_encode base64_decode
const Base64 = { // private property _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv ...
- MySQL事件的先后
今天闲聊之时 提及MySQL事件的执行,发现一些自己之前没有注意的细节 如果在执行事件过程中,如果insert的存储过程发生意外 会如何 USE iot2; CREATE TABLE aaaa (ti ...
- ReentrantLock VS synchronized
ReentrantLock 类实现了 Lock ,它拥有与 synchronized 相同的并发性和内存语义,但是添加了类似锁投票.定时锁等候和可中断锁等候的一些特性. 此外,它还提供了在激烈争用情况 ...