当前位置: 首页 > news >正文

17.延迟队列

介绍

延迟队列,队列内部是有序的,延迟队列中的元素是希望在指定时间到了以后或之前取出和处理。

死信队列中,消息TTL过期的情况其实就是延迟队列。

使用场景

1.订单在十分钟内未支付则自动取消。

2.新创建的店铺,如果十天内没有上传过商品,则自动发送消息提醒。

3.用户注册成功后,如果三天没有登陆则进行短信提醒。

4.用户发起退款,如果三天内没有得到处理则通知相关运营人员。

5.预定会议后,需要再预定的时间点前十分钟通知各个与会人员参加会议。

传统实现方案

可以开启一个定时任务,每秒中去轮训检查,取出需要被处理的数据。对于数据量较少可以这么做。但是如果有大数据量的任务需要处理,活动期间达到百万级或者千万级的庞大数据量是不可取的。

整合SpringBoot

引入依赖

<!--rabbitmq整合springboot使用的-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<!--rabbitmq测试依赖-->
<dependency><groupId>org.springframework.amqp</groupId><artifactId>spring-rabbit-test</artifactId><scope>test</scope>
</dependency>

配置文件添加配置

spring:rabbitmq:host: 192.168.171.128username: adminpassword: 123port: 5672

延迟队列代码架构图 

说明:QD为死信队列,QA和QB是普通队列。x为直接交换机,y为死信交换机。

代码结构的转变

整合springboot项目之前,将队列和交换机的声明和配置放在消费者端的。那么整合springboot之后将会将这些配置放在配置文件类代码中。

代码

配置类(声明队列、交换机、绑定关系)

package com.xkj.org.config;import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.HashMap;
import java.util.Map;/*** TTL队列,配置文件代码*/
@Configuration
public class TtlQueueConfig {//普通交换机public static final String X_EXCHANGE = "X";//死信交换机public static final String Y_HEAD_LETTER_EXCHANGE = "Y";//普通队列public static final String QUEUE_A = "QA";public static final String QUEUE_B = "QB";//死信队列public static final String DEAD_LETTER_QUEUE = "QD";/*** 声明普通交换机X,bean的别名xExchange* @return*/@Bean("xExchange")public DirectExchange xExchange() {return new DirectExchange(X_EXCHANGE);}/*** 声明死信交换机Y,bean的别名yExchange* @return*/@Bean("yExchange")public DirectExchange yExchange() {return new DirectExchange(Y_HEAD_LETTER_EXCHANGE);}/*** 声明普通队列QA* @return*/@Bean("queueA")public Queue queueA() {Map<String, Object> arguments = new HashMap<>(3);//设置死信交换机arguments.put("x-dead-letter-exchange", Y_HEAD_LETTER_EXCHANGE);//声明死信的routingeyarguments.put("x-dead-letter-routing-key", "YD");//设置消息过期时间ttl为10sarguments.put("x-message-ttl", 10000);return QueueBuilder.durable(QUEUE_A).withArguments(arguments).build();}/*** 声明普通队列QB* @return*/@Bean("queueB")public Queue queueB() {Map<String, Object> arguments = new HashMap<>(3);//设置死信交换机arguments.put("x-dead-letter-exchange", Y_HEAD_LETTER_EXCHANGE);//声明死信的routingKeyarguments.put("x-dead-letter-routing-key", "YD");//设置消息过期时间ttl为40sarguments.put("x-message-ttl", 40000);return QueueBuilder.durable(QUEUE_B).withArguments(arguments).build();}/*** 声明死信队列QD* @return*/@Bean("queueD")public Queue queueD() {return QueueBuilder.durable(DEAD_LETTER_QUEUE).build();}/*** 将队列QA绑定到交换机X上,指定routingKey为XA* @param queueA* @param xExchange* @return*/@Beanpublic Binding queueABindingX(@Qualifier("queueA") Queue queueA, @Qualifier("xExchange")DirectExchange xExchange) {return BindingBuilder.bind(queueA).to(xExchange).with("XA");}/*** 将队列QB绑定到交换机X上,指定routingKey为XB* @param queueB* @param xExchange* @return*/@Beanpublic Binding queueBBindingX(@Qualifier("queueB") Queue queueB, @Qualifier("xExchange") DirectExchange xExchange) {return BindingBuilder.bind(queueB).to(xExchange).with("XB");}/*** 将队列QD绑定到交换机Y上,指定routingKey为YD* @param queueD* @param yExchange* @return*/@Beanpublic Binding queueDBindingY(@Qualifier("queueD") Queue queueD, @Qualifier("yExchange") DirectExchange yExchange) {return BindingBuilder.bind(queueD).to(yExchange).with("YD");}
}

生产者(通过controller接口发送)

package com.xkj.org.controller;import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.Date;/*** 消息生产者*/
@Slf4j
@RestController
@RequestMapping("/ttl")
@Api(tags = "消息生产者", description = "消息生产者控制器")
public class MessageController {@Autowiredprivate RabbitTemplate rabbitTemplate;@ApiOperation("消息发送测试")@GetMapping("/sendMsg/{msg}")public void sendMsg(@ApiParam(value = "发送的消息内容", required = true) @PathVariable("msg") String message) {log.info("当前时间{},发送一条消息给两个队列:{}", new Date().toString(), message);rabbitTemplate.convertAndSend("X", "XA", "ttl=10s的消息:" + message);rabbitTemplate.convertAndSend("X", "XB", "ttl=40s的消息:" + message);}}

