性能优化 - 案例篇:11种优化接口性能的通用方案

文章目录

    • Pre
    • 1. 加索引:最低成本,最大收益
      • 常见问题:
      • 工具命令:
      • 建议:
    • 2. SQL 优化:比加索引再进阶一步
      • 常见 5 类问题:
      • 实用建议:
    • 3. 远程调用:从串行改并行,性能翻倍不止
      • 场景复现:
      • 优化:并行调用
      • 建议:
    • 4. 数据异构:跨服务请求太慢?同步一份!
      • 缺点:
    • 5. 避免重复调用
      • 案例 1:循环查数据库
        • 优化写法
      • 案例 2:死循环自旋
    • 6. 异步处理
      • 什么情况适合异步?
      • 推荐工具:
      • 注意:
    • 7. 锁粒度控制:避免全表级锁
      • 优化方式:
    • 8. 分页优化
      • 大偏移问题:
      • 推荐:
    • 9. 加缓存:请求再多,读缓存照样稳
      • 场景:
      • 推荐策略:
      • 注意:
    • 10. 分库分表
      • 适用场景:
      • 常见方案:
      • 注意:
    • 11. 辅助功能控制:接口不是万金油
    • 总结:性能优化是一门系统工程

在这里插入图片描述


Pre

性能优化 - 理论篇:常见指标及切入点

性能优化 - 理论篇:性能优化的七类技术手段

性能优化 - 理论篇:CPU、内存、I/O诊断手段

性能优化 - 工具篇:常用的性能测试工具

性能优化 - 工具篇:基准测试 JMH

性能优化 - 案例篇:缓冲区

性能优化 - 案例篇:缓存

性能优化 - 案例篇:数据一致性

性能优化 - 案例篇:池化对象_Commons Pool 2.0通用对象池框架

性能优化 - 案例篇:大对象的优化

性能优化 - 案例篇:使用设计模式优化性能

性能优化 - 案例篇:并行计算

性能优化 - 案例篇:多线程锁的优化

性能优化 - 案例篇:CAS、乐观锁、分布式锁和无锁

性能优化 - 案例篇: 详解 BIO NIO AIO

性能优化 - 案例篇: 19 条常见的 Java 代码优化法则

性能优化 - 案例篇:JVM垃圾回收器

性能优化 - 案例篇:JIT


性能优化不是一蹴而就的,它是一次“认知 + 实践”的双向奔赴。

你是不是也遇到过这样的场景:

  • 某核心接口,TPS(每秒事务数)一上来就拉垮;
  • 一个无害的查询,突然把数据库搞宕了;
  • 接口明明逻辑简单,但响应就是卡成 PPT。

接下来我将总结出的 11 条接口性能优化法则,其中不少优化点只需几行代码,就能把接口响应从 几秒 → 毫秒


1. 加索引:最低成本,最大收益

有没有用索引?用了索引有没有生效?MySQL 选对了索引吗?

这三个问题必须要会回答。

常见问题:

  • WHERE 条件没加索引;
  • ORDER BY 字段无索引或顺序不匹配;
  • 字段上存在函数、类型不一致导致索引失效;
  • 多个索引冲突,MySQL 选错了路径。

工具命令:

SHOW INDEX FROM `table_name`;
EXPLAIN SELECT * FROM `table_name` WHERE cloumn= 1;

建议:

  • 别忘了联合索引的最左前缀原则;
  • 必要时用 FORCE INDEX
  • 注意:添加、删除索引都要评估业务负载,避免高峰期操作。

2. SQL 优化:比加索引再进阶一步

索引优化完了,执行慢?那就看 SQL 本身。

常见 5 类问题:

  1. SELECT *(无脑全查)
  2. IN 太长或嵌套子查询
  3. 关联字段未加索引
  4. 过多 JOIN + 复杂嵌套
  5. 分页偏移过大(OFFSET)

实用建议:

  • 明确列名,不要 SELECT *
  • 拆子查询,用临时表换 IN;
  • 使用 LIMIT 时避免大偏移(“延迟分页”);
  • COUNT(*) 太大可用缓存兜底。

