【黑马点评】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提升为音视频播放界面即可。 当我们其他工程需要这个功能时,我们在调用…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...
leetcodeSQL解题:3564. 季节性销售分析
leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...

SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...