消费者(监听器)

package com.xkj.org.listener;import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;import java.util.Date;/*** 消费者*/
@Slf4j
@Componentpublic class DeadLetterQueueConsumer {@RabbitListener(queues = "QD")public void receiveD(Message message, Channel channel) throws Exception {String msg = new String(message.getBody(), "UTF-8");log.info("当前时间:{},收到死信队列的消息:{}", new Date().toString(), msg);}
}

结果

相关文章:

17.延迟队列

介绍 延迟队列&#xff0c;队列内部是有序的&#xff0c;延迟队列中的元素是希望在指定时间到了以后或之前取出和处理。 死信队列中&#xff0c;消息TTL过期的情况其实就是延迟队列。 使用场景 1.订单在十分钟内未支付则自动取消。 2.新创建的店铺&#xff0c;如果十天内没…...

KCache-go本地缓存,支持本地缓存过期、缓存过期自维护机制。

GitHub - kocor01/kcache: go 本地缓存解决方案&#xff0c;支持本地缓存过期、缓存过期自维护机制。 最近系统并发很高&#xff0c;单接口10W的 QPS&#xff0c;对 redis 压力很大&#xff0c;大量的热KEY导致 redis 分片CPU资源经常告警。计划用 go 本地缓存缓解 redis 的压…...

斯坦福UE4 C++课学习补充 14:UMG-优化血量条

文章目录 一、优化执行效率二、简单脉冲动画 一、优化执行效率 绑定事件需要每一帧检查绑定对象是否有变化&#xff0c;势必造成CPU资源的浪费&#xff0c;因此优化执行效率的思路是&#xff1a;UI组件不再自行每帧查询血量&#xff0c;而是让血量自己在发生变化的同时通知UI进…...

在生信分析中大家需要特别注意的事情​

在生信分析中大家需要特别注意的事情 标准的软件使用和数据分析流程 1. 先看我的b站教学视频 2. 先从我的百度网盘把演示数据集下载下来&#xff0c;先把要运行的模块的演示数据集先运行一遍 3. 前两步都做完了&#xff0c;演示数据集也运行成功了&#xff0c;并且知道了软件…...

Java工厂模式详解:方法工厂模式与抽象工厂模式

Java工厂模式详解&#xff1a;方法工厂模式与抽象工厂模式 一、引言 在Java开发中&#xff0c;设计模式是解决常见软件设计问题的一种有效方式。工厂模式作为创建型设计模式的一种&#xff0c;提供了灵活的对象创建机制&#xff0c;有助于降低代码的耦合度&#xff0c;提高系…...

springSecurity学习之springSecurity用户单设备登录

用户只能单设备登录 有时候在同一个系统中&#xff0c;只允许一个用户在一个设备登录。 之前的登陆者被顶掉 将最大会话数设置为1就可以保证用户只能同时在一个设备上登录 Override protected void configure(HttpSecurity http) throws Exception {http..anyRequest().aut…...

微信小程序实现聊天界面,发送功能

.wxml <scroll-view scroll-y"true" style"height: {{windowHeight}}px;"><view wx:for"{{chatList}}" wx:for-index"index" wx:for-item"item" style"padding-top:{{index0?30:0}}rpx"><!-- 左…...

【强化学习的数学原理】课程笔记--5(值函数近似,策略梯度方法)

目录 值函数近似一个例子TD 算法的值函数近似形式Sarsa, Q-learning 的值函数近似形式Deep Q-learningexperience replay 策略梯度方法&#xff08;Policy Gradient&#xff09;Policy Gradient 的目标函数目标函数 1目标函数 2两种目标函数的同一性 Policy Gradient 目标函数的…...

前端Long类型精度丢失:后端处理策略

文章目录 精度丢失的具体原因解决方法1. 使用 JsonSerialize 和 ToStringSerializer2. 使用 JsonFormat 注解3. 全局配置解决方案 结论 开发商城管理系统的品牌管理界面时&#xff0c;发现一个问题&#xff0c;接口返回品牌Id和页面展示的品牌Id不一致&#xff0c;如接口返回的…...

C++ | Leetcode C++题解之第300题最长递增子序列

题目&#xff1a; 题解&#xff1a; class Solution { public:int lengthOfLIS(vector<int>& nums) {int len 1, n (int)nums.size();if (n 0) {return 0;}vector<int> d(n 1, 0);d[len] nums[0];for (int i 1; i < n; i) {if (nums[i] > d[len])…...

springboo 整合 redis

springBoot 整合 redis starter启动依赖。—包含自动装配类—完成相应的装配功能。 引入依赖 <!--引入了redis整合springboot 的依赖--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis&…...

dpdk编译安装以及接收udp报文(基于ubuntu)