3. 远程调用:从串行改并行,性能翻倍不止

场景复现:

某接口需要:

  • 用户服务:昵称、头像、等级
  • 积分服务:积分
  • 成长值服务:成长值

如果这样写:

A → 用户服务(200ms)  
A → 积分服务(150ms)  
A → 成长值服务(180ms)  
总耗时:530ms

优化:并行调用

CompletableFuture.allOf(userFuture, bonusFuture, growthFuture
).join();

三路并发,总耗时 = 最长的一次,约 200ms。

建议:

  • 使用自定义线程池,避免高并发下线程爆炸;
  • 注意业务合并时机和异常兜底。

4. 数据异构:跨服务请求太慢?同步一份!

高并发接口建议使用缓存异构数据,减少远程依赖。

  • 用户信息 Redis 缓存结构:
{"userId": 123,"nickname": "Artisan","score": 87,"growth": 42
}
  • 更新策略:

    • 数据变更后同步更新 Redis;
    • 可选:异步 MQ 通知,或双写机制。

缺点:

  • 一致性需关注;
  • 数据过期和失效策略要设计清晰。

5. 避免重复调用

案例 1:循环查数据库

// 低效写法
for (User u : list) {userMapper.getUserById(u.getId());
}
优化写法
List<Long> ids = list.stream().map(User::getId).collect(toList());
userMapper.getUserByIds(ids);

减少 N 次 DB 请求 → 只要 1 次。

案例 2:死循环自旋

while (true) {if (flag) break;
}
  • 慎用!在并发条件不明的场景下容易让 CPU 打满;
  • 推荐用 LockSupport.park()CountDownLatch 等并发工具类。

6. 异步处理

什么情况适合异步?

  • 写操作完成后通知其他服务;
  • 接口响应不需要等待的操作。

推荐工具:

  • @Async
  • CompletableFuture
  • 消息队列(RocketMQ/Kafka)

注意:

  • 异步任务一定要兜底(失败重试、幂等保障);
  • 核心链路要保障同步结果,不建议异步。

7. 锁粒度控制:避免全表级锁

比如订单取消逻辑:

synchronized(lock) {cancelOrder();
}

这种是“粗粒度锁”。

优化方式:

  • 基于订单号加锁(细粒度)
  • Redis 分布式锁(Redisson)
  • 乐观锁:加版本号 version

8. 分页优化

分页是最常见的接口之一,但最容易踩坑。

大偏移问题:

SELECT * FROM order LIMIT 100000, 20;

扫描 10w 行,慢得要命!

推荐:

  • 延迟分页:记录上次最大 id
  • 游标分页:基于上次的主键分页
SELECT * FROM order WHERE id > lastId ORDER BY id LIMIT 20;

9. 加缓存:请求再多,读缓存照样稳

场景:

  • 热门xx详情
  • 用户画像、配置数据
  • 访问频率高但更新低的数据

推荐策略:

  • Redis String/Hash
  • 结合 Guava Cache 做本地一级缓存
  • 使用 CacheAside 模式:先查缓存 → 缓存失效再查库

注意:

  • 缓存过期 + 主动刷新;
  • 防止缓存雪崩/穿透/击穿(布隆过滤器 + 限流)。

10. 分库分表

适用场景:

  • 单表数据超千万;
  • 读写压力过大。

常见方案:

  • 垂直拆分:按业务分库
  • 水平拆分:按 ID 取模、按时间分表
  • 中间件:ShardingSphere、MyCat

注意:

  • JOIN 语句需要格外处理;
  • 跨分片分页/排序要小心。

11. 辅助功能控制:接口不是万金油

很多接口包含了不必要的逻辑,尤其是在企业后台管理系统中:

  • 复杂日志打印;
  • 权限、数据范围过滤;
  • 多租户、国际化处理;
  • 无用字段/参数传递。

建议:

  • 精简接口:核心功能优先返回;
  • 将辅助功能放到独立服务或中间件;
  • 用 AOP + 过滤器统一处理非业务逻辑。

总结:性能优化是一门系统工程

