一、背景
针对老项目,去年做了许多降本增效的事情,其中发现最多的就是接口耗时过长的问题,就集中搞了一次接口性能优化。本文将给小伙伴们分享一下接口优化的通用方案。
二、接口优化方案总结
1.批处理
批量思想:批量操作数据库,这个很好理解,我们在循环插入场景的接口中,可以在批处理执行完成后一次性插入或更新数据库,避免多次IO。
//for循环单笔入库 list.stream().forEatch(msg->{ insert(); });
//批量入库 batchInsert();
2.异步处理
3.空间换时间
一个很好理解的空间换时间的例子是合理使用缓存,针对一些频繁使用且不频繁变更的数据,可以提前缓存起来,需要时直接查缓存,避免频繁地查询数据库或者重复计算。
4.预处理
也就是预取思想,就是提前要把查询的数据,提前计算好,放入缓存或者表中的某个字段,用的时候会大幅提高接口性能。跟上面那个例子很像,但是关注点不同。
举个简单的例子:理财产品,会有根据净值计算年化收益率的数据展示需求,利用净值去套用年化收益率计算公式计算的逻辑我们可以采用预处理,这样每一次接口调用直接取对应字段就可以了。
5.池化思想
池化思想包含但并不局限于以上两种,总的来说池化思想的本质是预分配与循环使用,明白这个原理后,我们即使是在做一些业务场景的需求时,也可以利用起来。
6.串行改并行
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(); //插入账户任务 taskMapper.insert(ManagerParamUtil.buildTask(record, TaskEnum.Task_type.pension_account.type(), TaskEnum.Account_bizType.purchase_request.type())); //插入同步任务 taskMapper.insert(ManagerParamUtil.buildTask(record, TaskEnum.Task_type.pension_sync.type(), TaskEnum.Sync_bizType.purchase.type())); //插入影像件上传任务 taskMapper.insert(ManagerParamUtil.buildTask(record, TaskEnum.Task_type.pension_sync.type(), TaskEnum.Sync_bizType.cert.type())); result.setInfo(ResultInfoEnum.SUCCESS); return result; }
@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; }
所以为避免大事务问题,我们可以通过以下方案规避:
9.优化程序结构
10.深分页问题
深分页问题比较常见,分页我们一般最先想到的就是 limit ,为什么会慢,我们可以看下这个SQL:
select * from purchase_record where productCode = 'PA9044' and status=4 order by orderTime desc limit 100000,200
select * FROM purchase_record where id > 100000 limit 10;
11.SQL优化
12.锁粒度避免过粗
错误的加锁方式:
//非共享资源 private void notShare(){ } //共享资源 private void share(){ } private int wrong(){ synchronized (this) { share(); notShare(); } }
正确的加锁方式:
//非共享资源 private void notShare(){ } //共享资源 private void share(){ } private int right(){ notShare(); synchronized (this) { share(); } }
三、性能接口问题形成的原因思考
我相信很多接口的效率问题不是一朝一夕形成的,在需求迭代的过程中,为了需求快速上线,采取直接累加代码的方式去实现功能,这样会造成以上这些接口性能问题。
本文仅供学习!所有权归属原作者。侵删!文章来源: 京东云开发者
文章评论