IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 记一次接口优化经历 -> 正文阅读

[Java知识库]记一次接口优化经历

目录

1.接口优化维度

1.1 接口响应时间

1.1.1 缓存相关优化

1.1.2?SQL相关优化

1.1.3 数据存储位置相关优化

1.1.4 数据库服务相关配置

1.1.5 数据查询次数相关优化????????

1.1.6?非核心流程/耗时操作改异步

1.1.7?提高日志输出级别

1.2 内存占用率

1.2.1?检查是否接口内发生GC

1.3 代码上的一些小技巧(后续持续补充)

2.记录一次真实的调优经历


????????前言:最近接了一个导出接口的优化需求,原9000+数据导出秒数660+,优化后5S,特此记录一下优化方案以供大家一起讨论学习。本文先通篇列举一下优化的方案,再详细的阐述这次优化的具体细节。

1.接口优化维度

? ? ? ? 个人感觉接口优化分为两个维度,分为接口响应时间(使接口更快的返回数据)和内存占用率(减少接口内存消耗)。

? ?1.1 接口响应时间

? ? ? ? 这类接口需要优化的原因通常是因为该接口响应时间超过了nginx/网关/feign所配置的超时时间限制。那么我们可以考虑从以下几个方面尝试优化:

? ? ? ?1.1.1 缓存相关优化

? ? ? ? 加缓存的数据分为两种冷数据(很长一段周期不会改变的数据,比如某个月的报表数据/某些车辆的车型数据等)和热点数据(某些查询非常频繁但一旦生成几乎不会改变的数据,比如推出一个卖车活动/或者某些进入抢单池的订单等)。

? ? ? ? 针对于冷数据可以采取缓存预热的方式,在服务启动的时候提前将相关的缓存数据直接加载到缓存系统。避免用户在请求的时候,先查询数据库,再刷新缓存。缓存预热不需非得用NoSql的数据库,实在没有单表数据量不大的话上个HashMap也行。

? ? ? ? 热点数据的话比较麻烦,需要一套完善的热点发现机制和更新机制,这里就不展开说明了,感兴趣的同学可以自己查一查(其实自己也不咋精。。。)

? ? ? ?1.1.2?SQL相关优化

? ? ? ? 建立索引:经常查询的字段建立索引,提高查询速度

????????优化SQL结构:查看哪些sql理论上该走索引实际没走的,修一修

????????避免返回不必要的数据:别为了省事select *

????????谨慎使用limit offset,用滚动查询代替:mysql?limit offset分页方法当offset值过大时会有严重的效率问题,可以采用 循环+下面的SQL:

SELECT * FROM tableX WHERE id > #{lastBatchMaxId} ORDER BY id [ASC|DESC]LIMIT ${size}

????????通过不断传入?lastBatchMaxId来进行分段查询最后组装数据。(阿里开发规范第五章3.7)

? ? ? ?1.1.3 数据存储位置相关优化

????????分库分表:按照某一业务维度进行拆分,减少单表数据量,提高查询速度

????????中间表/冗余字段:这两种方法思路相同,都是在查询前尽量把数据维持在一个统一的地方,减少为了获取数据而查询其他表的次数

????????搜素引擎:类似中间表方案,区别为将数据统一存放在搜索引擎中,同时搜索引擎支持粒度更细的查询

? ? ? ?1.1.4 数据库服务相关配置

????????读写分离:分离读写任务,提高数据库服务性能上限

????????优化MySql conf文件配置:修改最大连接数、buffer缓冲区大小等(建议专业DBA来搞)

? ? ? ?1.1.5 数据查询次数相关优化????????

????????单次换批量:切记循环查库/调用其他服务,能用批量就用批量,大量磁盘IO/HTTP调用会耗费大量资源

? ? ? ?1.1.6?非核心流程/耗时操作改异步

????????一些消息通知,邮件或短信等,这些业务不是主流业务,即使出错也不会影响主流业务的进行,因此把这部分业务采用异步的方式去调用。

? ? ? ? 注:慎用异步方法,使用不当极容易造成线程阻塞导致服务宕机。

? ? ? ?1.1.7?提高日志输出级别

????????减少非必要日志的打印:日志打印过多会影响服务性能(这条笔者没有实践考证过,部门大佬这么说)

? ?1.2 内存占用率

? ? ? ? 这类接口需要优化的原因通常是因为调用单次接口的时候出现了频繁GC导致服务挂掉,常见于大数据导出/报表分析接口

? ? ? ?1.2.1?检查是否接口内发生GC

????????笔者遇到过一次是因为数据导出的时候采用一次性把目标数据全部查询出来再写到流中的方式,大量被查询的对象驻留在堆内存中,直接打满了堆内存。解决方案:分批次查询DB,再把结果分批次输入到OutputStream中。

? ?1.3 代码上的一些小技巧(后续持续补充)

? ? ? ? 仅获取集合中的某个实体对象,考虑用map来代替for循环遍历list:

反例:

List<User> userList = new ArrayList<User>();
for(User user : userList){
    if(userId.equals(user.getUserId)){
        XXX
    }
}

推荐方案:

Map<Long, User> userMap = leads.stream().filter(Objects::nonNull).
collect(Collectors.groupingBy(User::getUserId));
User user = userMap.get(userId);

????????如果数据量大HashMap初始容量开大一点:HashMap频繁扩容耗费资源

????????采用内存组装数据来代替数据库的连表查询:内存比磁盘IO快

????????list去重可以先转linkedHashSet再转回来,也可以直接使用Lamda:

linkedHashSet:

List<Integer> list = new ArrayList<>(Arrays.asList(1, 1, 2, 3));
LinkedHashSet<Integer> temporarySet = new LinkedHashSet<>(list);
ArrayList<Integer> noDuplicateList = new ArrayList<>(temporarySet);

Lamda:

List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 3));
List<Integer> noDuplicateList = list.stream().distinct().collect(Collectors.toList());

2.记录一次真实的调优经历

? ? ? ? 首先拿来接口一看,导出需求在技术实现上为异步,可能是为了前端用户体验(在大数量的情况下不会一直转圈)。打开zipkin想看一下耗时(如果没有可以加计时的日志),发现大量调用某服务的情况(这里猜测循环调用某服务),9000+数据跑了660+S。跟踪日志发现有一个组装数据的方法非常耗时,点进去发现首先查了es,然后发现了下面这行代码:

????????循环调用服务是大忌,9000条数据9000次http网络请求,果断改成批量。再往下看:

?????????发现一段很可疑的代码,看起来像是为了避免单次接口超时而分批次调用了该接口,跟进这个服务的这个接口:

????????好家伙,循环查库+调用其他服务,这不慢谁慢。优化思路:for循环干掉,单次换批量;数据库查询改业务层组装数据;HashMap初始化开大点

????????首先三个批量查询,把所有该查的数据都查完(前提是单次查询不能超时),然后用Lamda组装数据

????????再次测试该接口,9000+数据接口耗时5S。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-10-26 12:05:05  更:2021-10-26 12:07:08 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 23:47:22-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码