接口优化,不是追求“代码完美”,而是要用尽可能少的改动,达到可接受的性能表现

提到的这 11 点优化手段,从数据库 → 接口逻辑 → 缓存中间件 → 分布式架构全面覆盖,几乎涵盖了主流系统中所有性能问题的“对症下药”。

在这里插入图片描述

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

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

相关文章

Kafka - 并发消费拉取数据过少故障分析

文章目录 背景与问题描述原理与原因分析参数优化思路示例配置验证与监控实践注意事项与风险总结 背景与问题描述 场景描述 使用 Spring Boot Spring Kafka&#xff0c;注解 KafkaListener(topics..., id..., ...)&#xff0c;批量监听&#xff08;方法签名为 public void doHa…

开源 Arkts 鸿蒙应用 开发(二)封装库.har制作和应用

文章的目的为了记录使用Arkts 进行Harmony app 开发学习的经历。本职为嵌入式软件开发&#xff0c;公司安排开发app&#xff0c;临时学习&#xff0c;完成app的开发。开发流程和要点有些记忆模糊&#xff0c;赶紧记录&#xff0c;防止忘记。 相关链接&#xff1a; 开源 Arkts …

Qt基础相关

模态对话框和非模态对话框 在一个页面进行交互时弹出的一个新页面&#xff0c;新页面不堵塞旧页面的交互&#xff0c;这就是非模态对话框。 模态对话框 模态对话框就是当该对话框弹出后会阻塞其他窗口的响应事件&#xff0c;必须先关闭该对话框&#xff0c;其他窗口才会继续…

《汇编语言:基于X86处理器》第2章 x86处理器架构

本章重点是与 x86 汇编语言相关的底层硬件。有说法认为&#xff0c;汇编语言是直接与机器交流的理想软件工具。如果是真的&#xff0c;那么汇编程序员就必须非常熟悉处理器的内部结构与功能。本章将讨论指令执行时处理器内部发生的一些基本操作&#xff0c;以及操作系统如何加载…

最小生成树算法的解题思路与 C++ 算法应用

一、最小生成树算法针对问题类型及概述 先来简要陈述一下树的概念&#xff1a;一个由 N N N 个点和 N − 1 N-1 N−1 条边组成的无向连通图。由此&#xff0c;我们可以得知生成树算法的概念&#xff1a;在一个 N N N 个点的图中找出一个由 N − 1 N-1 N−1 条边组成的树。…

