一、开篇
做好性能优化可以节约资源、提高用户体验、规避风险。在代码开发时候我们要保证有效的编码,在上线前需要对系统进行性能测试,在参考平台上进行压测,在项目上线后,根据日志和监控系统来观测系统性能问题。
二、性能指标
1、操作系统
系统元素 | 指标 | 因子 |
cpu | 使用率 | 慢调用;大量线程切换;死循环; |
负载 | 慢调用; | |
内存 | 使用率 | 内存溢出;内存泄漏; |
磁盘 | 读写次数 | |
网络 | 带宽 | |
传输次数 | 小报文 | |
吞吐量 |
2、业务系统
指标 | 因子 |
吞吐量 - tps/qps | I/o模型 |
延迟时间 | 慢sql |
三、如何做性能优化
1、编码优化
根据二八定律,往往20%的代码执行会占据80%的资源,优化时候需要针对导致性能瓶颈的代码进行优化。
举个例子: 我们在日常工作中,有些业务逻辑是从db中获取数据,然后在jvm内存中进行过滤。这样很容易造成oom,过滤逻辑应该直接由db实现,然后加载过滤后的数据到内存中。
2、锁机制优化
相对于使用悲观锁,如mysql 事务对应行锁,使用乐观锁机制可以极大优化性能。例如在日常库存扣减业务中,基于乐观锁和版本号机制可以实现不需要mysql事务实现。
3、线程池优化
需要区分业务时i/o密集型还是cpu密集型设定线程数量。
具体的线程数量: N(CPU核数)*(1+WT(线程等待时间)/ST(线程时间运行时间)
4、慢sql优化
sql语句执行的快慢主要和扫描行数/进行磁盘io的次数有关。
对于多条件查询,需要给基数大的查询条件加上索引。
全表扫描需要加上limit限制,可以根据服务器和id进行取余获取。
5、内存优化
a.对象拷贝/复制
对象拷贝需要使用浅拷贝方式,之前由遇到过写的序列化工具类,先将source转成json字符串 ,后再json字符串序列化成target,这种方式特别耗内存。应该改成基于反射进行setter/getter操作。
b.内存计算改为数据库计算
c.内存溢出
最常见的内存溢出是map数据结构,每次执行都会往map中写数据,但是没有清除逻辑。
6.慢调用优化
1、同步调用改成异步调用,后续接收远程响应事件。
在一些交易场景中,售后操作往往都是异步的。
2、并行调用。
基于future-listener机制,发起并行调用。