接口性能优化思路
前言
日常开发中设计接口,响应时间是衡量一个接口质量的重要指标。
接口响应时间这里粗糙地分为三种:
- 即时响应:毫秒级,小于500毫秒
- 快速响应:秒级,大于500毫秒且小于2秒
- 长时间操作:大于2秒,甚至是分钟级别的操作
一般接口都是需要快速响应的,在不考虑任何优化策略的情况下,如果整个业务逻辑走下来,响应时间大于了2秒,那么就应该考虑对这个接口进行性能优化了,以免影响了用户的体验。
优化思路
缓存
毫无疑问,使用缓存是对性能提升最明显的方法。
若是缓存中存在,直接返回结果,否则再走接口逻辑,最后将结果放入缓存中,以便下次查询时使用。
缓存还可以分为本地缓存和分布式缓存
本地缓存:
由于数据是在本地内存,它的访问速度是最快的,同时它的容量也受限于运行本地内存,以及在分布式系统中,本地缓存的数据很可能和其他节点的数据不一致。所以本地缓存一般用来存储一些系统级别上基本上不会改变的内容。
在 Java 实现中,最简单的本地缓存其实可以用一个 ConcurrentHashMap 来实现,不过在实际开发中有更好的选择,可以选择 Caffeine 来做本地缓存,性能更好。
分布式缓存:
分布式缓存相对本地缓存,多了一次网络交互,所以速度会慢一些,但是大小则不会受制于本地服务机器内存了,内存不够用了还可以通过水平扩容来解决,而且在分布式系统中, 数据的一致性能够得以保证。
常用的分布式缓存为 Redis 和 MemCached,MemCached 更加轻量级一些,纯粹的缓存中间件,Redis 不仅仅可以作为缓存,它还支持更多的功能(分布式锁,分布式限流,地理位置应用,布隆过滤器等等)
异步
如果是单线程执行业务逻辑,那么可以考虑对业务逻辑进行拆分,将其中能够并行执行的部分分解出来,然后使用多线程的方式去同时运行,理论上能够将该部分的运行性能提升(提升的大小取决于能够同时运行的线程数)
Java 中可以使用线程池 ThreadPool 来并发执行任务,进阶一点还可以使用 CompletableFuture 来编排异步任务。
合并
合并其实是指将批量操作,将多个操作合并成一个去执行
例如数据库中的批量插入,同一个表的多条插入语句,其实可以优化成一个插入语句,这样可以减少数据库的交互,避免重复地创建数据库连接。Mybatis 中的 BatchExecutor 就是这个思路,将相同的 sql 语句添加到同一个 Satement 对象中等待执行,可以有效地减少 PrepareStatement 地编译操作
Redis 的 Pipeline 也是将多个请求合并,最后一起发送,这样可以将多次网络交互优化成一次网络交互,减少网络交互的时间,从而提升性能。
拆分
拆分其实是针对多线程编程中,对共享资源的一个拆分,避免因为竞争激烈,导致多线程并发执行性能反而比单线程还慢了
代码中如果使用到了锁,可以从两方面考虑
减少锁的持有时间:将不必要的操作尽可能地放到锁外面去执行,避免其他线程等待锁的释放时间过长
减少锁的粒度:参考JUC下并发类的设计
ConcurrentHashMap是一个线程安全的Map,虽然可以直接通过synchronized修饰 put 和 get 方法来得到一个线程安全的HashMap,但是这样显然十分影响性能。
在JDK 1.7中,ConcurrentHashMap采用了分段锁(Segment Lock)的机制来提高并发性能。这种设计将整个哈希表分割成多个段(Segment),每个段都维护着自己独立的锁。这样,当多个线程并发访问ConcurrentHashMap时,它们可以并行地访问不同的段,从而减少了锁的竞争。
在JDK 1.8中,ConcurrentHashMap的锁机制发生了重大变化,它放弃了JDK 1.7中的分段锁设计,转而采用了一种基于CAS(Compare-And-Swap)操作+synchronized锁的细粒度锁机制。
除了ConcurrentHashMap,在 JUC 包下还有许多 Adder 类(IntegerAdder,LongAdder 等等),当线程竞争不激烈时,直接采用CAS来实现数量的原子递增,如果竞争激励,则使用数组来维护元素个数(将单个资源的竞争拆分成多个),先从数组中随机选择一个,再通过CAS实现原子递增,最后再一起汇总。
单例
单例其实也可以看作是缓存的一种实现方式,本质是避免重复创建对象,直接服用现有的对象,从而减少重复创建对象的时间,提升性能。
在 spring 框架下开发,依赖注入默认就是单例的
压缩
接口的响应时间除了接口本身执行业务逻辑的时间,还有网络传输的时间。在其他条件都不变的情况下,减少网络传输内容的大小,也可以提升接口的性能。
如果接口的返回数据字段很多,可以考虑压缩字段的大小,比如说将返回的json中的有实际意思的单词字段名直接改成简单的f1,f2,f3;这样在返回数据量大的情况下也可以减少网络传输的内容大小。
相关文章:
接口性能优化思路
前言 日常开发中设计接口,响应时间是衡量一个接口质量的重要指标。 接口响应时间这里粗糙地分为三种: 即时响应:毫秒级,小于500毫秒快速响应:秒级,大于500毫秒且小于2秒长时间操作:大于2秒&a…...
PyQt5 多线程编程详细教程
PyQt5 多线程编程详细教程 在 PyQt5 中,多线程编程是提高应用程序性能和响应性的重要手段。本教程将详细介绍如何在 PyQt5 中使用 QThread 进行多线程编程,学习如何避免界面冻结和线程安全问题,并通过丰富的案例来展示如何实现这些功能。 Q…...
uniapp小程序上传pdf文件
<template><view class"mainInnBox"><view class"formBox"><!-- 注意,如果需要兼容微信小程序,最好通过setRules方法设置rules规则 --><u-form :model"form" ref"uForm" :rules&quo…...
Python酷库之旅-第三方库Pandas(036)
目录 一、用法精讲 111、pandas.Series.item方法 111-1、语法 111-2、参数 111-3、功能 111-4、返回值 111-5、说明 111-6、用法 111-6-1、数据准备 111-6-2、代码示例 111-6-3、结果输出 112、pandas.Series.xs方法 112-1、语法 112-2、参数 112-3、功能 112-…...
Python爬虫(2) --爬取网页页面
文章目录 爬虫URL发送请求UA伪装requests 获取想要的数据打开网页 总结完整代码 爬虫 Python 爬虫是一种自动化工具,用于从互联网上抓取网页数据并提取有用的信息。Python 因其简洁的语法和丰富的库支持(如 requests、BeautifulSoup、Scrapy 等…...
【iOS】——探究isKindOfClass和isMemberOfClass底层实现
isKindOfClass 判断该对象是否为传入的类或其子类的实例 // 类方法实现,用于检查一个类是否属于另一个类或其父类链上的任何类。(BOOL)isKindOfClass:(Class)cls {// 从当前类开始,tcls将沿着元类的继承链向上遍历。for (Class tcls self->ISA(); …...
Python 热门面试题(七)
Python中如何拷贝对象?浅拷贝和深拷贝的区别是什么? 在Python中,拷贝对象是一个常见的需求,尤其是当你需要修改一个对象但又不想影响原始对象时。Python提供了几种拷贝对象的方法,其中最重要的是浅拷贝(sh…...
STM32项目分享:智能宠物喂食系统
目录 一、前言 二、项目简介 1.功能详解 2.主要器件 三、原理图设计 四、PCB硬件设计 1.PCB图 五、程序设计 六、实验效果 七、资料内容 项目分享 一、前言 项目成品图片: 哔哩哔哩视频链接: https://www.bilibili.com/video/BV1zy411z7…...
数据结构——栈的实现(java实现)与相应的oj题
文章目录 一 栈栈的概念:栈的实现:栈的数组实现默认构造方法压栈获取栈元素的个数出栈获取栈顶元素判断当前栈是否为空 java提供的Stack类Stack实现的接口: LinkedList也可以当Stack使用虚拟机栈,栈帧,栈的三个概念 二 栈的一些算…...
linux修改时区为CST
目录 第一步: 第二步: 第三步: 第一步: 备份原来的时区信息 [rootlocalhost ~]# mv /etc/localtime localtime.bak 第二步: 通过软链接将亚洲/上海 的时区信息 指导时区信息 [rootlocalhost ~]# ln -s /usr/share…...
【Spring Security】初识Spring Security
今天晚上因为一个项目问题,而正式开始学习Spring Security。 这个问题是“APP端的操作员应仅可查看管理后台的项目负责人分配给自己的计划”。 一、Spring Security的核心组件: Spring Security的核心组件包括:SecurityContextHolder、Auth…...
配置单区域OSPF
目录 引言 一、搭建基础网络 1.1 配置网络拓扑图如下 1.2 IP地址表 二、测试每个网段都能单独连通 2.1 PC0 ping通Router1所有接口 2.2 PC1 ping通Router1所有接口 2.3 PC2 ping通Router2所有接口 2.4 PC3 ping通Router2所有接口 2.5 PC4 ping通Router3所有接口 2.…...
SQL中的游标是什么?
在 SQL 中,游标(Cursor)是一种用于遍历结果集的数据库对象。它允许开发者在 SQL 查询的结果集中逐行或逐批处理数据。 具体来说,SQL 中的游标通常用于以下目的: 遍历结果集:当一个 SQL 查询返回多行结果时…...
7. LangChain4j如何使用统一api调用?
前言 当我们对接LangChain4j的时候,面对复杂的各种各样的大模型的api的对接,让很多开发者感到力不从心。在每个大模型的api都不一样的时候?该如何快捷的切换模型的使用呢? 这时,One-API应运而生,它以其简洁…...
RPM、YUM 安装 xtrabackup 8 (mysql 热备系列一)包含rpm安装 mysql 8 配置主从
RPM安装 percona-xtrabackup-80-8.0.35-30.1.el7.x86_64.rpm 官网: https://www.percona.com/ 下载地址: https://www.percona.com/downloads wget https://downloads.percona.com/downloads/percona-distribution-mysql-ps/percona-distribution-mysq…...
maven项目打成可运行的jar及pom中的依赖一同打包
maven项目打jar及pom中的依赖一同打包 最近开发中有个需求,不部署新的服务,只jar包执行 那maven项目中,代码如何以jar的方式运行、如何把代码打成jar、pom中的依赖如何与代码一同打到jar包中? 1、代码如何以jar的方式运行&…...
Gettler‘s Screep World 笔记 Ⅰ
夏促时候刚刚入坑,写个笔记叭~ 环境配置 参考 HoPGoldy 大佬的简书,先配置下开发环境 萌新去看大佬的详细教程,我这里比较简单,有前端基础的可以直接抄 VSCode 跳过 node 我配的是v18.18.2 换源 npm config set registry h…...
联合体(union)的定义以及如何与结构体(struct)不同
联合体(Union)是一种特殊的数据类型,它允许在相同的内存位置存储不同的数据类型。但是,在任何给定的时间点,联合体只能存储其中的一个值;这意味着联合体的大小是其最大成员的大小,因为它必须足够…...
【Spark官方文档部分翻译】RDD编程指南(RDD Programming Guide)
写在前面 内容如何选择 本翻译只翻译本人认为精华的部分,本人认为的Spark的一些核心理念,编程思想。一些特别基础的操作包括但不限于搭建环境就不在此赘述了。 配套版本 本系列基于Spark 3.3.1,Scala 2.12.10,进行翻译总结 原…...
前端八股文 $set
为什么会有$set vue2中对数组中新增的属性是监听不到的 如图 vue 插件中有但是 视图中没有刷新 解决方法 解决就是 $set() 就是在数组中新增属性的时候可以重新渲染视图 具体的写法 写法 就是 第一个 是在那个对象上新增 第二个参数 是新增的属性 第三个参数是 新增的属性…...
Connecting weaviate with langflow across docker containers
题意:在Docker容器之间连接Weaviate与Langflow 问题背景: I am trying to build a local RAG application using Langflow. For my vectore store, I want to use a local Weaviate instance, hosted in a separate docker container on the same netwo…...
【linux vim使用说明】
基本概念 提示:本文是网络资源整理 模式: vim 有多种模式,每种模式都有不同的功能。 普通模式 (Normal Mode): 默认模式,用于导航和执行命令。插入模式 (Insert Mode): 用于文本输入。可以通过按 i 进入。可视模式 (Visual Mode): 用于选择…...
cocos2d-x安装和项目
首先多方查找资料发现教程很简洁,发现对自己的操作方面没多大帮助,后来干脆去官网,好像也很简洁。基于这样一个原因,加上我首次碰cocos2d-x,决定记录一下整个流程,解决实际操作上的疑惑。 涉及的方面&…...
因果推断 | 双重机器学习(DML)算法原理和实例应用
文章目录 1 引言2 DML算法原理2.1 问题阐述2.2 DML算法 3 DML代码实现3.1 策略变量为0/1变量3.2 策略变量为连续变量 4 总结5 相关阅读 1 引言 小伙伴们,好久不见呀。 距离上次更新已经过去了一个半月,上次发文章时还信誓旦旦地表达自己后续目标是3周更…...
Flutter 开源库学习
网上看了好多歌词实现逻辑相关资料,封装比较的好的 就 flutter_lyric,核心类是LyricsReader,而且如果实现逐字逐句歌词编辑功能还需要自己实现很多细节 ,网友原话是 :歌词的功能真的是不少,写起来也是挺难的…...
自主巡航,目标射击
中国机器人及人工智能大赛 参赛经验: 自主巡航赛道 【机器人和人工智能——自主巡航赛项】动手实践篇-CSDN博客 主要逻辑代码 #!/usr/bin/env python #coding: utf-8import rospy from geometry_msgs.msg import Point import threading import actionlib impor…...
MySQL中EXPLAIN关键字详解
昨天领导突然问到,MySQL中explain获取到的type字段中index和ref的区别是什么。 这两种状态都是在使用索引后产生的,但具体区别却了解不多,只知道ref相比于index效率更高。 因此,本文较为详细地记录了MySQL性能中返回字段的含义、状…...
如何理解ref toRef和toRefs
是什么 ref 生成值类型的响应式数据可用于模板和reactive通过.value修改值 ref也可以像vue2中的ref那样使用 toRef 针对一个响应式对象(reactive)的prop创建一个ref两者保持引用关系 toRefs 将响应式对象(reactive封装)转换…...
【linux】kernel-trace
文章目录 linux kernel trace配置trace内核配置trace接口使用通用配置Events配置Function配置Function graph配置Stack trace设置 跟踪器tracer功能描述 使用示例1.irqsoff2.preemptoff3.preemptirqsoff linux kernel trace 配置 源码路径: kernel/trace trace内…...
【Golang 面试基础题】每日 5 题(一)
✍个人博客:Pandaconda-CSDN博客 📣专栏地址:http://t.csdnimg.cn/UWz06 📚专栏简介:在这个专栏中,我将会分享 Golang 面试中常见的面试题给大家~ ❤️如果有收获的话,欢迎点赞👍收藏…...
站长工具视频/百度推广400客服电话
苹果系统设置matplotlib 和 seaborn画图中文显示问题 添加 import matplotlib.pyplot as plt plt.rcParams[font.family] [Arial Unicode MS] 即可...
wordpress 插件大全/企业文化设计
windows环境下MySQL重启的命令行说明 windowsR 弹出运行框 在运行框中输入cmd 回车 进入系统的dos窗口 .启动mysql:输入 net start mysql; .停止mysql:输入 net stop mysql; windows下不能直接重启(restart),只能先停止,再启…...
yy怎么一直在模板相关信息圆柱钢模板优势是什么?企业网站建设模板和定制化有什么区别呢?拼命加载中/徐州网站设计
hi 给自己放了大概三天的假,没有一点点防备,没有一点点准备,无意的 是不是贤者时间过不去了我不知道啊。。。继续看东西吧 1、MySQL -----运算符和函数----- 字符函数,数值运算符,比较运算等 ----字符函数 --- CONCAT(…...
电子商务网站管理系统完美版/网站外链平台
1、获取体素在全局坐标系下的坐标(x,y,z),根据ICP配准得到的变换矩阵,将体素的坐标从全局坐标系转换到相机坐标系; 2、根据相机的内参矩阵,转换到图像坐标系,得到体素所在的图像坐标(u,v&#x…...
注册域名之后如何做网站/seo优化一般包括哪些
目录第80题 编写程序:分解质因数(10分)🍋题目描述🍋源代码第80题 编写程序:分解质因数(10分) 🍋题目描述 求出区间[a,b]中所有整数的质因数分解。 输入格式 输入两个整数a,b。 输出格式 每行输出…...
英文书 影印版 网站开发/站长工具seo查询软件
在idea使用htmlcss 简单仿制QQ会员官网主页页面 附带登录页面 跳转登陆页面 导航栏设置固定 底部信息栏附加根据鼠标在页面滑动的距离设置自动隐藏和显示 登录页面在点击登录后,实现覆盖整个页面,保持固定在页面中央位置,背景半透明化 …...