提升接口的tps

一、DB优化

  • SQL查询走索引
  • 拆分复杂SQL
  • 读写分离

二、业务优化

  • Log4j2异步
  • 缓存(Redis)
  • 业务异步处理
  • 循环内不要操作数据库、缓存
  • sleep绝对不允许
  • 批量获取数据
  • 用空间换时间

 

下面逐步拆分每种情况的优化分案:

1、所有的SQL查询尽量走索引,不要全表扫描。把SQL都放到数据库中看一下执行计划。比如,使用mysql可以把每条SQL前加上explain,看一下执行计划

2、不要写负责的SQL,不要将业务逻辑抛给数据库去处理,应在程序中处理这些业务逻辑,数据库只是用来取基础数据,尽可能的单表查询走索引,拿到数据之后根据业务需求在程序中处理

3、数据库要读写分离

4、尽可能的去掉无用日志,代码写的规范不用过多的日志,看代码就知道业务逻辑。日志打印使用异步的方式,生产环境关闭debug日志。

5、循环内部不要有数据库、缓存操作,把这些操作都移到循环外,通过批量的方式一次性获取数据,然后在程序中对这些数据进行处理,转换成想要的格式。比如,

①. 不要在for循环内执行 orderInfo.getById(id),而是在循环外执行 orderInfo.batchById(List),然后把返回的数据以id做key,每行记录做value存储到Map中,循环内只需要根据id就可以获取到每条记录。

②. 不要在for循环内执行 redisTemplate.hget(key,field),而是在循环外执行 redisTemplate.hmget(key, fieldList),一次性的获取所有值,按照顺序获取每个值就OK了。

6、代码中绝对不能写sleep,要是有这样的代码怎么优化都白扯,TPS肯定上不去。

7、把耗时并且不影响业务主流程的逻辑异步处理,启用线程去处理这些业务。比如,用户每次下单前都需要自动释放上一笔没有支付的订单,像这种情况可以启动一个线程单独处理,并且不用等待线程的返回接口。

8、一个大的业务方法中,各子模块相互独立,互不依赖,可以考虑使用并发处理,即多线程并发查询数据。有个前提是该接口应至少高于20ms,如果再低,线程切换等因素可能会抵消掉多线程带来的性能提高。比如,首页接口需要返回3块数据,每块都是独立的,并且都比较耗时,所以可以启动3个线程同时获取数据,最后等待每个线程返回结果。

9、业务数据增加Redis缓存。这是减少数据库查询,提升TPS的有效手段。但是要根据实际业务情况来使用Redis,合理的设计好缓存key的结构,避免缓存重复数据浪费空间。使用缓存的时候需要注意缓存穿透、缓存雪崩等问题。

10、异步执行任务的时候需要使用线程池,不能直接创建线程并启动。创建线程池时需要使用无界队列,若使用有界队列,当并发量大,并且等待线程超过队列大小时就会报错,线程无法放入队列导致任务丢失。无界队列创建方式:

public static ExecutorService noticePushPool = new ThreadPoolExecutor(50,

100,0L, TimeUnit.MILLISECONDS,

new LinkedBlockingDeque<>(), new ThreadFactoryBuilder()

.setNameFormat(“notice-push-pool-%d”).build(), new ThreadPoolExecutor.AbortPolicy());

LinkedBlockingDeque 不指定大小默认创建大小为int的最大值,也可以手动设置队列大小,但是不建议。

以上优化都属于外部优化,要是还需要深度优化的话,可以考虑优化业务逻辑代码,尽量减少循环次数,提高代码的执行效率,降低时间复杂度,所以操作时间复杂度尽快能达到O(1)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值