RabbitMQ实现秒杀场景示例
本文章通过MQ队列来实现秒杀场景
整体的设计如下图,整个流程中对于发送发MQ失败和发送到死信队列的数据未做后续处理

1、首先先创建MQ的配置文件
@Configuration
public class RabbitConfig {public static final String DEAD_LETTER_EXCHANGE = "deadLetterExchange";public static final String DEAD_LETTER_QUEUEA_ROUTING_KEY = "dead.#";public static final String DEAD_LETTER_QUEUEA_NAME = "deadQueue";@Autowiredprivate RabbitTemplate rabbitTemplate;@Autowiredprivate ConnectionFactory connectionFactory;@Beanpublic TopicExchange topicExchange(){return new TopicExchange("seckill_topic",true,false);}// 声明死信Exchange@Bean("deadLetterExchange")public DirectExchange deadLetterExchange(){return new DirectExchange(DEAD_LETTER_EXCHANGE);}@Bean("seckillQueue")public Queue seckillQueue(){Map<String,Object> args = new HashMap<>();args.put("x-dead-letter-exchange", DEAD_LETTER_EXCHANGE);// x-dead-letter-routing-key 这里声明当前队列的死信路由keyargs.put("x-dead-letter-routing-key", DEAD_LETTER_QUEUEA_ROUTING_KEY);return QueueBuilder.durable("seckillQueue").withArguments(args).build();}@Bean("deadQueue")public Queue binding(){return new Queue(DEAD_LETTER_QUEUEA_NAME);}@Beanpublic Binding bindingExchange(){return BindingBuilder.bind(seckillQueue()).to(topicExchange()).with("seckill.#");}// 声明死信队列绑定关系@Beanpublic Binding deadLetterBinding(@Qualifier("deadQueue") Queue queue,@Qualifier("deadLetterExchange") DirectExchange exchange){return BindingBuilder.bind(queue).to(exchange).with(DEAD_LETTER_QUEUEA_ROUTING_KEY);}//配置会覆盖yml的重试次数//RabbitMQ监听容器/*@Beanpublic SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(ConnectionFactory connectionFactory){SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();factory.setConnectionFactory(connectionFactory);//设置并发factory.setConcurrentConsumers(1);SimpleMessageListenerContainer s=new SimpleMessageListenerContainer();//最大并发factory.setMaxConcurrentConsumers(1);//消息接收——手动确认factory.setAcknowledgeMode(AcknowledgeMode.AUTO);//设置超时factory.setReceiveTimeout(2000L);//设置重试间隔factory.setFailedDeclarationRetryInterval(3000L);//监听自定义格式转换//factory.setMessageConverter(jsonMessageConverter);return factory;}*/
}
2、配置yml文件
spring:redis:database: 0host: xxxport: 6379password: xxxtimeout: 60jedis:pool:max-active: 8max-wait: -1max-idle: 8min-idle: 0rabbitmq:username: adminpassword: adminvirtual-host: /host: xxxxport: 12345publisher-confirms: truepublisher-returns: truetemplate:mandatory: truelistener:simple:concurrency: 1max-concurrency: 3# 消费者预取1条数据到内存,默认为250条prefetch: 1# 确定机制acknowledge-mode: manualretry:enabled: true #是否支持重试max-attempts: 2# 重试间隔(ms)initial-interval: 5000
这里有一点需要注意的是在做死信队列的时候如果Config文件中配置了监听容器,在yml文件中的一些属性要在容器里面进行配置,当时测试重试的时候发现没有在Config文件中配置,只在yml文件中配置了重试次数,结果会无限期的重试,MQ的默认方式就是无限期的重试,所以这点很容易踩坑
3、实现交换机的ACK,实现 RabbitTemplate.ConfirmCallback接口
@Component
public class ConfirmCallBackHandler implements RabbitTemplate.ConfirmCallback {@Autowiredprivate RabbitMessageMapper rabbitMessageMapper;@Autowiredprivate RabbitTemplate rabbitTemplate;//注入//PostConstruct注解会在Component、Autowired注解完成后再执行@PostConstructpublic void init(){rabbitTemplate.setConfirmCallback(this);}@Overridepublic void confirm(CorrelationData correlationData, boolean ack, String cause) {if(!ack){RabbitMessage rabbitMessage = new RabbitMessage();rabbitMessage.setUniqueKey(correlationData.getId().toString());rabbitMessage.setSuccessFlag("N");rabbitMessageMapper.updateSuccessFlag(rabbitMessage);System.out.println("失败原因:"+cause);}}
}
4、实现队列的ACK,实现 RabbitTemplate.ReturnCallback
@Component
public class ReturnCallBackHandler implements RabbitTemplate.ReturnCallback {@Autowiredprivate RabbitTemplate rabbitTemplate;//注入//PostConstruct注解会在Component、Autowired注解完成后再执行@PostConstructpublic void init(){rabbitTemplate.setReturnCallback(this);}@Overridepublic void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {System.out.println("消息主体 message:"+message);System.out.println("应答码 replyCode: :"+replyCode);System.out.println("原因描述 replyText:"+replyText);System.out.println("交换机 exchange:"+exchange);System.out.println("消息使用的路由键 routingKey:"+routingKey);}
}
5、消费者方面,实现 ChannelAwareMessageListener 接口
@Component
public class AckListener implements ChannelAwareMessageListener {@Autowiredprivate RabbitMqService rabbitMqService;@RabbitListener(queues = "seckillQueue")@Overridepublic void onMessage(Message messagex, Channel channel) throws Exception {try {String result = new String(messagex.getBody(),"utf-8");rabbitMqService.receive(result);channel.basicAck(messagex.getMessageProperties().getDeliveryTag(), false);}catch (Exception exception){channel.basicNack(messagex.getMessageProperties().getDeliveryTag(), false, false);}}
}
相关文章:
RabbitMQ实现秒杀场景示例
本文章通过MQ队列来实现秒杀场景 整体的设计如下图,整个流程中对于发送发MQ失败和发送到死信队列的数据未做后续处理 1、首先先创建MQ的配置文件 Configuration public class RabbitConfig {public static final String DEAD_LETTER_EXCHANGE "deadLetterE…...
如何提升网站排名优化(百度SEO优化,轻松提升排名)
在当今互联网时代,拥有一个优秀的网站是很重要的。而一个网站如果能够在搜索引擎上的排名很靠前,那么将会带来更多的流量、更多的用户和更多的利润。那么如何提升网站排名优化呢?蘑菇号www.mooogu.cn 百度SEO优化的5个规则 1.关键词选取要合…...
CountDownLatch 和 CyclicBarrier 用法以及区别
在使用多线程执行任务时,通常需要在主线程进行阻塞等待,直到所有线程执行完毕,主线程才能继续向下执行,主要有以下几种可选方式 1. 调用 main 线程的 sleep 方法 一般用于预估线程的执行时间,在主线程内执行线程sleep…...
9.9喝遍“茶、奶、果、酒”,茶饮价格战是因为“无活可整”?
“家人们谁懂啊,周一瑞幸周二奈雪周三茶百道周四库迪周五古茗周六coco,9块9根本喝不完!” 紧随咖啡的9.9大战,茶饮们也在今年加速“蜜雪冰城化”,9.9变成了一种潮流。伴随着茶百道、coco、奈雪的茶等品牌把9.9玩出了更…...
echarts 学习网址
1、PPChart 网址:PPChart - 让图表更简单 2、YX-Chartlib 网址:http://chartlib.datains.cn3、isqqw 网址:echarts图表集4、makeapie 网址:makeapie echarts社区图表可视化案例5、Chart.Top 网址:chart.top - 让图…...
android源码编译
整包编译 导入环境变量 source ./build/envsetup.shlunch:选择平台编译选项make:执行编译 编译单个apk 进入到apk mk所在路径 mma...
盘点双电机驱动技术
对于电动汽车来说,双电机相对于单电机加主减速器或变速箱的方案在提高驱动效率方面的优势: 第一,单电机在低速、高速轻载等情况下,效率降低比较严重。 电动机的高效区间虽然比内燃机大得多,但是汽车的转速和转矩要求…...
ubuntu下用pycharm专业版连接AI服务器及其docker环境
一:用pycharm专业版连接AI服务器 1、首先在自己电脑上新建一个文件夹,后续用于映射服务器上自己所要用的项目文件 2、用pycharm专业版打开该文件夹,作为一个项目打开 3、然后在工具->部署->配置 4、配置中形式如下: 点击左…...
IntentFilter笔记
一、action <intent-filter>中可以有多个action,Intent只要匹配其中1个action即匹配成功<intent-filter>没有action,任何Intent无法与之匹配<intent-filter>中有action,Intent中没有action时可以与之匹配成功<intent-fi…...
【二叉树】——链式结构(快速掌握递归与刷题技巧)
📙作者简介: 清水加冰,目前大二在读,正在学习C/C、Python、操作系统、数据库等。 📘相关专栏:C语言初阶、C语言进阶、C语言刷题训练营、数据结构刷题训练营、有感兴趣的可以看一看。 欢迎点赞 👍…...
项目管理—项目普遍存在的问题
软件公司有开发业务,在完成一个软件产品或实施项目时,常常会出现以下的状况: 开发人员不懂客户业务,一个高大上的规划,落地后的软件,只是机械的满足了基本功能,毫无易用性和科学性可言。 项目只…...
Ubuntu Seata开机自启动服务
1、创建service文件 在/lib/systemd/system目录下创建seata.service文件 [Unit] Descriptionalibaba seata Afternetwork.target Documentationhttps://seata.io/zh-cn/[Service] Userroot Grouproot Typeforking Environment"JAVA_HOME/usr/local/programs/jdk-8u333-li…...
腾讯mini项目-【指标监控服务重构】2023-08-26
今日已办 Venus 的 Trace 无感化 定义 handler 函数 fiber.Handler 的主要处理逻辑返回处理中出现的 error返回处理中响应 json 的函数 // handler // Description: // Author xzx 2023-08-26 18:00:03 // Param c // Return error // Return func() error : function for …...
《Essential C++》之(面向过程泛型编程)
目录 🌼面向过程的编程风格 -- 第2章 🍈2.2 🍈2.4 🍈2.5 🍈2.6 🌼泛型编程风格 -- 第3章 🍍3.1 🍍3.4 前言 要求 完整代码 输入输出 🌼面向过程的编程风…...
机器学习笔记:adaBoost
1 介绍 AdaBoost(Adaptive Boosting)是一种集成学习方法,它的目标是将多个弱分类器组合成一个强分类器 通过反复修改训练数据的权重,使得之前分类错误的样本在后续的分类器中得到更多的关注每一轮中,都会增加一个新的…...
Anchor DETR
Anchor DETR(AAAI 2022) 改进: 提出了基于anchor的对象查询提出Attention变体-RCDA 在以前DETR中,目标的查询是一组可学习的embedding。然而,每个可学习的embedding都没有明确的意义 (因为是随机初始化的)ÿ…...
适合在家做的副业 整理5个,有电脑就行
今天,我们不说别的,整理5个适合个人在家单干的副业。需要电脑,如果你没电脑就不用看了,最后两个,我们也在做,你可以看到最后了解。这些副业,大家多去实践操作,前期,每月三…...
Android WebSocket
WS Android WebSocket 资源 名字资源AAR下载GitHub查看Gitee查看 Maven 1.build.grade allprojects {repositories {...maven { url https://jitpack.io }} }2./app/build.grade dependencies {implementation com.github.RelinRan:WS:2022.2023.9.23.1 }初始化 配置权…...
Android 按键流程
一、驱动层流程 主要流程涉及以下文件 kernel/msm-4.19/drivers/input/keyboard/gpio_keys.c kernel/msm-4.19/drivers/input/input.c kernel/msm-4.19/drivers/input/evdev.c kernel/msm-4.19/drivers/input/input-compat.c 有按键动作时,根据 dtsi 中配置 c…...
C语言——运算符
C用运算符表示算术运算。 C没有指数运算符,不过,C的标准数学库提供了一个pow()函数用于指数运算。 基本运算符 赋值运算符: 变量名变量值 从右到左 左值和变量名的区别: 变量名是一个标识符的名称,左值是一个可变…...
51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...
站群服务器的应用场景都有哪些?
站群服务器主要是为了多个网站的托管和管理所设计的,可以通过集中管理和高效资源的分配,来支持多个独立的网站同时运行,让每一个网站都可以分配到独立的IP地址,避免出现IP关联的风险,用户还可以通过控制面板进行管理功…...
STM32HAL库USART源代码解析及应用
STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...
