--------------------好记性不如烂笔头---------------------------

windows 环境,使用 rabbit Mq 需要安装, erl   和  rabbit Mq

1.erl 安装完需要配置环境变量

2.查询 erl 是否安装好,cmd-->erl -version

erl -version
3.MQ 安装目录下
D:\anzhuang\rabbitmq_server-3.8.9\sbin
启动 :cmd-->rabbitmq-server

访问:http://localhost:15672/#/

guest/guest (用户名/密码)

--以上可以登录,进行下面操作,配置文件

spring:


rabbitmq:
host: localhost
port: 5672
virtualHost: /
username : guest
password : guest
listener:
simple:
acknowledge-mode: manual

pom文件
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

配置类

package com.example.servicebuy.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
* Created by qiuzhijie.
* Date: 2019-01-07
* 备注: mq config information
*/
@Configuration
public class RabbitMQConfig {

private Logger log = LoggerFactory.getLogger(this.getClass());
@Value("${spring.rabbitmq.host}")
private String HOST;
@Value("${spring.rabbitmq.port}")
private Integer PORT;
@Value("${spring.rabbitmq.virtualHost}")
private String VIRTUALHOST;
@Value("${spring.rabbitmq.username}")
private String USERNAME;
@Value("${spring.rabbitmq.password}")
private String PASSWORD;

@Bean
public CachingConnectionFactory connectionFactory() {
log.info("RabbitMQ链接信息:{},{},{},{}", HOST, PORT, USERNAME, PASSWORD);
CachingConnectionFactory connectionFactory = new CachingConnectionFactory(this.HOST, this.PORT);

connectionFactory.setUsername(this.USERNAME);
connectionFactory.setPassword(this.PASSWORD);
connectionFactory.setVirtualHost(this.VIRTUALHOST);
log.info("RabbitMQ连接成功");

return connectionFactory;

}

/**
* 死信队列交换机标识符 属性值不能改,写死
*/
private static final String DEAD_LETTER_QUEUE_KEY = "x-dead-letter-exchange";
/**
* 死信队列交换机绑定键 标识符 属性值不能改,写死
*/
private static final String DEAD_LETTER_ROUTING_KEY = "x-dead-letter-routing-key";

/**
* deadLetterExchange(direct类型交换机)
*
* @return
*/
@Bean("deadLetterExchange")
public Exchange deadLetterExchange() {
return ExchangeBuilder.directExchange("DEAD_LETTER_EXCHANGE").durable(true).build();
}

/**
* 声明一个死信队列
* x-dead-letter-exchange 对应 死信交换机
* x-dead-letter-routing-key 对应 死信队列
*/
@Bean("deadLetterQueue")
public Queue deadLetterQueue() {
//应该像个普通队列,里面多设置了两个参数,这个队列没有被消费或者超时 则通过x-dead-letter-exchange 指明重新回到死信交换机 TEST_SIGN_EXCHANGE
//交换机
// 参数
Map<String, Object> args = new HashMap<>(2);
// 出现dead letter之后将dead letter重新发送到指定exchange
args.put(DEAD_LETTER_QUEUE_KEY, "DEAD_LETTER_EXCHANGE");
// 出现dead letter之后将dead letter重新按照指定的routing-key发送
args.put(DEAD_LETTER_ROUTING_KEY, "REDIRECT_KEY");
// name队列名字 durable是否持久化,true保证消息的不丢失, exclusive是否排他队列,如果一个队列被声明为排他队列,该队列仅对首次申明它的连接可见,并在连接断开时自动删除, autoDelete如果该队列没有任何订阅的消费者的话,该队列是否会被自动删除, arguments参数map
return new Queue("DEAD_LETTER_QUEUE", true, false, false, args);
}

/**
* 死信路由通过 DEAD_LETTER_KEY 绑定到死信队列上.
*/
@Bean
public Binding deadLetterBinding() {
return new Binding("DEAD_LETTER_QUEUE", Binding.DestinationType.QUEUE, "DEAD_LETTER_EXCHANGE", "DEAD_LETTER_KEY", null);

}

/**
* 死信路由通过 REDIRECT_KEY 绑定到转发队列上. 这个队列绑定的是当出现死信消息后 重新转发给的队列
*/
@Bean
public Binding redirectBinding() {
return new Binding("REDIRECT_QUEUE", Binding.DestinationType.QUEUE, "DEAD_LETTER_EXCHANGE", "REDIRECT_KEY", null);
}
/**
* 定义死信队列转发队列. (和普通队列一样,这个队列是为了原有的消息没有被消费重新转发给一个新的队列)
*/
@Bean("redirectQueue")
public Queue redirectQueue() {
return new Queue("REDIRECT_QUEUE", true, false, false);
}

}

