引言:性能瓶颈调优
在实际的性能测试中,会遇到各种各样的问题,比如 TPS 压不上去等,导致这种现象的原因有很多,测试人员应配合开发人员进行分析,尽快找出瓶颈所在。
性能调优步骤
- 确定问题:根据性能监控的数据和性能分析的结果,确定性能存在的问题。
- 确定原因:确定问题之后,对问题进行分析,找出问题的原因。
- 确定解决方案(改服务器参数配置/增加硬件资源配置/修改代码)。
- 验证解决方案,分析调优结果。
注意:性能测试调优并不是一次完成的过程,针对同一个性能问题,上述步骤可能要经过多次循环才能最终完成性能调优的目标,即:测试发现问题 -> 找原因 -> 调整 -> 验证 -> 分析 -> 再测试 ...
性能瓶颈概率分布
60%:数据库瓶颈
- 数据库服务器 CPU 使用率高(慢查询、SQL 过多、连接数过多)
- 抛出连接数过多(连接池设置太小,导致连接排队)
- 数据库出现死锁
25%:应用瓶颈
- 应用出现内存泄露
- 应用出现线程竞争/死锁
- 程序代码的算法复杂度
- 中间件、第三方应用出现异常
- 计算密集型任务引起 CPU 负载高
- I/O 密集型任务引起 I/O 负载高
10%:压测工具瓶颈
- JMeter 单机负载能力有限,如果需要模拟的用户请求数超过其负载极限,也会导致 TPS 压不上去
5%:Linux 机器出现异常
- Linux 可用内存无法回收(开销速率大于回收速率)
系统资源
- CPU监控内容:CPU 使用率、CPU 使用类型(用户进程、内核进程)瓶颈分析:CPU已压满(接近 100%),需要再看其他指标的拐点所出现的时刻是否与 CPU 压满的时刻基本一致。
- 内存监控内容:实际内存、虚拟内存瓶颈分析:内存不足时,操作系统会使用虚拟内存,从虚拟内存读取数据,影响处理速度。
- 磁盘 I/O监控内容:I/O 速度、磁盘等待队列瓶颈分析:磁盘 I/O 成为瓶颈时,会出现磁盘I/O繁忙,导致交易执行时在 I/O 处等待。
- 网络监控内容:网络流量(带宽使用率)、网络连接状态瓶颈分析:如果接口传递的数据包过大,超过了带宽的传输能力,就会造成网络资源竞争, 导致 TPS 上不去。
发现了瓶颈后,只要对症下药就可以了。简单来说无论哪个地方出现瓶颈,只需要降低压力或者增加这部分瓶颈资源(应用软件没有瓶颈或优化空间之后),即可缓解症状。
- CPU 瓶颈:增加 CPU 资源。
- 内存瓶颈:增加内存、释放缓存。
- 磁盘 I/O 瓶颈:更换性能更高的磁盘(如固态 SSD)。
- 网络带宽瓶颈;增加网络带宽。
CPU
后台服务的所有指令和数据处理都是由 CPU 负责,服务对 CPU 的利用率对服务的性能起着决定性的作用。
top 参数详解
下面以 top 命令的输出例,对 CPU 各项主要指标进行说明:
- us(user):运行(未调整优先级的)用户进程所消耗的 CPU 时间的百分比。像 shell 程序、各种语言的编译器、数据库应用、web 服务器和各种桌面应用都算是运行在用户地址空间的进程。这些程序如果不是处于 idle 状态,那么绝大多数的 CPU 时间都是运行在用户态。
- sy(system):运行内核进程所消耗的 CPU 时间的百分比。所有进程要使用的系统资源都是由 Linux 内核处理的。当处于用户态(用户地址空间)的进程需要使用系统的资源时,比如需要分配一些内存、或是执行 I/O 操作、再或者是去创建一个子进程,此时就会进入内核态(内核地址空间)运行。事实上,决定进程在下一时刻是否会被运行的进程调度程序就运行在内核态。对于操作系统的设计来说,消耗在内核态的时间应该是越少越好。通常 sy 比例过高意味着被测服务在用户态和系统态之间切换比较频繁,此时系统整体性能会有一定下降。在实践中有一类典型的情况会使 sy 变大,那就是大量的 I/O 操作,因此在调查 I/O 相关的问题时需要着重关注它。大部分后台服务使用的 CPU 时间片中 us 和 sy 的占用比例是最高的。同时这两个指标又是互相影响的,us 的比例高了,sy 的比例就低,反之亦然。另外,在使用多核 CPU 的服务器上,CPU 0 负责 CPU 各核间的调度,CPU 0 上的使用率过高会导致其他 CPU 核心之间的调度效率变低。因此测试过程中需要重点关注 CPU 0。
- ni(niced):用做 nice 加权的进程分配的用户态 CPU 时间百分比。每个 Linux 进程都有个优先级,优先级高的进程有优先执行的权利,这个叫做 pri。进程除了优先级外,还有个优先级的修正值。这个修正值就叫做进程的 nice 值。这里显示的 ni 表示调整过 nice 值的进程消耗掉的 CPU 时间。如果系统中没有进程被调整过 nice 值,那么 ni 就显示为 0。一般来说,被测服务和服务器整体的 ni 值不会很高。如果测试过程中 ni 的值比较高,需要从服务器 Linux 系统配置、被测服务运行参数查找原因。
- id(idle):空闲的 CPU 时间百分比。一般情况下, us + ni + id 应该接近 100%。线上服务运行过程中,需要保留一定的 id 冗余来应对突发的流量激增。在性能测试过程中,如果 id 一直很低,吞吐量上不去,需要检查被测服务线程/进程配置、服务器系统配置等。
- wa(I/O wait):CPU 等待 I/O 完成时间百分比。和 CPU 的处理速度相比,磁盘 I/O 操作是非常慢的。有很多这样的操作,比如:CPU 在启动一个磁盘读写操作后,需要等待磁盘读写操作的结果。在磁盘读写操作完成前,CPU 只能处于空闲状态。Linux 系统在计算系统平均负载时会把 CPU 等待 I/O 操作的时间也计算进去,所以在我们看到系统平均负载过高时,可以通过 wa 来判断系统的性能瓶颈是不是过多的 I/O 操作造成的。磁盘、网络等 I/O 操作会导致 CPU 的 wa 指标提高。通常情况下,网络 I/O 占用的 wa 资源不会很高,而频繁的磁盘读写会导致 wa 激增。如果被测服务不是 I/O 密集型的服务,那需要检查被测服务的日志量、数据载入频率等。如果 wa 高于 10% 则系统开始出现卡顿;若高于 20% 则系统几乎动不了;若高于 50% 则很可能磁盘出现故障。
- hi:硬中断消耗时间百分比。
- si:软中断消耗时间百分比。硬中断是外设对 CPU 的中断,即外围硬件发给 CPU 或者内存的异步信号就是硬中断信号;软中断由软件本身发给操作系统内核的中断信号。通常是由硬中断处理程序或进程调度程序对操作系统内核的中断,也就是我们常说的系统调用(System Call)。在