之前工作中,遇到一个504
超时问题。原因是因为接口耗时过长,超过nginx
配置的10
秒。然后 真枪实弹搞了一次接口性能优化,最后接口从11.3s
降为170ms
。本文将跟小伙伴们分享接口优化的一些通用方案。
1. 批量思想:批量操作数据库
优化前:
//for循环单笔入库
for(TransDetail detail:transDetailList){
insert(detail);
}
优化后:
batchInsert(transDetailList);
打个比喻:
打个比喻:假如你需要搬一万块砖到楼顶,你有一个电梯,电梯一次可以放适量的砖(最多放
500
), 你可以选择一次运送一块砖,也可以一次运送500
,你觉得哪种方式更方便,时间消耗更少?
2. 异步思想:耗时操作,考虑放到异步执行
耗时操作,考虑用 异步处理 ,这样可以降低接口耗时。
假设一个转账接口,匹配联行号,是同步执行的, 但是它的操作耗时有点长 ,优化前的流程:
为了降低接口耗时,更快返回,你可以把匹配联行号移到 异步处理 ,优化后:
- 除了转账这个例子,日常工作中还有很多这种例子。比如: 用户注册成功后,短信邮件通知,也是可以异步处理的 ~
- 至于异步的实现方式, 你可以用线程池,也可以用消息队列实现 。
3. 空间换时间思想:恰当使用缓存。
在适当的业务场景,恰当地使用缓存,是可以大大提高接口性能的。缓存其实就是一种 空间换时间的思想 ,就是你把要查的数据,提前放好到缓存里面,需要时, 直接查缓存,而避免去查数据库或者计算的过程 。
这里的缓存包括:Redis
缓存,JVM
本地缓存,memcached
,或者Map
等等。我举个我工作中,一次使用缓存优化的设计吧,比较简单,但是思路很有借鉴的意义。
那是一次转账接口的优化, 老代码 ,每次转账,都会根据客户账号,查询数据库,计算匹配联行号。
因为每次 都查数据库,都计算匹配,比较耗时 ,所以 使用缓存 ,优化后流程如下:
4. 预取思想:提前初始化到缓存
预取思想很容易理解,就是 提前把要计算查询的数据,初始化到缓存 。如果你在未来某个时间需要用到某个经过复杂计算的数据, 才实时去计算的话,可能耗时比较大 。这时候,我们可以采取预取思想, 提前把将来可能需要的数据计算好,放到缓存中 ,等需要的时候,去缓存取就行。这将大幅度提高接口性能。
我记得以前在第一个公司做视频直播的时候,看到我们的直播列表就是用到 这种优化方案 。就是启动个任务, 提前把直播用户、积分等相关信息,初始化到缓存 。
5. 池化思想:预分配与循环使用
大家应该都记得, 我们为什么需要使用线程池 ?
线程池可以帮我们管理线程,避免增加创建线程和销毁线程的资源损耗。
如果你每次需要用到线程,都去创建,就会有增加一定的耗时,而线程池可以重复利用线程,避免不必要的耗时。 池化技术不仅仅指线程池,很多场景都有池化思想的体现,它的本质就是 预分配与循环使用 。
比如TCP
三次握手,大家都很熟悉吧,它为了减少性能损耗,引入了Keep-Alive长连接
,避免频繁的创建和销毁连接。当然,类似的例子还有很多,如数据库连接池、HttpClient
连接池。
我们写代码的过程中, 学会池化思想 ,最直接相关的就是使用线程池而不是去new
一个线程。
-
接口优化
+关注
关注
0文章
4浏览量
1349
发布评论请先 登录
相关推荐
评论