feign.FeignException$NotFound: [404 ] during [POST] to [http://ti/ti/v1/i/se

feign.FeignException$NotFound: [404 ] during [POST] to [http://ti/ti/v1/i/send 原因&#xff1a;多个地方注册 FeignClient(name “ti”, path “/ti/v1/i/send/repeat”) 解决&#xff1a;删除一个即可

Mac m1 通过docker镜像安装kafka

kafka依赖zookeeper&#xff0c;因此需要使用docker同时安装zookeeper和kafka。 macOS的docker在容器和宿主之间无法通过ip直接通信&#xff0c;因此在安装的时候需要特殊注意与ip相关的设置。当容器需要访问宿主ip时&#xff0c;需要使用docker.for.mac.host.internal或者host…

01初始uni-app+tabBar+首页

初始uni-apptabBar首页 1. uni-app1.1 新建uni-app项目1.2 目录结构1.3 把项目配置运行到微信开发者工具 2. tabBar3.1 首页3.1 配置网络请求3.2 轮播图区域3.3 分类导航区域3.4 楼层区域 1. uni-app ​ uni-app 是使用 Vue.js 开发前端应用的框架。开发者编写一套代码&#x…

微信小程序,微信授权手机号码

uniapp中index.vue: <template><view class"content"><button open-type"getPhoneNumber" getphonenumber"getPhoneNumber"type"primary">授权手机号登录 </button></view></template><scrip…

数据结构 学习 图 2025年6月14日 12点57分

搜索算法 深度优先搜索 一种用于遍历或搜索树或图的算法。它沿着树的深度遍历树的节点&#xff0c;尽可能深的搜索树的分支。 DFS核心思想 深度优先&#xff1a;尽可能深地搜索树的分支 回溯思想&#xff1a;当节点v的所在边都已被探寻过&#xff0c;搜索将回溯到发现节点v的…

H3C路由器使用PBR 实现两条互联网专线互为备份

实验拓扑 图 1-1 注&#xff1a;如无特别说明&#xff0c;描述中的 R1 或 SW1 对应拓扑中设备名称末尾数字为 1 的设备&#xff0c;R2 或 SW2 对应拓扑中设备名称末尾数字为 2 的设备&#xff0c;以此类推&#xff1b;另外&#xff0c;同一网段中&#xff0c;IP 地址的主机位为…

深化信创生态布局!聚铭网络与海量数据完成产品兼容性互认证

近日&#xff0c;聚铭网络成功与海量数据完成了一系列产品的兼容性互认证&#xff0c;并获得了由海量数据颁发的产品兼容互认证书。这一成就标志着双方在技术整合方面迈出了重要一步。 经过全面严格的测试&#xff0c;聚铭网络自主研发的安全系列产品&#xff0c;包括聚铭下一…

Unity AR+ 百度AI 实现 物体识别与对应英文翻译

一、前言 我目前实现了拍照保存到手机的功能 我想进一步优化&#xff0c;实现通过手机摄像头实时识别眼前的物体&#xff0c;显示对应的英文的功能。 1.项目技术栈&#xff1a;Unity 2022.3.53 Vuforia 11 百度物体识别API 百度翻译API 2.功能目标&#xff1a;使用手机摄像…

Vue.js第二节

计算属性、事件绑定、条件判断、遍历循环 计算属性&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0">…

从开源代码入场无人机学术研究到商业化市场的全路径指南-优雅草卓伊凡

从开源代码入场无人机学术研究到商业化市场的全路径指南-优雅草卓伊凡 引言&#xff1a;开源代码在无人机研究中的重要性 优雅草卓伊凡在这里告诉大家&#xff0c;如果真的要开始进入无人机领域&#xff0c;我们需要一步步开始研究。目前先去看看开源无人机代码是尤为重要的&…

window11中开启ubuntu22.04子系统

一、启用Windows子系统 打开控制面板 选择程序然后点击“启用或关闭Windows功能” 勾选如下2项&#xff0c;点击确定 二、安装内核升级包 打开链接https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi下载内核升级包&#xff0c;打开后安装、重启电脑…

80Qt窗口_对话框

目录 5. 对话框 5.1 对话框介绍 用例1&#xff1a; 用例2&#xff1a; 用例3&#xff1a; 用例4&#xff1a; 5.2 对话框的分类 5.2.1 模态对话框 5.2.2 ⾮模态对话框 5. 对话框 5.1 对话框介绍 对话框是 GUI 程序中不可或缺的组成部分。⼀些不适合在主窗⼝实现的功…

Pyenv 跟 Conda 还有 Poetry 有什么区别?各有什么不同?

pyenv、Conda 和 Poetry 是 Python 生态中常用的工具&#xff0c;但它们的核心功能和用途不同&#xff0c;通常可以结合使用。以下是它们的区别和特点&#xff1a; 1. pyenv 用途&#xff1a;管理多个 Python 解释器版本。 核心功能&#xff1a; 安装不同版本的 Python&#x…

数学符号和标识中英文列表(含义与示例)

数学符号和标识的参考&#xff0c;涵盖了数学的各个主要分支&#xff0c;并提供清晰的定义和示例&#xff0c;方便快速查找和学习收藏。 目录 基础数学符号几何符号代数符号线性代数符号概率与统计符号集合论符号逻辑符号微积分与分析符号数字与字母符号 特点 中英对照&…

「Java流程控制」switch结构

知识点解析 1.switch结构的核心概念 switch语句是一种多分支选择结构,它根据表达式的值来选择执行不同的代码块。与if-else结构相比,switch更适合处理离散的、有限个值的比较。 2.switch结构的基本语法 switch (表达式) {case 值1:// 代码块1[break;]case 值2:// 代码块…