日常工作中,我们多少都会遇到应用的性能问题。在阿里面试中,性能优化也是常被问到的题目,用来考察是否有实际的线上问题处理经验。面对这类问题,阿里工程师齐光给出了详细流程。来阿里面试前,先看看这篇文章哦。
性能问题和Bug不同,后者的分析和解决思路更清晰,很多时候从应用日志(文中的应用指分布式服务下的单个节点)即可直接找到问题根源,而性能问题,其排查思路更为复杂一些。
对应用进行性能优化,是一个系统性的工程,对工程师的技术广度和技术深度都有所要求。一个简单的应用,它不仅包含了应用代码本身,还和容器(虚拟机)、操作系统、存储、网络、文件系统等紧密相关,线上应用一旦出现了性能问题,需要我们从多方面去考虑。
与此同时,除了一些低级的代码逻辑引发的性能问题外,很多性能问题隐藏的较深,排查起来会比较困难,需要我们对应用的各个子模块、应用所使用的框架和组件的原理有所了解,同时掌握一定的性能优化工具和经验。
本文总结了我们在进行性能优化时常用的一些工具及技巧,目的是希望通过一个全面的视角,去感知性能优化的整体脉络。本文主要分为下面三个部分:
- 第一部分会介绍性能优化的一些背景知识。
- 第二部分会介绍性能优化的通用流程以及常见的一些误区。
- 第三部分会从系统层和业务层的角度,介绍高效的性能问题定位工具和高频性能瓶颈点分布。
本文中提到的线程、堆、垃圾回收等名词,如无特别说明,指的是 Java 应用中的相关概念。
1.性能优化的背景
前面提到过,应用出现性能问题和应用存在缺陷是不一样的,后者大多数是由于代码的质量问题导致,会导致应用功能性的缺失或出现风险,一经发现,会被及时修复。而性能问题,可能是由多方面的因素共同作用的结果:代码质量一般、业务发展太快、应用架构设计不合理等,这些问题处理起来一般耗时较长、分析链路复杂,大家都不愿意干,因此可能会被一些临时性的补救手段所掩盖,如:系统水位高或者单机的线程池队列爆炸,那就集群扩容增加机器;内存占用高/高峰时段 OOM,那就重启分分钟解决......
临时性的补救措施只是在给应用埋雷,同时也只能解决部分问题。譬如,在很多场景下,加机器也并不能解决应用的性能问题,如对时延比较敏感的一些应用必须把单机的性能优化到极致,与此同时,加机器这种方式也造成了资源的浪费,长期来看是得不偿失的。对应用进行合理的性能优化,可在应用稳定性、成本核算获得很大的收益。
上面我们阐述了进行性能优化的必要性。假设现在我们的应用已经有了性能问题(eg. CPU 水位比较高),准备开始进行优化工作了,在这个过程中,潜在的痛点会有哪些呢?下面列出一些较为常见的:
- 对性能优化的流程不是很清晰。初步定为一个疑似瓶颈点后,就兴高采烈地吭哧吭哧开始干,最终解决的问题其实只是一个浅层次的性能瓶颈,真实的问题的根源并未触达;
- 对性能瓶颈点的分析思路不是很清晰。CPU、网络、内存......这么多的性能指标,我到底该关注什么,应该从哪一块儿开始入手?
- 对性能优化的工具不了解。遇到问题后,不清楚该用哪个工具,不知道通过工具得到的指标代表什么。
2.性能优化的流程
在性能优化这个领域,并没有一个严格的流程定义,但是对于绝大多数的优化场景,我们可以将其过程抽象为下面四个步骤。
- 准备阶段:主要工作是是通过性能测试,了解应用的概况、瓶颈的大概方向,明确优化目标;
- 分析阶段:通过各种工具或手段,初步定位性能瓶颈点;
- 调优阶段:根据定位到的瓶颈点,进行应用性能调优;
- 测试阶段:让调优过的应用进行性能测试,与准备阶段的各项指标进行对比,观测其是否符合预期,如果瓶颈点没有消除或者性能指标不符合预期,则重复步骤2和3。
下图即为上述四个阶段的简要流程。
2.1 通用流程详解
在上述通用流程的四个步骤当中,步骤2和3我们会在接下来两个部分重点进行介绍。首先我们来看一下,在准备阶段和测试阶段,我们需要做一些什么。
★ 2.1.1 准备阶段
准备阶段是非常关键的一步,不能省略。
首先,需要对我们进行调优的对象进行详尽的了解,所谓知己知彼,百战不殆。
- 对性能问题进行粗略评估,过滤一些因为低级的业务逻辑导致的性能问题。譬如,线上应用日志级别不合理,可能会在大流量时导致 CPU 和磁盘的负载飙高,这种情况调整日志级别即可;
- 了解应用的的总体架构,比如应用的外部依赖和核心接口有哪些,使用了哪些组件和框架,哪些接口、模块的使用率较高,上下游的数据链路是怎么样的等;
- 了解应用对应的服务器信息,如服务器所在的集群信息、服务器的 CPU/内存信息、安装的 Linux 版本信息、服务器是容器还是虚拟机、所在宿主机混部后是否对当前应用有干扰等;
其次,我们需要获取基准数据,然后结合基准数据和当前的一些业务指标,确定此次性能优化的最终目标。
- 使用基准测试工具获取系统细粒度指标。可以使用若干 Linux 基准测试工具(eg. jmeter、ab、loadrunnerwrk、wrk等),得到文件系统、磁盘 I/O、网络等的性能报告。除此之外,类似 GC、Web 服务器、网卡流量等信息,如有必要也是需要了解记录的;
- 通过压测工具或者压测平台(如果有的话),对应用进行压力测试,获取当前应用的宏观业务指标,譬如:响应时间、吞吐量、TPS、QPS、消费速率(对于有 MQ