目录 1、编译 2、设置运行环境 3、使用dpdk接收udp报文 3.1、设置发送端arp信息 3.2、测试 3.3、代码 4、其他 1、编译 代码下载&#xff1a; DPDK 下载版本&#xff1a;DPDK 19.08.2 export RTE_SDK/root/dpdk-stable-19.08.2/ export RTE_TARGETx86_64-native-li…...

【计算机网络】OSPF单区域实验

一&#xff1a;实验目的 1&#xff1a;掌握在路由器上配置OSPF单区域。 2&#xff1a;学习OSPF协议的原理&#xff0c;及其网络拓扑结构改变后的变化。 二&#xff1a;实验仪器设备及软件 硬件&#xff1a;RCMS交换机、网线、内网网卡接口、Windows 2019操作系统的计算机等。…...

Java聚合快递小程序对接云洋系统程序app源码

​一场物流效率的革命 引言&#xff1a;物流新时代的序章 在数字化浪潮席卷各行各业的今天&#xff0c;物流行业也迎来了前所未有的变革。为了进一步提升物流效率&#xff0c;优化用户体验&#xff0c;聚合快递系统与云洋系统小程序的对接成为了行业内外关注的焦点。这一创新…...

【React】详解组件通信:从基础到进阶的全面指南

文章目录 一、父组件向子组件传递数据1. 基本概念2. 示例代码3. 详解定义子组件 Son定义父组件 App导出父组件 App数据流props 的内容 二、子组件向父组件传递数据1. 基本概念2. 示例代码3. 详解引入React库和useState钩子定义子组件 Son定义父组件 App导出父组件 App数据流 三…...

【vluhub】zabbix漏洞

介绍&#xff1a; zabbix是对服务器资源状态例如、内存空间、CPU、程序运行状态进行检测、设置预警值、短信设置等功能等一款开源工具。配置不当存在未授权,SQL注入漏洞 弱口令 nameadmin&passwordzabbix nameguest&password POST /index.php HTTP/1.1 Host: 192.1…...

openGauss触发器详解

openGauss 是一款开源关系型数据库管理系统&#xff0c;广泛应用于企业级应用中。随着数据量的增长和业务逻辑的复杂化&#xff0c;数据库管理和操作的自动化需求越来越高。触发器&#xff08;Triggers&#xff09;作为数据库中重要的编程工具&#xff0c;能够极大地简化复杂操…...

抄作业-跟着《React通关秘籍》捣鼓React-playground-上集

文章目录 前言1. 搭建react 开发环境2、react hooks 知识3. 目标&#xff1a;跟着小册实现 react-playground3.1 整体布局初始化项目使用Alloment 来实现左右分屏的拖拉功能 3.2 代码编辑器Monaco Editor 3.3 实现了多文件的切换用 useContext 来共享数据。优化 tab的样式&…...

80后最后的书信 年代

当时11亿人口只有1.8万部固定电话 中国几千年来 鱼传尺素 雁寄鸿书 写信最后要写 亲啓 如有照片&#xff0c;封面要写内有照片&#xff0c;请勿折叠 信的开头应该是 见字如面&#xff0c;展信舒颜 如果拜托别人做事情&#xff0c;最后要写为盼 最后要写 某某草 书未尽…...

软考-软件设计师(4)-计算机网络与安全:OSI七层、子网划分、网络安全控制技术、网络安全协议、网络安全威胁、对称与非对称加密等高频考点

场景 软考-软件设计师-计算机网络与信息安全模块高频考点整理。 以下为高频考点、知识点汇总,不代表该模块所有知识点覆盖,请以官方教程提纲为准。 注: 博客:霸道流氓气质-CSDN博客 实现 知识点 OSI/RM七层模型 注意各层的主要功能,特别是表示层负责数据的加密、压…...

【Linux】shell脚本忽略错误继续执行

在 shell 脚本中&#xff0c;可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行&#xff0c;可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令&#xff0c;并忽略错误 rm somefile…...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

UDP(Echoserver)

网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法&#xff1a;netstat [选项] 功能&#xff1a;查看网络状态 常用选项&#xff1a; n 拒绝显示别名&#…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用&#xff0c;可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器&#xff0c;能够帮助开发者更好地管理复杂的依赖关系&#xff0c;而 GraphQL 则是一种用于 API 的查询语言&#xff0c;能够提…...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文&#xff1f; 多租户隔离&#xff1a;自动为接入设备追加租户前缀&#xff0c;后端按 ClientID 拆分队列。零代码鉴权&#xff1a;将入站用户名替换为 OAuth Access-Token&#xff0c;后端 Broker 统一校验。灰度发布&#xff1a;根据 IP/地理位写…...

【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表

1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具&#xff0c;可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下&#xff1a; ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜&#xff1a; ffmpeg…...

【单片机期末】单片机系统设计

主要内容&#xff1a;系统状态机&#xff0c;系统时基&#xff0c;系统需求分析&#xff0c;系统构建&#xff0c;系统状态流图 一、题目要求 二、绘制系统状态流图 题目&#xff1a;根据上述描述绘制系统状态流图&#xff0c;注明状态转移条件及方向。 三、利用定时器产生时…...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...