2.消息生产者 --》发送消息

import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
@Autowired
private RabbitTemplate rabbitTemplate;
/**
* 延迟消息 ribbit MQ栗子
*
* @param messAge
* @throws Exception
*/
@ApiOperation("死信发送消息")
@GetMapping("creatMessageDear")
public void creatMessageDear(@RequestParam("messAge") String messAge) throws Exception {
//声明消息处理器 设置消息的编码以及消息的过期时间 时间毫秒值为字符串
MessagePostProcessor messagePostProcessor = message -> {
MessageProperties messageProperties = message.getMessageProperties();
messageProperties.setMessageId(UUID.randomUUID().toString().replaceAll("-", ""));
messageProperties.setContentEncoding("utf-8");
//超时时间10秒 (我这里是延迟10秒,根据业务需要设置时间)
messageProperties.setExpiration(String.valueOf(1000 * 10));
return message;
};
Map<String, Object> dataMap = new HashMap<>();
dataMap.put("msg", messAge);
rabbitTemplate.convertAndSend("DEAD_LETTER_EXCHANGE", "DEAD_LETTER_KEY", dataMap, messagePostProcessor);
}

3.接受死信消息
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;


@Component
public class TestMQConsumer {

/**
* 监听转发队列 死信队列重新转发回这里
*
*/
@RabbitListener(queues = {"REDIRECT_QUEUE"})
public void redirect(HashMap<String,Object> dataMap) throws IOException {
System.out.println(dataMap.get("msg"));
System.out.println("我是转发队列,这里执行逻辑业务");
}
}
------------------------------

