接口优化计划总结:
1. 批处理
批量思维: 批量操作数据库, 在循环插入场景的接口中, 能够在批处理执行实现后一次性插入或更新数据库, 防止屡次 IO.// 批量入库
batchInsert();
mybatis <foreach> 进行批处理 `
2. 异步解决
异步思维: 针对耗时比拟长且不是后果必须的逻辑, 能够思考放到异步执行, 这样能升高接口耗时.
留神: 异步不能实时获取后果, 异步过程中报错无奈晓得
例如一个理财的申购接口,入账和写入申购文件是同步执行的,因为是 T + 1 交易,前面这两个逻辑其实不是后果必须的,咱们并不需要关注它的实时后果,所以咱们思考把入账和写入申购文件改为异步解决。如图所示:
实现形式: 能够应用线程池, 音讯队列, 还能够应用一些调度工作框架
我的项目案例: 异步导出大数量报表数据
3. 空间换工夫
一个很好了解的空间换工夫的例子是正当应用缓存,针对一些频繁应用且不频繁变更的数据,能够提前缓存起来,须要时间接查缓存,防止频繁地查询数据库或者反复计算。须要留神的事,这里用了正当二字,因为空间换工夫也是一把双刃剑,须要综合思考你的应用场景,毕竟缓存带来的数据一致性问题也挺令人头疼。这里的缓存能够是 R2M,也能够是本地缓存、memcached,或者 Map。举一个股票工具的查问例子:
因为策略轮动的调仓信息,每周只更新一次,所以原来的调接口就去查库的逻辑并不合理,而且拿到调仓信息后,须要通过简单计算,最终得出回测收益和跑赢沪深指数这些咱们想要的后果。如果咱们把查库操作和计算结果放入缓存,能够节俭很多的执行工夫。
如图:
4. 预处理
也就是预取思维,就是提前要把查问的数据,提前计算好,放入缓存或者表中的某个字段,用的时候会大幅提高接口性能。跟下面那个例子很像,然而关注点不同。举个简略的例子:理财产品,会有依据净值计算年化收益率的数据展现需要,利用净值去套用年化收益率计算公式计算的逻辑咱们能够采纳预处理,这样每一次接口调用间接取对应字段就能够了。
留神: 3,4 用于条件少且不常常变动的 例如: 大盘
5. 池化思维
咱们都用过数据库连接池,线程池等,这就是池思维的体现,它们解决的问题就是防止反复创建对象或创立连贯,能够反复利用,防止不必要的损耗,毕竟创立销毁也会占用工夫。池化思维蕴含但并不局限于以上两种,总的来说池化思维的实质是预调配与循环应用,明确这个原理后,咱们即便是在做一些业务场景的需要时,也能够利用起来。
比方:对象池
6. 串行改并行
串行就是,以后执行逻辑必须等上一个执行逻辑完结之后才执行,并行就是两个执行逻辑互不烦扰,所以并行相对来说就比拟节省时间,当然是建设在没有后果参数依赖的前提下。比方,理财的持仓信息展现接口,咱们既须要查问用户的账户信息,也须要查问商品信息和 banner 位信息等等来渲染持仓页,如果是串行,基本上接口耗时就是累加的。如果是并行,接口耗时将大大降低。如图:
我的项目案例: 并行获取 销售报表, 应收款, 指标数据
7. 索引
加索引能大大提高数据查问效率,这个在接口设计之出也会思考到,这里不再多赘述,随着需要的迭代,咱们重点整顿一下索引不失效的一些场景,心愿对小伙伴们有所帮忙。
具体不失效场景不再一一举例,前面有工夫的话,独自整顿一下。
8. 防止大事务
所谓大事务问题,就是运行工夫较长的事务,因为事务统一不提交,会导致数据库连贯被占用,影响到别的申请拜访数据库,影响别的接口性能。举个例子:
@Transactional(value = "taskTransactionManager", propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED, rollbackFor = {RuntimeException.class, Exception.class})
public BasicResult purchaseRequest(PurchaseRecord record) {BasicResult result = new BasicResult();
...
pushRpc.doPush(record);
result.setInfo(ResultInfoEnum.SUCCESS);
return result;
}
所以为防止大事务问题,咱们能够通过以下计划躲避:
1,RPC 调用不放到事务外面
2,查问操作尽量放到事务之外
3,事务中防止解决太多数据
9. 优化程序结构
程序结构问题个别呈现在屡次需要迭代后,代码叠加造成。会造成一些反复查问、屡次创建对象等耗时问题。在多人保护一个我的项目时比拟多见。解决起来也比较简单,咱们须要针对接口整体做重构,评估每个代码块的作用和用处,调整执行程序。
10. 深分页问题
(深分页: 深分页就是对于试用 limit m,n 这种来实现分页查问的时候,须要将满足条件的 m n 条数据都查问进去,而后进行排序,而后再取第(m-1) n 到第 m * n 这 n 条数据。当 m 十分大的时候,那么须要参加排序的数据就会十分多,导致查问后果会十分慢。) 深分页问题比拟常见,分页咱们个别最先想到的就是 limit,为什么会慢,咱们能够看下这个 SQL:
select * from purchase_record where productCode = 'PA9044' and status=4 and id > 100000 limit 200
11.SQL 优化
sql 优化能大幅提高接口的查问性能,因为本文重点讲述接口优化的计划,具体 sql 优化不再一一列举,小伙伴们能够联合索引、分页、等关注点思考优化计划。
12. 锁粒度防止过粗
锁个别是为了在高并发场景下爱护共享资源采纳的一种伎俩,然而如果锁的粒度太粗,会很影响接口性能。对于锁粒度:就是你要锁的范畴有多大,不论是 synchronized 还是 redis 分布式锁,只须要在临界资源处加锁即可,不波及共享资源的,不必要加锁,就好比你要上卫生间,只须要把卫生间的门锁上就能够,不须要把客厅的门也锁上。
谬误的加锁形式:
正确加锁形式: 订单号的生成, 分布式锁