一、背景
行业常识,性能问题和功能Bug 不同,而后者的分析和解决思路清晰且直接,很多时候从应用日志(文中的应用指分布式服务下的单个节点)即可直接找到问题根源,而性能问题,其排查思路则较为复杂一些。
应用的性能优化,是一个系统性的工程,对工程师的技术广度和技术深度都有所要求。一个简单的应用,它不仅包含了应用代码本身,还和容器(虚拟机)、操作系统、存储、网络、文件系统等紧密相关,线上应用一旦出现了性能问题,
更需要从多方面去思考和寻找问题,与此同时,除了一些低级的代码逻辑引发的性能问题外,很多性能问题隐藏的较深,排查起来会比较困难,需要我们对应用的各个子模块、应用所使用的框架和组件的原理有所了解,同时掌握一定的性能优化工具和经验。
二、痛点--引蛇出洞
前面提到过,应用出现性能问题和应用存在缺陷是不一样的,后者大多数是由于代码的质量问题导致,会导致应用功能性的缺失或出现风险,一经发现,会被及时修复。而性能问题,可能是由多方面的因素共同作用的结果:
代码质量一般、业务发展太快、应用架构设计不合理等,这些问题处理起来一般耗时较长、分析链路复杂,大家都不愿意干,因此可能会被一些临时性的补救手段所掩盖,如:系统水位高或者单机的线程池队列爆炸,那就集群扩容增加机器;
内存占用高/高峰时段 OOM,那就重启分分钟解决...
弊端:临时性的补救措施只是在给应用埋雷,同时也只能解决部分问题,譬如,在很多场景下,加机器也并不能解决应用的性能问题,如对时延比较敏感的一些应用必须把单机的性能优化到极致,与此同时,加机器这种方式也造成了资源的浪费,长期来看是得不偿失的。对应用进行合理的性能优化,可在应用稳定性、成本核算获得很大的收益;
上面我们阐述了进行性能优化的必要性。假设现在我们的应用已经有了性能问题(eg. CPU 水位比较高),准备开始进行优化工作了,在这个过程中,潜在的痛点会有哪些呢?
常见痛点:
1.对性能优化的流程不是很清晰。初步定为一个疑似瓶颈点后,就兴高采烈地吭哧吭哧开始干,最终解决的问题其实只是一个浅层次的性能瓶颈,真实的问题的根源并未触达;
2.对性能瓶颈点的分析思路不是很清晰。CPU、网络、内存......这么多的性能指标,我到底该关注什么,应该从哪一块儿开始入手?
3.对性能优化的工具不了解。遇到问题后,不清楚该用哪个工具,不知道通过工具得到的指标代表什么。
三、性能优化流程(优化方案)
在性能优化这个领域,并没有一个严格的流程定义,但是对于绝大多数的优化场景,我们可以将其过程抽象为下面四个步骤:
1、准备阶段:主要工作是是通过性能测试,了解应用的概况、瓶颈的大概方向,明确优化目标;
2、分析阶段:通过各种工具或手段,初步定位性能瓶颈点
3、调优阶段:根据定位到的瓶颈点,进行应用性能调优;
4、测试阶段:让调优过的应用进行性能测试,与准备阶段的各项指标进行对比,观测其是否符合预期,如果瓶颈点没有消除或者性能指标不符合预期,则重复步骤2和3。
下图即为上述四个阶段的简要流程。
四、分析工具--工欲善其事必先利其器
性能优化其实就是找出应用/系统架构存在性能瓶颈点,然后设法通过一些调优手段去缓解。性能瓶颈点的定位是较困难的,快速、直接地定位到瓶颈点,需要具备下面两个条件:
1、神兵利器的工具;
2、扎实的性能优化经验
五、性能问题/异常的分析思路有哪些
在实际运行中,性能测试涉及到系统、组件、应用,这三者往往是相辅相成、相互影响的。系统是为应用提供了运行时环境,性能问题的本质就是系统资源达到了使用的上限,反映在应用层,就是应用/组件的各项指标开始下降;
而应用/组件的不合理使用和设计,也会加速系统资源的耗尽。性能瓶颈点的分布都可能落在三个纬度上,因此,分析瓶颈点时,需要我们结合从不同角度分析出的结果,抽出共性,得到最终的结论。
六、总结
性能优化是一个很大的领域,这里面的每一个小点,都可以拓展为数十篇文章去阐述。对应用进行性能优化,除了上面介绍的之外,还有前端优化、架构优化(分布式、缓存使用等)、数据存储优化、代码优化(如设计模式优化)等,限于篇幅所限,在这里并未一一展开,本文的这些内容,只是起一个抛砖引玉的作用。同时,本文的东西是我的一些经验和知识,并不一定全对,希望大家指正和补充。
性能优化是一个综合性的工作,需要不断地去实践,将工具学习、经验学习融合到实战中去,不断完善,形成一套属于自己的调优方法论。
此外,虽然性能优化很重要,但是不要过早在优化上投入太多精力(当然完善的架构设计和编码是必要的),过早优化是万恶之源。一方面,提前做的优化工作,可能会不适用快速变化的业务需求,反倒给新需求、新功能起了阻碍的作用;另一方面,过早优化使得应用复杂性升高,降低了应用的可维护性。何时进行优化、优化到什么样的程度,是一个需要多方权衡的命题。