高并发如何实现单用户信息查询接口

2023-12-16 08:20

本文主要是介绍高并发如何实现单用户信息查询接口,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

高并发如何实现单用户信息查询接口

故事情节

  • 产品:小李,有个单用户信息查询的功能,需要你实现一下
  • 小李:这还不简单,两分钟我给你实现
  • 两分钟过去…
  • 小李:欧克了,部署上线了
  • 运维:哪个傻蛋写的接口,导致MySQL宕机了
  • 小李一愣,他写的接口明明没有报错啊,这是怎么回事呢?
  • 产品:小李赶紧给我排查出来,否则这个月的奖金一分都没有
  • 小李:这这这,我不知道什么问题啊
  • 小李纳闷中,思来思去不知道什么问题如何解决…
  • 小李:老黄,只能求你出马了,这个月我的奖金全部都给你
  • 老黄听到小李的请求,他微微一笑,答应了下来
  • 老黄:么得问题了
  • 老黄耐心地指导小李修复了这个错误,并对代码进行了优化和完善
  • 小李听得认真,心里暗自发誓要吸取教训,以后在工作中更加严谨细致。而这次经历也让他对老黄产生了更深的敬意和信任
  • 最终,小李成功排查并解决了问题,产品顺利上线运行。产品部门的领导对他的表现给予了肯定和赞赏,而他也因为自己的努力和进步获得了全额的奖金

小李写的代码:

Service层:
直接查询MySQL返回数据

 public UserQueryRespDTO queryUserByUserId(Long userId) {LambdaQueryWrapper<UserDO> queryWrapper = Wrappers.lambdaQuery(UserDO.class).eq(UserDO::getUserId, userId);List<UserDO> userDOList = userMapper.selectList(queryWrapper);UserDO userDO = CollUtil.isNotEmpty(userDOList) ? userDOList.get(0) : null;UserQueryRespDTO userQueryRespDTO = new UserQueryRespDTO();BeanUtil.convert(userDO, userQueryRespDTO);return userQueryRespDTO;
}

流程图:
在这里插入图片描述

http 请求直接打到 MySQL 数据库,不宕机才怪嘞

老黄写的代码:

Service层:

  1. 先读取 Redis 缓存,数据存在直接返回用户
  2. 数据不存在,读取 MySQL 数据库,加上双重判定锁,减轻获得分布式锁后线程访问数据库压力
  3. 读取到 MySQL 数据,缓存到 Redis 并且返回
  4. 读取数据为NULL,缓存空对象到 Redis 中,并设置一个较短的过期时间(防止缓存穿透)
