傻瓜式搭建网站/电脑优化软件

傻瓜式搭建网站,电脑优化软件,建立b2c网站,武汉做公司网站的公司目录 引言 解决办法 互斥锁(强一致,性能差) 逻辑过期(高可用,性能优) 设计逻辑过期时间 引言 缓存击穿:给某一个key设置了过期时间,当key过期的时候,恰好这个时间点对…

目录

引言

解决办法

        互斥锁(强一致,性能差)

        逻辑过期(高可用,性能优)

设计逻辑过期时间


引言

        缓存击穿:给某一个key设置了过期时间,当key过期的时候,恰好这个时间点对这个key有大量的并发请求过来,这些并发的请求可能会瞬间把DB压垮

解决办法

        互斥锁(强一致,性能差)

                

 根据图片就可以看出,我们的思路就是只能让一个线程能够进行访问Redis,要想实现这个功能,我们也可以使用Redis自带的setnx

封装两个方法,一个写key来尝试获取锁另一个删key来释放锁

/*** 尝试获取锁** @param key* @return*/
private boolean tryLock(String key) {Boolean flag = stringRedisTemplate.opsForValue().setIfAbsent(key, "1", 10, TimeUnit.SECONDS);return BooleanUtil.isTrue(flag);
}/*** 释放锁** @param key*/
private void unlock(String key) {stringRedisTemplate.delete(key);
}

