053 性能压测 单机锁 setnx
文章目录
- 性能压测-压力测试
- 索引
- thymeleaf
- nginx
- 减少数据库查询(代码有bug)
- 缓存
- 安全
- 单机锁(防止缓存击穿)
- setnx
- pom.xml
性能压测-压力测试
1 响应时间(Response Time: RT):响应时间指用户从客户端发起一个请求开始,到客户端接收到从服务器端返回的响应结束,整个过程所耗费的时间。
HPS(Hits Per Second):每秒点击次数,单位是次/秒
TPS(Transaction per Second):系统图每秒处理交易数,单位是笔/秒
OPS(Query per Second):系统每秒处理查询次数,单位是次/秒
2 性能测试主要关注如下三个指标:
吞吐量:每秒钟系统能够处理的请求数、任务数
响应时间:服务处理一个请求或一个任务的耗时
错误率:一批请求中结果出错的请求所占比例
https://jmeter.apache.org/download_jmeter.cgi
索引

thymeleaf
spring:thymeleaf:cache: true
nginx
conf.d
location /static {root /usr/share/nginx/html;}location / {proxy_set_header Host $host;proxy_pass http://cubemall;}
减少数据库查询(代码有bug)
/*** 获取三级分类* @return*/@Overridepublic List<CategoryVo> getLevel1Categorys() {//改为查询所有分类List<CategoryEntity> selectList = baseMapper.selectList(null);List<CategoryEntity> categoryEntities = getParentId(selectList,0);List<CategoryVo> CategoryVoList = categoryEntities.stream().map(categoryEntity -> {CategoryVo categoryVo = new CategoryVo();BeanUtils.copyProperties(categoryEntity, categoryVo);//查询一级分类下的二级分类List<CategoryEntity> level2Categorys = getParentId(selectList,categoryEntity.getId());//将当前一级分类下的二级分类封装成Voif (level2Categorys != null) {List<Category2Vo> category2VoList = level2Categorys.stream().map(level2Category -> {Category2Vo category2Vo = new Category2Vo();category2Vo.setId(level2Category.getId().toString());category2Vo.setName(level2Category.getName());category2Vo.setCategory1Id(categoryEntity.getId().toString());//查询二级分类下的三级分类List<CategoryEntity> level3Categorys = getParentId(selectList,level2Category.getId());//将当前二级分类下的三级分类封装到Voif (level3Categorys != null) {List<Category3Vo> category3VoList = level3Categorys.stream().map(level3Category -> {Category3Vo category3Vo = new Category3Vo();category3Vo.setId(level3Category.getId().toString());category3Vo.setName(level3Category.getName());category3Vo.setCategory2Id(category2Vo.getId());return category3Vo;}).collect(Collectors.toList());category2Vo.setCategory3VoList(category3VoList);}return category2Vo;}).collect(Collectors.toList());categoryVo.setCategory2VoList(category2VoList);}return categoryVo;}).collect(Collectors.toList());return CategoryVoList;}private List<CategoryEntity> getParentId(List<CategoryEntity> selectList, Integer parentId) {List<CategoryEntity> collect = selectList.stream().filter(item -> {return item.getParentId() == parentId;}).collect(Collectors.toList());return collect;}
缓存

/*** 使用redis改造三级分类* @return*/public List<CategoryVo> getLevel1Categorys() {//1.从缓存中查询数据String categoryJSON = redisTemplate.opsForValue().get("categoryJSON");if (StringUtils.isEmpty(categoryJSON)) {//2.缓存中没有数据,查询数据库,从数据库查询分类数据List<CategoryVo> categoryJsonFromDb = getCategoryJsonFromDb();//3.查询的数据放入缓存中,将对象转换为json传入redisTemplate.opsForValue().set("categoryJSON", JSON.toJSONString(categoryJsonFromDb));return categoryJsonFromDb;}//4.如果缓存中有数据,将查询出的数据转换为java对象,指明转为的对象类型List<CategoryVo> categoryVos = JSON.parseObject(categoryJSON, new TypeReference<List<CategoryVo>>() {});return categoryVos;}
安全
单机锁(防止缓存击穿)

/*** 使用redis改造三级分类* @return*/public List<CategoryVo> getLevel1Categorys() {//1.从缓存中查询数据String categoryJSON = redisTemplate.opsForValue().get("categoryJSON");if (StringUtils.isEmpty(categoryJSON)) {System.out.println("缓存不命中,查询数据库。。。");//2.缓存中没有数据,查询数据库,从数据库查询分类数据List<CategoryVo> categoryJsonFromDb = getCategoryJsonFromDb();return categoryJsonFromDb;}System.out.println("缓存命中。。。");//4.如果缓存中有数据,将查询出的数据转换为java对象,指明转为的对象类型List<CategoryVo> categoryVos = JSON.parseObject(categoryJSON, new TypeReference<List<CategoryVo>>() {});return categoryVos;}/*** 获取三级分类* @return*/public List<CategoryVo> getCategoryJsonFromDb() {synchronized (this){//得到锁之后,去查看缓存中是否有数据,如果没有数据,继续查询数据库String categoryJSON = redisTemplate.opsForValue().get("categoryJSON");if(!StringUtils.isEmpty(categoryJSON)){List<CategoryVo> categoryVos = JSON.parseObject(categoryJSON, new TypeReference<List<CategoryVo>>() {});return categoryVos;}System.out.println("查询了数据库。。。");//改为查询所有分类List<CategoryEntity> selectList = baseMapper.selectList(null);List<CategoryEntity> categoryEntities = getParentId(selectList,0);List<CategoryVo> CategoryVoList = categoryEntities.stream().map(categoryEntity -> {CategoryVo categoryVo = new CategoryVo();BeanUtils.copyProperties(categoryEntity, categoryVo);//查询一级分类下的二级分类List<CategoryEntity> level2Categorys = getParentId(selectList,categoryEntity.getId());//将当前一级分类下的二级分类封装成Voif (level2Categorys != null) {List<Category2Vo> category2VoList = level2Categorys.stream().map(level2Category -> {Category2Vo category2Vo = new Category2Vo();category2Vo.setId(level2Category.getId().toString());category2Vo.setName(level2Category.getName());category2Vo.setCategory1Id(categoryEntity.getId().toString());//查询二级分类下的三级分类List<CategoryEntity> level3Categorys = getParentId(selectList,level2Category.getId());//将当前二级分类下的三级分类封装到Voif (level3Categorys != null) {List<Category3Vo> category3VoList = level3Categorys.stream().map(level3Category -> {Category3Vo category3Vo = new Category3Vo();category3Vo.setId(level3Category.getId().toString());category3Vo.setName(level3Category.getName());category3Vo.setCategory2Id(category2Vo.getId());return category3Vo;}).collect(Collectors.toList());category2Vo.setCategory3VoList(category3VoList);}return category2Vo;}).collect(Collectors.toList());categoryVo.setCategory2VoList(category2VoList);}return categoryVo;}).collect(Collectors.toList());//3.查询的数据放入缓存中,将对象转换为json传入redisTemplate.opsForValue().set("categoryJSON", JSON.toJSONString(CategoryVoList),1, TimeUnit.DAYS);return CategoryVoList;}}private List<CategoryEntity> getParentId(List<CategoryEntity> selectList, Integer parentId) {List<CategoryEntity> collect = selectList.stream().filter(item -> {return item.getParentId() == parentId;}).collect(Collectors.toList());return collect;}
setnx

/*** 获取三级分类(redis分布式锁)* @return*/public List<CategoryVo> getCategoryJsonFromWithRedisLock() {String uuid = UUID.randomUUID().toString();//1.占分布式Boolean lock = redisTemplate.opsForValue().setIfAbsent("lock", uuid,30,TimeUnit.SECONDS);if (lock){//加锁成功,执行业务//设置过期时间//redisTemplate.expire("lock",30,TimeUnit.SECONDS);//List<CategoryVo> dataFromDb = getDataFromDb();//删除锁
// String lockValue = redisTemplate.opsForValue().get("lock");
// if (uuid.equals(lockValue)) {
// //删除自己的锁
// redisTemplate.delete("lock");
// }List<CategoryVo> dataFromDb = null;try {dataFromDb = getDataFromDb();} finally {//删除锁String script = "if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end";redisTemplate.execute(new DefaultRedisScript<Integer>(script, Integer.class), Arrays.asList("lock"), uuid);}return dataFromDb;} else {//加锁失败,重试return getCategoryJsonFromWithRedisLock();//自旋}}private List<CategoryVo> getDataFromDb() {//得到锁之后,去查看缓存中是否有数据,如果没有数据,继续查询数据库String categoryJSON = redisTemplate.opsForValue().get("categoryJSON");if(!StringUtils.isEmpty(categoryJSON)){List<CategoryVo> categoryVos = JSON.parseObject(categoryJSON, new TypeReference<List<CategoryVo>>() {});return categoryVos;}System.out.println("查询了数据库。。。");//改为查询所有分类List<CategoryEntity> selectList = baseMapper.selectList(null);List<CategoryEntity> categoryEntities = getParentId(selectList,0);List<CategoryVo> CategoryVoList = categoryEntities.stream().map(categoryEntity -> {CategoryVo categoryVo = new CategoryVo();BeanUtils.copyProperties(categoryEntity, categoryVo);//查询一级分类下的二级分类List<CategoryEntity> level2Categorys = getParentId(selectList,categoryEntity.getId());//将当前一级分类下的二级分类封装成Voif (level2Categorys != null) {List<Category2Vo> category2VoList = level2Categorys.stream().map(level2Category -> {Category2Vo category2Vo = new Category2Vo();category2Vo.setId(level2Category.getId().toString());category2Vo.setName(level2Category.getName());category2Vo.setCategory1Id(categoryEntity.getId().toString());//查询二级分类下的三级分类List<CategoryEntity> level3Categorys = getParentId(selectList,level2Category.getId());//将当前二级分类下的三级分类封装到Voif (level3Categorys != null) {List<Category3Vo> category3VoList = level3Categorys.stream().map(level3Category -> {Category3Vo category3Vo = new Category3Vo();category3Vo.setId(level3Category.getId().toString());category3Vo.setName(level3Category.getName());category3Vo.setCategory2Id(category2Vo.getId());return category3Vo;}).collect(Collectors.toList());category2Vo.setCategory3VoList(category3VoList);}return category2Vo;}).collect(Collectors.toList());categoryVo.setCategory2VoList(category2VoList);}return categoryVo;}).collect(Collectors.toList());//3.查询的数据放入缓存中,将对象转换为json传入redisTemplate.opsForValue().set("categoryJSON", JSON.toJSONString(CategoryVoList),1, TimeUnit.DAYS);return CategoryVoList;}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.18.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.xd.cubemall</groupId><artifactId>cubemall-product</artifactId><version>0.0.1-SNAPSHOT</version><name>cubemall-product</name><description>cubemall-product</description><url/><licenses><license/></licenses><developers><developer/></developers><scm><connection/><developerConnection/><tag/><url/></scm><properties><java.version>1.8</java.version><spring-cloud.version>Greenwich.SR3</spring-cloud.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><exclusions><exclusion><groupId>io.lettuce</groupId><artifactId>lettuce-core</artifactId></exclusion></exclusions></dependency><!-- https://mvnrepository.com/artifact/redis.clients/jedis --><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId></dependency><!--当修改页面后不需要再重启项目--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId></dependency><!--引入common公共模块--><dependency><groupId>com.xd.cubemall</groupId><artifactId>cubemall-common</artifactId><version>0.0.1-SNAPSHOT</version></dependency><!--添加模板技术渲染页面--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!--阿里云OSS-->
<!-- <dependency>-->
<!-- <groupId>com.aliyun.oss</groupId>-->
<!-- <artifactId>aliyun-sdk-oss</artifactId>-->
<!-- <version>3.17.4</version>-->
<!-- </dependency>--></dependencies><dependencyManagement><dependencies><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>2.1.0.RELEASE</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>相关文章:
053 性能压测 单机锁 setnx
文章目录 性能压测-压力测试索引thymeleafnginx减少数据库查询(代码有bug)缓存 安全单机锁(防止缓存击穿)setnx pom.xml 性能压测-压力测试 1 响应时间(Response Time: RT):响应时间指用户从客…...
【天线】IFA天线知识点摘抄
MIFA天线的尺寸与性能关系 1,辐射效率 天线越小,辐射效率越低。唯一好处是减少PCB占用空间 2,带宽 一般MIFA天线在2.4G频段内的带宽:S11≤-10dB的范围为2.44GHz230MHz。较小的尺寸可能会限制带宽 3,增益 MIFA天线的…...
Mysql视图有什么作用?你是否使用过视图?
MySQL视图(View)是一种虚拟表,其内容由查询定义。视图并不实际存储数据,而是基于一个或多个表的查询结果生成。以下是关于MySQL视图的详细说明: 1. 视图的定义 概念:视图是一个虚拟表,其内容由…...
【vue项目如何利用event-stream实现文字流式输出效果】
引言 在现代 Web 应用中,实时数据展示是一个常见需求,例如聊天消息逐字显示、日志实时推送、股票行情更新等。传统的轮询或一次性数据加载方式无法满足这类场景的流畅体验,而 流式传输(Streaming) 技术则能实现数据的…...
微信问题总结(onpageshow ,popstate事件)
此坑描述 订单详情某按钮点击,通过window.location.href跳转到(外部)第三方链接后,回退后,在ios中生命周期和路由导航钩子都失效了,无法触发。 在安卓中无视此坑, 回退没有问题 解决 原因&am…...
【Gin-Web】Bluebell社区项目梳理3:社区相关接口开发
本文目录 一、接口详情1. 获取分类社区列表接口2. 根据id查询社区 二、值类型与引用类型 一、接口详情 跟社区有关的接口详情如下。 1. 获取分类社区列表接口 首先是Controller层,然后跳转到Logic层业务逻辑的开发。 这是Logic层,再做一次跳转&#…...
Unity 聊天气泡根据文本内容适配
第一步 拼接UI 1、对气泡图进行九宫图切割 2、设置底图pivot位置和对齐方式 pivot位置:(0,1) 对齐方式:左上对齐 3、设置文本pivot位置和对齐方式,并挂上布局组件 pivot设置和对齐方式和底图一样&#…...
对学习编程语言的一些理解
目录 一、代码运行的过程 二、跨平台的实现 1)C/C 2)C# 3)Java 三、总结 一、代码运行的过程 开发程序无论使用何种编程语言,至少都需要经历编码、编译、连接和运行这么4个过程,C语言是这样,Java语言…...
MySQL MHA 部署全攻略:从零搭建高可用数据库架构
文章目录 1.MHA介绍2.MHA组件介绍3.集群规划4.服务器初始化5.MySQL集群部署5.1 安装MySQL集群5.2 配置一主两从5.3 测试MySQL主从5.4 赋予MHA用户连接权限 6.安装MHA环境6.1 安装MHA Node6.2 安装MHA Manager 7.配置MHA环境8.MySQL MHA高可用集群测试8.1 通过VIP连接MySQL8.2模…...
windows怎样查看系统信息(处理器等)
首先打开命令行工具 win R 输入 cmd, 输入 msinfo32 ,然后回车 这个页面就可以看到 电脑的锐龙版就是 AMD 芯片 酷睿版就是 intel 芯片...
007 HBuilderX提示IDE service port disabled. To use CLI Call, open IDE
描述 微信小程序 工具的服务端口已关闭 解决方案 在HBuider的菜单“运行”选择“运行到小程序模拟器-微信开发者工具”时,步骤如图: 提示:IDE service port disabled. To use CLI Call, open IDE -> Settings -> Security Settings,…...
计算机网络之TCP的可靠传输
上一篇内容可能比较多,显得比较杂乱,这一篇简单总结一下TCP是靠什么实现可靠传输的吧。 校验和 TCP是端到端的传输,由发送方计算校验和,接收方进行验证,目的是为了验证TCP首部和数据在发送过程中没有任何改动&#x…...
Python爬虫系列教程之第十四篇:爬虫项目部署、调度与监控系统
大家好,欢迎继续关注本系列爬虫教程! 在前面的文章中,我们已经详细讲解了如何构建爬虫、如何处理反爬、如何实现分布式爬虫以及如何使用 Scrapy 框架开发高效的爬虫项目。随着项目规模的不断扩大,如何将爬虫项目稳定部署到生产环境…...
线程与进程的深入解析及 Linux 线程编程
在操作系统中,进程和线程是进行并发执行的两种基本单位。理解它们的区别和各自的特点,能够帮助开发者更好地进行多任务编程,提高程序的并发性能。本文将探讨进程和线程的基础概念,及其在 Linux 系统中的实现方式,并介绍…...
在ubuntu上用Python的openpyxl模块操作Excel的案例
文章目录 安装模块读取Excel数据库取数匹配数据和更新Excel数据 在Ubuntu系统的环境下基本职能借助Python的openpyxl模块实现对Excel数据的操作。 安装模块 本次需要用到的模块需要提前安装(如果没有的话) pip3 install openpyxl pip3 install pymysql在操作前,需…...
【OS安装与使用】part6-ubuntu 22.04+CUDA 12.4运行MARL算法(多智能体强化学习)
文章目录 一、待解决问题1.1 问题描述1.2 解决方法 二、方法详述2.1 必要说明2.2 应用步骤2.2.1 下载源码并安装2.2.2 安装缺失的依赖项2.2.3 训练执行MAPPO算法实例 三、疑问四、总结 一、待解决问题 1.1 问题描述 已配置好基础的运行环境,尝试运行MARL算法。 1…...
【Python爬虫(35)】解锁Python多进程爬虫:高效数据抓取秘籍
【Python爬虫】专栏简介:本专栏是 Python 爬虫领域的集大成之作,共 100 章节。从 Python 基础语法、爬虫入门知识讲起,深入探讨反爬虫、多线程、分布式等进阶技术。以大量实例为支撑,覆盖网页、图片、音频等各类数据爬取ÿ…...
HarmonyOS 开发套件 介绍 ——上篇
HarmonyOS 开发套件 介绍 ——上篇 在当今科技飞速发展的时代,操作系统作为智能设备的核心,其重要性不言而喻。而HarmonyOS,作为华为推出的全新操作系统,正以其独特的魅力和强大的功能,吸引着越来越多的开发者和用户的…...
Linux 高级篇 日志管理、定制自己的Linux系统、备份与恢复
一、日志管理 (1)基本介绍 日志文件是重要的系统信息文件,记录了如用户登录、系统启动、系统安全、邮件及各种服务等相关重要系统事件在安全方面,日志也至关重要,它能记录系统日常发生的各类事情,可用于检…...
deepseek与其他大模型配合组合
DeepSeek与其他大模型的配合组合,展现了其在多个领域中的强大应用潜力和灵活性。以下是对DeepSeek与其他大模型配合组合的详细分析: 一、DeepSeek与华知大模型的组合 背景介绍: 华知大模型是同方知网与华为联手打造的,具备全学科…...
别再死记硬背了!从勾股定理到斜率乘积-1,一个初中生也能懂的几何证明
从勾股定理到斜率关系:一场初中生也能玩转的几何推理游戏 数学课本上那些冷冰冰的公式,常常让学生们望而生畏。特别是当老师要求"记住这个结论"时,很多同学的第一反应是机械背诵,而不是理解背后的逻辑。今天,…...
React Native App Auth源码架构解析:理解AppAuth桥接层实现原理
React Native App Auth源码架构解析:理解AppAuth桥接层实现原理 【免费下载链接】react-native-app-auth React native bridge for AppAuth - an SDK for communicating with OAuth2 providers 项目地址: https://gitcode.com/gh_mirrors/re/react-native-app-aut…...
【LeetCode刷题日记】225.用队列实现栈--三招实现栈操作(多种思维)
🔥个人主页:北极的代码(欢迎来访) 🎬作者简介:java后端学习者 ❄️个人专栏:苍穹外卖日记,SSM框架深入,JavaWeb ✨命运的结局尽可永在,不屈的挑战却不可须臾或…...
Advantech工业连接器国产替代方案与选型实践解析
在工业计算机与嵌入式系统领域,连接器不仅是基础互连器件,更是系统稳定运行的重要保障。Advantech 作为工业计算机行业的代表厂商,其产品广泛应用于工业自动化、智能制造、医疗设备、交通系统及物联网等领域。虽然 Advantech 本身并非传统意义…...
LSTM在多元时间序列预测中的实战应用
1. 理解LSTM在多元时间序列预测中的应用长短期记忆网络(LSTM)作为循环神经网络(RNN)的一种特殊变体,在处理时间序列数据时展现出独特优势。与传统的线性方法相比,LSTM能够自动学习时间序列中的长期依赖关系…...
Flux2-Klein-9B-True-V2文生图教程:电影级打光提示词(伦勃朗/蝴蝶光)
Flux2-Klein-9B-True-V2文生图教程:电影级打光提示词(伦勃朗/蝴蝶光) 1. 项目简介与快速入门 Flux2-Klein-9B-True-V2是基于FLUX.2-Klein-9B微调的图片生成模型,专为高质量图像生成和编辑而设计。这个模型特别适合需要专业级光影…...
从信号处理到图像压缩:用Python手把手理解傅里叶矩阵与FFT的底层原理
从信号处理到图像压缩:用Python手把手理解傅里叶矩阵与FFT的底层原理 在数字信号处理领域,傅里叶变换就像一把瑞士军刀,它能将时域信号分解为频域成分,这种能力在音频分析、图像压缩和通信系统中发挥着核心作用。但你是否想过&…...
终极NHS UK Frontend教程:3步构建专业医疗网站界面
终极NHS UK Frontend教程:3步构建专业医疗网站界面 【免费下载链接】nhsuk-frontend NHS.UK frontend contains the code you need to start building user interfaces for NHS websites and services. 项目地址: https://gitcode.com/gh_mirrors/nh/nhsuk-fronte…...
ABAP 与七伤拳
我每次在项目里看到某些 ABAP 写法,脑子里都会蹦出《倚天屠龙记》里的七伤拳。原因不神秘,这门功夫最扎人的地方,不只是威力大,而是练功和出拳的代价会先落回自己身上。公开资料里对七伤拳的描述很一致,它被概括为一门先伤己后伤人的拳法,内力不够、根基不稳时,强行修炼…...
Kubernetes监控核心组件kube-state-metrics:原理、部署与生产调优指南
1. 项目概述:Kubernetes集群的“状态仪表盘”在Kubernetes的世界里,我们常说“可观测性”是运维的生命线。你部署了Deployment,创建了Service,挂载了ConfigMap,但你怎么知道你的应用副本数是否健康?你的Pod…...
