【黑马点评】jmeter测试秒杀接口前后耗时,和查询店铺(redis+caffeine二级缓存)接口
【黑马点评】jmeter测试秒杀接口前后耗时,和查询店铺缓存穿透接口
- 4.测试秒杀接口耗时
- 4.1 修改VoucherOrderController
- 4.2 测试原本的接口耗时
- 5. 测试缓存穿透
这篇是测试,使用RabbitMQ消息异步处理订单,以及不异步处理订单的耗时对比
以及查询店铺时使用redis+caffeine二级缓存接口
4.测试秒杀接口耗时
需要修改VoucherOrderController中的秒杀代码,在秒杀操作前后计算接口耗时
4.1 修改VoucherOrderController
注释掉原先的seckillVoucher方法
// @PostMapping("seckill/{id}")
// public Result seckillVoucher(@PathVariable("id") Long voucherId) {
// return voucherOrderService.seckillVoucher(voucherId);
// }
改为
@PostMapping("seckill/{id}")public Result seckillVoucher(@PathVariable("id") Long voucherId) {long startTime = System.currentTimeMillis();Result result = voucherOrderService.seckillVoucher(voucherId);long endTime = System.currentTimeMillis();long duration = endTime - startTime;log.info("秒杀接口耗时:{}ms",duration);
// return voucherOrderService.seckillVoucher(voucherId);return result;}
之后,使用Apifox发起测试

命令行输出结构为:3ms

4.2 测试原本的接口耗时
修改VoucherOrderServiceImpl.java代码如下
主要注释掉如下三个方法
- handleVoucherOrder
- seckillVoucher
- createVoucherOrder
// @TODO 注释掉以下部分,以下部分为用RabbitMQ实现的异步秒杀
// @Transactional
// public void handleVoucherOrder(VoucherOrder voucherOrder) {
// //1.所有信息从当前消息实体中拿
// // 获取用户
// Long userId = voucherOrder.getUserId();
// //创建锁对象
// RLock redisLock = redissonClient.getLock("lock:order:"+userId);
// //尝试获取锁
// boolean isLock = redisLock.tryLock();
//
// //4.判断是否获取锁成功
// if(!isLock){
// //获取锁失败,直接返回失败或者重试
// log.error("不允许重复下单!");
// return;
// }
// try{
// //获取代理对象(事务)
// IVoucherOrderService proxy = (IVoucherOrderService) AopContext.currentProxy();
// proxy.createVoucherOrder(voucherOrder);
// }finally {
// if (redisLock.isHeldByCurrentThread()) {
// redisLock.unlock();
// }
// }
///* Long voucherId = voucherOrder.getVoucherId();
// //2.扣减库存
// boolean success = seckillVoucherService.update().setSql("stock=stock-1")
// .eq("voucher_id", voucherId)
// //======判断当前库存是否大于0就可以决定是否能抢池子中的券了
// .gt("stock", 0)
// .update();
// //3.创建订单
// if(success) save(voucherOrder);*/
// }
//
//
// @Resource
// RabbitTemplate rabbitTemplate;
// @Override
// public Result seckillVoucher(Long voucherId) {
// //1.执行lua脚本,判断当前用户的购买资格
// Long userId = UserHolder.getUser().getId();
// Long result = stringRedisTemplate.execute(
// SECKILL_SCRIPT,
// Collections.emptyList(),
// voucherId.toString(), userId.toString());
// if (result != 0) {
// //2.不为0说明没有购买资格
// return Result.fail(result==1?"库存不足":"不能重复下单");
// }
// //3.走到这一步说明有购买资格,将订单信息存到消息队列
// VoucherOrder voucherOrder = new VoucherOrder();
// long orderId = redisIdWorker.nextId("order");
// voucherOrder.setId(orderId);
// voucherOrder.setUserId(UserHolder.getUser().getId());
// voucherOrder.setVoucherId(voucherId);
// //存入消息队列等待异步消费
// rabbitTemplate.convertAndSend("hmdianping.direct","direct.seckill",voucherOrder);
// return Result.ok(orderId);
// }
//
//
//
// @Transactional
// public void createVoucherOrder(VoucherOrder voucherOrder){
// // 5.一人一单逻辑
// // 5.1.用户id
// //6.扣减库存
// Long voucherId = voucherOrder.getVoucherId();
// boolean success = seckillVoucherService.update()
// .setSql("stock= stock -1") // set stock = stock -1
// .eq("voucher_id", voucherId)
// .gt("stock",0)// where id = ? and stock > 0
// .update();
// if (!success) {
// //扣减库存
// log.error("库存不足!");
// return ;
// }
//
//
// save(voucherOrder);
//
// }
添加以下内容
// 原先秒杀接口,用来测试接口耗时@Overridepublic Result seckillVoucher(Long voucherId) {// 1.查询优惠券SeckillVoucher voucher = seckillVoucherService.getById(voucherId);// 2.判断秒杀是否开始if (voucher.getBeginTime().isAfter(LocalDateTime.now())) {// 尚未开始return Result.fail("秒杀尚未开始!");}// 3.判断秒杀是否已经结束if (voucher.getEndTime().isBefore(LocalDateTime.now())) {// 尚未开始return Result.fail("秒杀已经结束!");}// 4.判断库存是否充足if (voucher.getStock() < 1) {// 库存不足return Result.fail("库存不足!");}// 5.一人一单逻辑// 5.1.用户idLong userId = UserHolder.getUser().getId();int count = query().eq("user_id", userId).eq("voucher_id", voucherId).count();// 5.2.判断是否存在if (count > 0) {// 用户已经购买过了return Result.fail("用户已经购买过一次!");}//6,扣减库存boolean success = seckillVoucherService.update().setSql("stock= stock -1").eq("voucher_id", voucherId).update();if (!success) {//扣减库存return Result.fail("库存不足!");}//7.创建订单VoucherOrder voucherOrder = new VoucherOrder();// 7.1.订单idlong orderId = redisIdWorker.nextId("order");voucherOrder.setId(orderId);voucherOrder.setUserId(userId);// 7.3.代金券idvoucherOrder.setVoucherId(voucherId);save(voucherOrder);return Result.ok(orderId);}@Overridepublic void createVoucherOrder(VoucherOrder voucherOrder) {}@Overridepublic void handleVoucherOrder(VoucherOrder voucherOrder) {}
测试结果如下:400ms

5. 测试缓存穿透
修改http请求如下

1000并发下

10000并发下

相关文章:
【黑马点评】jmeter测试秒杀接口前后耗时,和查询店铺(redis+caffeine二级缓存)接口
【黑马点评】jmeter测试秒杀接口前后耗时,和查询店铺缓存穿透接口 4.测试秒杀接口耗时4.1 修改VoucherOrderController4.2 测试原本的接口耗时 5. 测试缓存穿透 这篇是测试,使用RabbitMQ消息异步处理订单,以及不异步处理订单的耗时对比 以及查…...
盛铂科技 SCP4006/4018/4040:国产袖珍式功率计 射频微波功率探头 平均功率计
在通信、电子测量等领域,功率计是确保信号稳定、系统高效运行的关键设备。盛铂科技自主研发的 SCP4000 系列自带 USB 接口的袖珍式 CW 信号平均功率计,以其卓越的性能、高性价比和便捷的操作,在众多同类产品中脱颖而出,成为行业内…...
数据科学之数据管理|统计学
使用python学习统计 目录 01 统计学基础 7 一、 统计学介绍 7 二、 数据和变量 8 02 描述统计 10 一、 描述统计概述 10 二、 分类变量的描述 11 三、 等距数值变量的描述 13 四、 等比数值变量的描述 16 五、 常用软件包介绍 16 六、 数值变量的描述统计 18 (一)…...
C++ 设计模式-建造者模式
以下是一个完整的C建造者模式示例,包含产品类、建造者接口、具体建造者、指挥者以及测试代码: #include <iostream> #include <string> #include <memory>// 产品类:汽车 class Car { public:void setBody(const std::str…...
从零搭建:Canal实时数据管道打通MySQL与Elasticsearch
Canal实时同步Mysql Binlog至 Elasticsearch 文章目录 Canal实时同步Mysql **Binlog**至**Elasticsearch** 一. 环境准备1.环境检查检查Mysql是否开启BinLog开启Mysql BinlogJava环境检查 2.新建测试库和表3.新建Es索引 二.**部署 Canal Server****2.1 解压安装包****2.2 配置 …...
Baumer工业相机堡盟工业相机如何通过BGAPI SDK实现一次触发控制三个光源开关分别采集三张图像(C#)
Baumer工业相机堡盟工业相机如何通过BGAPI SDK实现一次触发控制三个光源开关分别采集三张图像(C#) Baumer工业相机Baumer工业相机定序器功能的技术背景Baumer工业相机通过BGAPI SDK使用定序器功能预期的相机动作定序器的工作原理 Baumer工业相机通过BGAP…...
网络安全用centos干嘛 网络安全需要学linux吗
网络安全为啥要学Linux系统,据不完全统计,Linux系统在数据中心操作系统上的份额高达70%。它一般运行于服务器和超级计算机上。 所以我们日常访问的网站后台和app后端都是部署在Linux服务器上的,如果你不会Linux系统操作,那么很多…...
【React】react-redux+redux-toolkit实现状态管理
安装 npm install reduxjs/toolkit react-reduxRedux Toolkit 是官方推荐编写Redux的逻辑方式,用于简化书写方式React-redux 用来链接Redux和React组件之间的中间件 使用 定义数据 创建要管理的数据模块 store/module/counter.ts import { createSlice, Payloa…...
如何通过AI轻松制作PPT?让PPT一键生成变得简单又高效
如何通过AI轻松制作PPT?让PPT一键生成变得简单又高效!在这个信息化飞速发展的时代,PPT已经成为我们日常工作、学习和生活中不可或缺的一部分。无论是公司会议、学术报告,还是个人展示,PPT的作用都不容忽视。很多人对于…...
Springer |第七届2025年区块链、人工智能和可信系统国际会议
Springer |第七届2025年区块链、人工智能和可信系统国际会议 International Conference on Blockchain, Artificial Intelligence, and Trustworthy Systems 【重要日期】 论文提交截止日期:2025年03月01日(第2轮) 会议报名截止日期&…...
新一代SCADA: 宏集Panorama Suite 2025 正式发布,提供更灵活、符合人体工学且安全的应用体验
宏集科技宣布正式推出全新Panorama Suite 2025 SCADA软件!全新版本标志着 Panorama Suite的一个重要里程碑,代表了从 Panorama Suite 2022 开始并跨越三个版本(2022、2023、2025)的开发过程的顶峰。 此次重大发布集中在六个核心主…...
AI在电竞比分网中的主要应用场景
AI在电竞体育比分网的数据应用非常广泛,能够显著提升数据分析、预测、用户体验和商业价值。以下是AI在电竞比分网中的主要应用场景: 1. 实时数据采集与分析 比赛数据实时更新:AI通过自动化系统实时采集比赛数据(如击杀数、经济差、…...
前端快速生成接口方法
大家好,我是苏麟,今天聊一下OpenApi。 官网 : umijs/openapi - npm 安装命令 npm i --save-dev umijs/openapi 在根目录(项目目录下)创建文件 openapi.config.js import { generateService } from umijs/openapi// 自…...
【Pico】使用Pico进行无线串流搜索不到电脑
使用Pico进行无线串流搜索不到电脑 官串方式:使用Pico互联连接电脑。 故障排查 以下来自官方文档 请按照以下步骡排除故障: 确认电脑和一体机连接了相同的路由器WiFi网络(相同网段) IP地址通常为192.168.XX,若两设备的IP地址前三段相同&…...
机柜机箱制冷风扇在使用过程中突然停止运转的原因
在机柜机箱的正常运行中,制冷风扇起着关键的散热作用,可一旦它在使用时突然停止运转,将会对机柜机箱内设备的稳定运行构成严重威胁。而导致这一现象出现的原因较为复杂,主要涵盖以下几个方面。 从电源供应角度来看,这是…...
Python函数返回值250214
import requests from xml.etree import ElementTree as ETdef xml_to_list(city):data_list []url "...".format(city) # 具体url地址就不写了res requests.get(url url)root ET.XML(res.text)for node in root:data_list.append(node.text)return dat_listres…...
call、apply、bind 详解
在 JavaScript 中,call、apply 和 bind 是 Function 对象的三个重要方法,它们都与函数的上下文(this 值)和参数传递有关。 一、call 方法 1. 语法 function.call(thisArg, arg1, arg2, ...) 2. 示例代码 const person {name…...
详解电子邮箱工作原理|SMTP、POP3、IMAP、SPF、MIME
写在前面 电子邮件(Email)是一种通过互联网进行异步通信的技术,工作原理涉及多个协议、服务器和客户端协同工作。 接下来我们来介绍一下电子邮箱的工作原理 1. 电子邮件的核心组成部分 邮件客户端:用户直接交互的软件…...
QT笔记——QPlainTextEdit
文章目录 1、概要2、文本设计2.1、设置文本2.1、字体样式(大小、下划线、加粗、斜体) 1、概要 QPlainTextEdit 是 Qt 框架中用于处理纯文本编辑的控件,具有轻量级和高效的特点,以下是它常见的应用场景: 文本编辑器&am…...
Qt使用pri和pro文件进行模块化编程
假如我想要做一个功能,这个功能用代码模块化实现出来,方便将来移植,比如音视频播放器的界面,将来想要在其他工程使用时,只需要将widget提升为音视频播放界面即可。 当我们其他工程需要这个功能时,我们在调用…...
基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...
关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...
基于 TAPD 进行项目管理
起因 自己写了个小工具,仓库用的Github。之前在用markdown进行需求管理,现在随着功能的增加,感觉有点难以管理了,所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD,需要提供一个企业名新建一个项目&#…...
【C++进阶篇】智能指针
C内存管理终极指南:智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...