Ribbit Mq 实现延迟消息的更多相关文章

  1. 基于redis的延迟消息队列设计

    需求背景 用户下订单成功之后隔20分钟给用户发送上门服务通知短信 订单完成一个小时之后通知用户对上门服务进行评价 业务执行失败之后隔10分钟重试一次 类似的场景比较多 简单的处理方式就是使用定时任务 ...

  2. 基于redis的延迟消息队列设计(转)

    需求背景 用户下订单成功之后隔20分钟给用户发送上门服务通知短信 订单完成一个小时之后通知用户对上门服务进行评价 业务执行失败之后隔10分钟重试一次 类似的场景比较多 简单的处理方式就是使用定时任务 ...

  3. RabbitMQ延迟消息学习

    准备做一个禁言自动解除的功能,立马想到了订单的超时自动解除,刚好最近在看RabbitMQ的实现,于是想用它实现,查询了相关文档发现确实可以实现,动手编写了这篇短文. 准备工作 1.Erlang安装请参 ...

  4. Spring Boot RabbitMQ 延迟消息实现完整版

    概述 曾经去网易面试的时候,面试官问了我一个问题,说 下完订单后,如果用户未支付,需要取消订单,可以怎么做 我当时的回答是,用定时任务扫描DB表即可.面试官不是很满意,提出: 用定时任务无法做到准实时 ...

  5. RabbitMQ延迟消息的延迟极限是多少?

    之前在写Spring Cloud Stream专题内容的时候,特地介绍了一下如何使用RabbitMQ的延迟消息来实现定时任务.最近正好因为开发碰到了使用过程中发现,延迟消息没有效果,消息直接就被消费了 ...

  6. RocketMQ系列(五)广播与延迟消息

    今天要给大家介绍RocketMQ中的两个功能,一个是"广播",这个功能是比较基础的,几乎所有的mq产品都是支持这个功能的:另外一个是"延迟消费",这个应该算是R ...

  7. 阿里云RocketMQ定时/延迟消息队列实现

    新的阅读体验:http://www.zhouhong.icu/post/157 一.业务需求 需要实现一个提前二十分钟通知用户去做某件事的一个业务,拿到这个业务首先想到的最简单得方法就是使用Redis ...

  8. Alibaba-技术专区-RocketMQ 延迟消息实现原理和源码分析

    痛点背景 业务场景 假设有这么一个需求,用户下单后如果30分钟未支付,则该订单需要被关闭.你会怎么做? 之前方案 最简单的做法,可以服务端启动个定时器,隔个几秒扫描数据库中待支付的订单,如果(当前时间 ...

  9. SpringBoot - 集成RocketMQ实现延迟消息队列

    目录 前言 环境 具体实现 前言 RocketMQ是阿里巴巴在2012年开源的分布式消息中间件,记录下SpringBoot整合RocketMQ的方式,RocketMQ的安装可以查看:Windows下安 ...

  10. RocketMQ源码详解 | Broker篇 · 其四:事务消息、批量消息、延迟消息

    概述 在上文中,我们讨论了消费者对于消息拉取的实现,对于 RocketMQ 这个黑盒的心脏部分,我们顺着消息的发送流程已经将其剖析了大半部分.本章我们不妨乘胜追击,接着讨论各种不同的消息的原理与实现. ...

随机推荐

  1. 初学银河麒麟linux笔记 第六章 发布qt程序

    本章参考了@长沙红胖子Qt 的笔记 https://blog.51cto.com/hongpangzi/5788384 这里纪录一下步骤 linux上的QT程序已经能正常编译运行,这里需要进行发布. ...

  2. ssh登录、scp传送文件

    一.ssh 1.远程登陆服务器 ssh user@hostname user: 用户名hostname: IP地址或域名 第一次登录时会提示:The authenticity of host '123 ...

  3. 2023-03-01 react-native 实现 复制功能 @react-native-community/clipboard 报错:TypeError: null is not an object (evaluating 'NativeClipboard_1.default.setString')。

    我的react-native(下称rn)版本为0.68,要实现这个功能主要用到rn的clipboard,在21年的时候他就已经提示clipboard会在未来的版本中上去掉,官方的建议是不要再从reac ...

  4. Camstar代码:指定执行某函数

  5. eKuiper 1.8.0 发布:零代码实现图像/视频流的实时 AI 推理

    LF Edge eKuiper 是 Golang 实现的轻量级物联网边缘分析.流式处理开源软件,可以运行在各类资源受限的边缘设备上.eKuiper 的主要目标是在边缘端提供一个流媒体软件框架(类似于 ...

  6. easyui datagrid 表头与数据错位

    方法一:容易,实用的方法 在jquery.easyui.min.js中查找到field.replace(/[\.|\s]/g, "-")在其后添加replace 例子:field. ...

  7. 《Vue.js 3.x高效前端开发(视频教学版)》简介

    #好书推荐##好书奇遇季#<Vue.js 3.x高效前端开发(视频教学版)>,京东当当天猫都有发售.本书配套示例源码.PPT课件.思维导图.数据集.开发环境与答疑服务. 本书通过对Vue. ...

  8. jmeter-时间处理

    ${__time(,)} 1486091280955 //无格式化参数,返回当前毫秒时间,默认13位.一般用来做时间戳 ${__time(/1000,)} //为取10位的时间戳的函数表达式(时间精确 ...

  9. 关于Java的惰性求值

    最近在学scala的时候,函数传参可以是传名参数,或者传值参数 1.Scala中的传名参数是什么意思?lazy关键字有什么作用? Scala官方文档的定义是:传名参数 仅在被使用时触发实际参数的求值运 ...

  10. ABAP 指定字符替换为空格

    上代码 DATA:str1 TYPE string VALUE '小红##爱#six##小绿#666'. *******DATA(str1) = '小红##爱#six##小绿#666'. " ...