接口性能优化
一、耗时统计
在做接口的性能优化时,最重要的是知道时间消耗在哪里。
可以用StopWatch,进行耗时统计。
详情见: https://www.cnblogs.com/expiator/p/17045089.html
二、链路追踪
如果团队使用了Skywalking,可以用来进行链路追踪,耗时统计。
时间主要消耗在哪些服务,哪些方法,通过traceid一看便知。
Skywalking非常有用,哪怕项目里没有,也可以积极推进并接入Skywalking。
三、性能监控
如果团队里面有用到一些性能监控的工具,比如Grafana、Prometheus。
可以多看下接口的请求数、响应时间、服务器的CPU、GcCount等。
四、线程池
多线程、异步
如果多个任务之间不存在先后关系,没有强依赖,可以使用线程池做多线程、异步。
如果接口中存在多个任务,可以考虑使用多线程。
如果接口中有某个任务比较耗时,可以考虑使用异步。
CompletableFuture类能够开多线程处理多个任务,还能处理异步回调。
还能将多个任务合并成一个,设置阻塞时间。非常实用。
详情见:https://www.cnblogs.com/expiator/p/17056690.html
线程池调优
详情见:https://www.cnblogs.com/expiator/p/17087726.html
五、MQ
MQ的使用场景: 异步,解耦,削峰。
如果存在耗时的任务或功能,对性能的要求比较高,可以使用MQ做异步。
线程池也可以异步处理,但如果系统挂了,线程池也会失效,MQ则不会。MQ做异步,还有重试机制。
六、数据库
数据表加索引
数据库最常见的优化,就是加索引。
索引能够极大地提升数据表查询的速度。
常用的区分度高的字段,可以尝试加索引。
如果经常查询的有多个字段,可以考虑查询条件是否符合最左匹配原则,符合的话用复合索引。
批量处理--数据表
接口代码在做批量处理时,一定要注意,不要在for循环中调用数据库/缓存,不仅性能极差,还有连接数耗尽的可能。
数据表的批量处理,详情见:https://www.cnblogs.com/expiator/p/14417061.html
Explain
接口中的sql比较慢时,可以用 Explain查看执行计划,做性能优化。
详情见: https://segmentfault.com/a/1190000008131735
分库分表
数据表的数据量大,可以分库分表。
七、缓存
加缓存
Redis缓存的处理速度,远远快于数据库/网络这些IO。在做性能优化时,如果数据库/网络太慢,经常会用到Redis缓存。
加缓存有几点要注意:
1.如果在查询时使用了缓存,那么在更新(删除、插入)之后,必须处理缓存(一般是更新DB后删除缓存),让数据最终一致。
2.实时数据,频繁更新的数据,最好不要加缓存。
3.如果不是频繁更新的数据,又没法在数据变更时处理缓存,比如调用其他系统的接口,可以尝试加较短时间的缓存,比如1分钟。
批量处理--缓存
Redis的execute(),可以在一次连接中处理多个命令。
Redis的execute(),详情见:https://www.cnblogs.com/expiator/p/17085454.html
Pipeline (管道) 可以一次性发送多条命令并在执行完后一次性将结果返回。
Redis的管理操作,详情见: https://www.cnblogs.com/expiator/p/17073834.html
数据预热
使用定时任务,定时去查询数据,或者是通过前置过滤器提前预热。
查询之后数据进入缓存,那么用户再去查时速度就会快很多。
八、服务器
服务器的状态
服务器是否正常启动。
在调用接口时,服务器的CPU、GcCount是否正常。
服务器的个数
服务器肯定是越多越好。
服务器的个数有多少,能否加机器。
九、优化服务链路
如果接口的服务链路比较复杂,可以试着优化服务链路。
比如A服务中分别调用了B,C,D服务,那可以试着将BCD服务的内容合并到一个服务中,只做一次调用。
比如服务链路为 A->B->C->D,可以试着缩短服务链路,由 A->D,这样消耗的时间也会变短。
十、去掉冗余逻辑
如果接口复用了项目中其他的方法/代码,可以看是否有冗余的逻辑,如果有冗余的,考虑能否抽取可用逻辑,去掉冗余的逻辑。