public UserQueryRespDTO queryUserByUserId(Long userId) {UserDO userDO = distributedCache.safeGet(USER_INFO_KEY + userId,UserDO.class,() -> {LambdaQueryWrapper<UserDO> queryWrapper = Wrappers.lambdaQuery(UserDO.class).eq(UserDO::getUserId, userId);List<UserDO> userDOList = userMapper.selectList(queryWrapper);return CollUtil.isNotEmpty(userDOList) ? userDOList.get(0) : null;},30,TimeUnit.MINUTES,null,null,key -> {// 缓存空对象,解决缓存穿透。也可以使用布隆过滤器。distributedCache.put(key, new UserDO(), 5, TimeUnit.MINUTES);});UserQueryRespDTO userQueryRespDTO = new UserQueryRespDTO();BeanUtil.convert(userDO, userQueryRespDTO);return userQueryRespDTO;
}

第二行distributedCache.safeGet方法

public <T> T safeGet(String key, Class<T> clazz, CacheLoader<T> cacheLoader, long timeout, TimeUnit timeUnit,RBloomFilter<String> bloomFilter, CacheGetFilter<String> cacheGetFilter, CacheGetIfAbsent<String> cacheGetIfAbsent) {T result = get(key, clazz);// 缓存结果不等于空或空字符串直接返回;通过函数判断是否返回空,为了适配布隆过滤器无法删除的场景;两者都不成立,判断布隆过滤器是否存在,不存在返回空if (!CacheUtil.isNullOrBlank(result)|| Optional.ofNullable(cacheGetFilter).map(each -> each.filter(key)).orElse(false)|| Optional.ofNullable(bloomFilter).map(each -> !each.contains(key)).orElse(false)) {return result;}RLock lock = redissonClient.getLock(SAFE_GET_DISTRIBUTED_LOCK_KEY_PREFIX + key);lock.lock();try {// 双重判定锁,减轻获得分布式锁后线程访问数据库压力if (CacheUtil.isNullOrBlank(result = get(key, clazz))) {// 如果访问 cacheLoader 加载数据为空,执行后置函数操作if (CacheUtil.isNullOrBlank(result = loadAndSet(key, cacheLoader, timeout, timeUnit, true, bloomFilter))) {Optional.ofNullable(cacheGetIfAbsent).ifPresent(each -> each.execute(key));}}} finally {lock.unlock();}return result;
}

流程图:
在这里插入图片描述

这篇关于高并发如何实现单用户信息查询接口的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/499822

相关文章

SpringBoot集成Milvus实现数据增删改查功能

《SpringBoot集成Milvus实现数据增删改查功能》milvus支持的语言比较多,支持python,Java,Go,node等开发语言,本文主要介绍如何使用Java语言,采用springboo... 目录1、Milvus基本概念2、添加maven依赖3、配置yml文件4、创建MilvusClient

JS+HTML实现在线图片水印添加工具

《JS+HTML实现在线图片水印添加工具》在社交媒体和内容创作日益频繁的今天,如何保护原创内容、展示品牌身份成了一个不得不面对的问题,本文将实现一个完全基于HTML+CSS构建的现代化图片水印在线工具... 目录概述功能亮点使用方法技术解析延伸思考运行效果项目源码下载总结概述在社交媒体和内容创作日益频繁的

SQL表间关联查询实例详解

《SQL表间关联查询实例详解》本文主要讲解SQL语句中常用的表间关联查询方式,包括:左连接(leftjoin)、右连接(rightjoin)、全连接(fulljoin)、内连接(innerjoin)、... 目录简介样例准备左外连接右外连接全外连接内连接交叉连接自然连接简介本文主要讲解SQL语句中常用的表

openCV中KNN算法的实现

《openCV中KNN算法的实现》KNN算法是一种简单且常用的分类算法,本文主要介绍了openCV中KNN算法的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录KNN算法流程使用OpenCV实现KNNOpenCV 是一个开源的跨平台计算机视觉库,它提供了各

OpenCV图像形态学的实现

《OpenCV图像形态学的实现》本文主要介绍了OpenCV图像形态学的实现,包括腐蚀、膨胀、开运算、闭运算、梯度运算、顶帽运算和黑帽运算,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起... 目录一、图像形态学简介二、腐蚀(Erosion)1. 原理2. OpenCV 实现三、膨胀China编程(

通过Spring层面进行事务回滚的实现

《通过Spring层面进行事务回滚的实现》本文主要介绍了通过Spring层面进行事务回滚的实现,包括声明式事务和编程式事务,具有一定的参考价值,感兴趣的可以了解一下... 目录声明式事务回滚:1. 基础注解配置2. 指定回滚异常类型3. ​不回滚特殊场景编程式事务回滚:1. ​使用 TransactionT

MySQL高级查询之JOIN、子查询、窗口函数实际案例

《MySQL高级查询之JOIN、子查询、窗口函数实际案例》:本文主要介绍MySQL高级查询之JOIN、子查询、窗口函数实际案例的相关资料,JOIN用于多表关联查询,子查询用于数据筛选和过滤,窗口函... 目录前言1. JOIN(连接查询)1.1 内连接(INNER JOIN)1.2 左连接(LEFT JOI

Android实现打开本地pdf文件的两种方式

《Android实现打开本地pdf文件的两种方式》在现代应用中,PDF格式因其跨平台、稳定性好、展示内容一致等特点,在Android平台上,如何高效地打开本地PDF文件,不仅关系到用户体验,也直接影响... 目录一、项目概述二、相关知识2.1 PDF文件基本概述2.2 android 文件访问与存储权限2.

MySQL 中查询 VARCHAR 类型 JSON 数据的问题记录

《MySQL中查询VARCHAR类型JSON数据的问题记录》在数据库设计中,有时我们会将JSON数据存储在VARCHAR或TEXT类型字段中,本文将详细介绍如何在MySQL中有效查询存储为V... 目录一、问题背景二、mysql jsON 函数2.1 常用 JSON 函数三、查询示例3.1 基本查询3.2

使用Python实现全能手机虚拟键盘的示例代码

《使用Python实现全能手机虚拟键盘的示例代码》在数字化办公时代,你是否遇到过这样的场景:会议室投影电脑突然键盘失灵、躺在沙发上想远程控制书房电脑、或者需要给长辈远程协助操作?今天我要分享的Pyth... 目录一、项目概述:不止于键盘的远程控制方案1.1 创新价值1.2 技术栈全景二、需求实现步骤一、需求