[性能优化]-02制定调优策略


总结:测试——分析——优化
一、测试--> 输出,性能测试报告
1、微基准性能测试
	精准测试,测试某个模块/方法在不同的实现方式下的性能表现。
2、宏基准性能测试,
	综合测试,考虑:测试环境、场景、目标
		环境,模拟真实线上环境
		场景,排除干扰因素,包含:其他服务、第三方接口
		目标,逐渐增加并发数,测试TPS(最大的每秒事务请求数),并观察:吞吐量、响应时间、cpu、内存、磁盘IO、网络IO使用率等
输出“性能测试报告”,包含以下指标:
	测试接口的平均/最大/最小吞吐量
	响应时间
	cpu/内存/磁盘IO/网络IO的资源使用率
	jvm的gc频率
	
干扰因子
1、热身问题
	现象,第一次请求接口比较慢,后面请求越来越快
	分析,.java文件被编译为.class文件后,需要解释器转化为机器码 才能运行。某个方法/代码块被经常执行,则被虚拟机认定为“热点代码”。为了提高执行效率,虚拟机通过编译器把这些代码编译为与本地平台相关的机器码,并进行各个层次的优化,后存储在内存中,之后运行时,直接从内存中获取。因此,刚开始运行时比较慢(虚拟机花长时间全面优化代码),越往后越快
2、测试结果不稳定
	即使测试的数据集一样,结果也可能有差异。考虑,机器中其他进程影响,网络波动,jvm垃圾回收等
	可以通过多次测试,求平均值/统计曲线图,保证平均值在合理范围之内即可。
3、多jvm的影响
	任意一个jvm都拥有整个系统的资源使用权,尽量保证线上环境一台机器中部署一个jvm。

二、分析 (自下而上)
按照下面顺序,分析“性能测试报告”
	1、计算机资源:cpu、内存、磁盘IO、网络IO 是否存异常?并查看异常日志
	2、容器:web容器
	3、jvm层面:垃圾回收频率、内存分配情况
	4、应用服务器:java编码问题、读写数据瓶颈

三、优化(自上而下)
1、应用层的调优
	1)优化代码,因为资源耗尽而暴露。
		代码问题,如:内存溢出/jvm内存用完,引发jvm频繁垃圾回收,导致cpu1000%,又消耗系统cpu资源
		非代码问题,如:for循环遍历LinkedList。每次循环都要遍历一次链表,降低读的效率。
	2)优化设计,利用设计模式优化业务层/中间层的代码设计,精简代码,提高性能
		如,单例模式,共享创建的兑现,减少频繁创建、销毁带来的性能消耗
	3)优化算法
		如,查找算法
	4)时间换空间,适用于对存储容量要求苛刻,单查询速度不作要求的场景
		如,String的interm方法,将重复率高的数据存储在常量池中,节省存储空间。(常量池使用HashMap实现,不能存储过多数据,否则性能下降)
	5)空间换时间,提升访问速度
		如,分库分表。mysql单表数据上千万时,读写性能明显下降。
	
2、系统调优
	1)jvm调优,合理设置jvm内存空间、垃圾回收策略
		若业务中创建大量的大对象,可以通过设置将大对象直接放入 老年代,减少年轻代频繁发生小的垃圾回收(minor gc),减少cpu占用时间
	2)组件调优
		如,web容器,线程池的设置
	3)操作系统调优,优化内核参数
	
四、兜底策略!
无论系统调优多么好,总会存在承受极限,通过兜底方法,保证系统稳定性。
1、限流熔断。设置最大访问限制(参考tps值),友好返回没有成功的请求。
2、扩容
	1)智能横向扩容。当访问量超过指定阈值,自动新增/减少机器。
	2)提前扩容。常用于 高并发系统。
		如,瞬间的抢购业务,要提前加机器;瞬间大量请求,即使横向扩容成功了,抢购也结束了。
	推荐,Kubernetes作为Docker容器的容器管理器,可以实现智能 横向扩容+ 提前扩容Docker服务

总结,
任何调优都需要结合场景,明确已知问题和性能目标,不能为了调优而调优,否则带来风险和bug。
调优策略千变万化,但思想和核心都一样的。都是从业务调优——编码调优——系统调优

 

你可能感兴趣的:(性能优化)