在并行情况下每当其他线程想要获取锁,来访问缓存都要通过将自己的key写到tryLock()方法里,setIfAbsent()返回false则说明有线程在在更新缓存数据,锁未释放。若返回true则说明当前线程拿到锁了可以访问缓存甚至操作缓存。
我们在下面一个热门的查询场景中用代码用代码来实现互斥锁解决缓存击穿,代码如下:

    /*** 解决缓存击穿的互斥锁* @param id* @return*/public Shop queryWithMutex(Long id) {String key = CACHE_SHOP_KEY + id;//1.从Redis查询缓存String shopJson = stringRedisTemplate.opsForValue().get(key);  //JSON格式//2.判断是否存在if (StrUtil.isNotBlank(shopJson)) { //不为空就返回 此工具类API会判断" "为false//存在则直接返回Shop shop = JSONUtil.toBean(shopJson, Shop.class);//return Result.ok(shop);return shop;}//3.判断是否为空值 这里过滤 " "的情况,不用担心会一直触发这个条件因为他有TTLif (shopJson != null) {//返回一个空值return null;}//4.缓存重建 Redis中值为null的情况//4.1获得互斥锁String lockKey = "lock:shop"+id;Shop shopById=null;try {boolean isLock = tryLock(lockKey);//4.2判断是否获取成功if (!isLock){//4.3失败,则休眠并重试Thread.sleep(50);return queryWithMutex(id);}//4.4成功,根据id查询数据库shopById = getById(id);//5.不存在则返回错误if (shopById == null) {//将空值写入RedisstringRedisTemplate.opsForValue().set(key, "", CACHE_NULL_TTL, TimeUnit.MINUTES);//为什么这里要存一个" "这是因为如果后续DB中有数据补充的话还可以去重建缓存//return Result.fail("暂无该商铺信息");return null;}//6.存在,写入RedisstringRedisTemplate.opsForValue().set(key, JSONUtil.toJsonStr(shopById), CACHE_SHOP_TTL, TimeUnit.MINUTES);} catch (InterruptedException e) {throw new RuntimeException(e);} finally {//7.释放互斥锁unlock(lockKey);}return shopById;}

        逻辑过期(高可用,性能优)

        方案:用户查询某个热门产品信息,如果缓存未命中(即信息为空),则直接返回空,不去查询数据库。如果缓存信息命中,则判断是否逻辑过期,未过期返回缓存信息,过期则重建缓存,尝试获得互斥锁,获取失败则直接返回已过期缓存数据,获取成功则开启独立线程去重构缓存然后直接返回旧的缓存信息,重构完成之后就释放互斥锁。

封装一个方法用来模拟更新逻辑过期时间与缓存的数据在测试类里运行起来达到数据与热的效果 

/*** 添加逻辑过期时间** @param id* @param expireTime*/
public void saveShopRedis(Long id, Long expireTime) {//查询店铺信息Shop shop = getById(id);//封装逻辑过期时间RedisData redisData = new RedisData();redisData.setData(shop);redisData.setExpireTime(LocalDateTime.now().plusSeconds(expireTime));//将封装过期时间和商铺数据的对象写入RedisstringRedisTemplate.opsForValue().set(CACHE_SHOP_KEY + id, JSONUtil.toJsonStr(redisData));
}

查询接口:

/*** 逻辑过期解决缓存击穿** @param id* @return*/
public Shop queryWithLogicalExpire(Long id) throws InterruptedException {String key = CACHE_SHOP_KEY + id;Thread.sleep(200);//1.从Redis查询缓存String shopJson = stringRedisTemplate.opsForValue().get(key);  //JSON格式//2.判断是否存在if (StrUtil.isBlank(shopJson)) {//不存在则直接返回return null;}//3.判断是否为空值if (shopJson != null) {//返回一个空值//return Result.fail("店铺不存在!");return null;}//4.命中//4.1将JSON反序列化为对象RedisData redisData = JSONUtil.toBean(shopJson, RedisData.class);Shop shop = JSONUtil.toBean((JSONObject) redisData.getData(), Shop.class);LocalDateTime expireTime = redisData.getExpireTime();//4.2判断是否过期if (expireTime.isAfter(LocalDateTime.now())) {//5.未过期则返回店铺信息return shop;}//6.过期则缓存重建//6.1获取互斥锁String LockKey = LOCK_SHOP_KEY + id;boolean isLock = tryLock(LockKey);//6.2判断是否成功获得锁if (isLock) {//6.3成功,开启独立线程,实现缓存重建CACHE_REBUILD_EXECUTOR.submit(() -> {try {//重建缓存this.saveShop2Redis(id, 20L);} catch (Exception e) {throw new RuntimeException(e);} finally {//释放锁unlock(LockKey);}});}//6.4返回商铺信息return shop;
}

设计逻辑过期时间

可以用这个方法设置逻辑过期时间

  import org.redisson.Redisson;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;public class RedissonExample {public static void main(String[] args) {Config config = new Config();config.useSingleServer().setAddress("redis://127.0.0.1:6379");RedissonClient redisson = Redisson.create(config);String key = "exampleKey";String value = "exampleValue";int timeout = 10; // 过期时间(秒)// 获取RBucket对象RBucket<String> bucket = redisson.getBucket(key);// 设置值并指定过期时间bucket.set(value, timeout, TimeUnit.SECONDS);System.out.println("设置成功");redisson.shutdown();}
}

 大家可以看到,逻辑过期锁就是可以实现并发,所以他的效率更快,性能更好

但是

  • 牺牲了数据的实时性,以保证高并发场景下的服务可用性和数据库的稳定性。

  • 在实际应用中,需要确保获取互斥锁的操作是原子的,并且锁具有合适的超时时间,以避免死锁的发生。

  • 逻辑过期策略适用于那些对数据实时性要求不高,但要求服务高可用性的场景。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/72792.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

架构思维:软件建模与架构设计的关键要点

文章目录 1. 软件建模的核心概念2. 七种常用UML图及其应用场景类图时序图组件图部署图用例图状态图活动图 3. 软件设计文档的三阶段结构4. 架构设计的关键实践1. 用例图&#xff1a;核心功能模块2. 部署图&#xff1a;架构演进阶段3. 技术挑战与解决方案4. 关键架构图示例5. 架…

numpy学习笔记14:模拟随机游走过程(一次实验)

numpy学习笔记14&#xff1a;模拟随机游走过程(一次实验) 随机游走是一个对象在离散时间步中的随机移动&#xff0c;每次移动的方向和步长由概率决定。在用户提供的代码中&#xff0c;步长数组steps的每个元素是-1或1&#xff0c;代表向左或向右移动一步。np.random.choice的作…

FPGA-DE2115开发板实现流水灯

文章目录 一、安装VScode&#xff0c;在其中下载安装Verilog-HDL/SystemVerilog插件&#xff1b;&#xff08;1&#xff09;安装VScode&#xff08;2&#xff09;安装插件&#xff08;3&#xff09;与Quartus关联 二、不分模块实现流水灯&#xff08;1&#xff09;新建工程&…

JS逆向案例-HIKVISION-视频监控的前端密码加密分析

免责声明 本文仅为技术研究与渗透测试思路分享,旨在帮助安全从业人员更好地理解相关技术原理和防御措施。任何个人或组织不得利用本文内容从事非法活动或攻击他人系统。 如果任何人因违反法律法规或不当使用本文内容而导致任何法律后果,本文作者概不负责。 请务必遵守法律…

碰一碰发视频saas系统技术源头一站式开发文档

碰一碰发视频系统技术源头一站式开发文档 一、引言 在数字化信息传播高速发展的当下&#xff0c;如何让视频分享更便捷、高效&#xff0c;成为商家和开发者们关注的焦点。“碰一碰发视频”系统以其独特的交互方式和强大的功能优势&#xff0c;为视频分享领域带来了革命性变革。…

VSCode + CMake

参考文献&#xff1a; 如何用 GCC, CMake 和 Make 编译C/C代码Windows 上的 Linux 子系统&#xff1a;WSLWSL&#xff1a;桌面 UI 远程连接 RDP 配置 VScode 文章目录 CMake 配置VSCode 配置launch.jsontask.jsonc_cpp_properties.json CMake 配置 编写如下的 CmakeLists.t…

yolov5学习及手势识别实战

目录 一、YOLOv5核心原理 1. 单阶段检测范式 2. 关键技术特性 二、YOLOv5网络架构组成 1. Backbone&#xff1a;CSPDarknet53 2. Neck&#xff1a;PANet&#xff08;Path Aggregation Network&#xff09; 3. Head&#xff1a;检测头 三、YOLOv5网络架构细节 1. 整体架…

VMware-workstation-17.6.3安装教程

1.下载VMware-workstation-17.6.3软件包 2.安装并输入许可码 3.开始使用

[Linux][经验总结]Ubuntu6.11.0 docker更换镜像源(实操可用的正确方法)

一、前言 关于Ubuntu更换docker镜像源&#xff0c;网上有很多的教程&#xff0c;但在实操中发现&#xff0c;更换的源无法生效——原因是我的docker是在系统安装时&#xff0c;选择附加安装的package的方式安装的。 现将处理过程记录如下。 二、获取镜像源 在网上随便找个几…

Element Plus开发实战指南:快速上手Vue 3企业级组件库

Element Plus全栈开发指南&#xff1a;从入门到企业级实战 一、环境搭建与工程配置1.1 项目初始化&#xff08;Windows/Mac通用&#xff09;1.2 配置文件关键代码 二、主题定制与样式管理2.1 SCSS变量覆盖方案2.2 暗黑模式切换 三、核心组件深度实践3.1 智能表格开发&#xff0…

VIVO手机如何实现证件照换底色?证件照换底色技巧分享

在日常生活中&#xff0c;我们常常需要使用不同底色的证件照&#xff0c;无论是办理证件、提交资料还是其他用途&#xff0c;一张符合要求的证件照都显得尤为重要。 而VIVO手机凭借其强大的拍照功能和便捷的图片编辑工具&#xff0c;为我们提供了一种简单高效的证件照换底色解…

A SURVEY ON POST-TRAINING OF LARGE LANGUAGE MODELS——大型语言模型的训练后优化综述——第一部分

arXiv 2025 摘要 大型语言模型&#xff08;LLMs&#xff09;的出现从根本上改变了自然语言处理&#xff0c;使其在从对话系统到科学研究的各个领域中变得不可或缺。然而&#xff0c;它们的预训练架构在特定情境下经常显示出局限性&#xff0c;包括有限的推理能力、伦理不确定…

深入理解Python闭包与递归:原理、应用与实践

目录 闭包 什么是闭包&#xff1a; 闭包的基本结构&#xff1a; 实现闭包的条件&#xff1a; 1.嵌套函数 2.内函数引用外部函数的变量 3.外部函数返回内部函数 4.外部函数已经执行完毕 递归函数 什么是递归函数&#xff1a; 递归函数条件 1.必须有个明确的结束条…

ABAP PDF预览

画个屏幕 PDF JPG TXT都可以参考预览&#xff0c;把二进制流传递给标准函数就行 *&---------------------------------------------------------------------* *& Report YDEMO2 *&---------------------------------------------------------------------* *&am…

【视频】文本挖掘专题:Python、R用LSTM情感语义分析实例合集|上市银行年报、微博评论、红楼梦、汽车口碑数据采集词云可视化

原文链接&#xff1a;https://tecdat.cn/?p41149 分析师&#xff1a;Zhenzhen Liu&#xff0c;Shuai Fung 作为数据科学家&#xff0c;我们始终关注如何从非结构化数据中提取高价值信息。本专题合集聚焦企业年报的文本分析技术&#xff0c;通过Python与R语言实战案例&#xff…

高效团队开发的工具与方法 引言

引言 在现代软件开发领域&#xff0c;团队协作的效率和质量直接决定了项目的成败。随着项目规模的扩大和技术复杂度的增加&#xff0c;如何实现高效团队开发成为每个开发团队必须面对的挑战。高效团队开发不仅仅是个人技术能力的简单叠加&#xff0c;更需要借助合适的工具和方…

Python----计算机视觉处理(Opencv:图像颜色替换)

一、开运算 开运算就是对图像先进行腐蚀操作&#xff0c; 然后进行膨胀操作。开运算可以去除二值化图中的小的噪点&#xff0c;并分离相连的物体。 其主要目的就是消除那些小白点 在开运算组件中&#xff0c;有一个叫做kernel的参数&#xff0c;指的是核的大小&#xff0c;通常…

基于SpringBoot的“ERP-物资管理”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“ERP-物资管理”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 系统总体结构图 E-R实体关系图 管理员登录界面 管…

链表操作:分区与回文判断

目录 链表分区&#xff08;Partition&#xff09; 功能概述 代码实现 要点与难点 注意事项 链表回文判断&#xff08;PalindromeList&#xff09; 功能概述 代码实现 要点与难点 注意事项 总结 在链表相关的算法问题中&#xff0c;理解链表的基本结构和操作至关重要…

如何在 Node.js 中使用 .env 文件管理环境变量 ?

Node.js 应用程序通常依赖于环境变量来管理敏感信息或配置设置。.env 文件已经成为一种流行的本地管理这些变量的方法&#xff0c;而无需在代码存储库中公开它们。本文将探讨 .env 文件为什么重要&#xff0c;以及如何在 Node.js 应用程序中有效的使用它。 为什么使用 .env 文…