性能测试是软件测试中细分的一块,也是难度比较大的,大部分人学习性能测试都是偏重工具的使用了,有点本末倒置,性能测试最主要还是性能分析,性能调优。性能测试时我们一般使用如下参考:
要去测性能我们首先得知道哪些因素会影响到性能,我们知道一个应用系统不是独立的,而是依赖很多因素,依赖的因素都是影响性能的变量,如果我们只关注某些因素那测试的时候一定要保持其他因素不变才会有个稳定的结果。以看病为例,从中医的角度看人体器官是个互相依赖的复杂系统,不能头痛医头脚痛医脚。
下面介绍下哪些因素会影响到性能,以及是怎么影响的。
影响性能4大要素
影响性能主要是这么4大方面的因素:
1)硬件层面
计算(CPU)、存储(Storage)、网络(Network),计算机硬件资源也主要是这3方面的资源,现在流行的云计算也主要是这3大资源的虚拟化
2)系统层面
操作系统(Operating sytstem)是大部分应用离不开的一个平台,目前前后端主流的操作系统是Linux,Windows,Android,iOS。同一种操作系统,不同的发行版本对性能的影响也是比较大。
3)中间件、数据库
这一层不是每个应用都会涉及,但大多数复杂的后台应用系统都会涉及到。比如很多web server会用到middleware Tomcat、Nginx, 会用到数据库MySQL、Oracle.
4)应用程序
最后这个就是我们直接接触,直接测试的系统本身了,对性能影响最大的因素毫无疑问就是应用程序本身了。
1、硬件层面
硬件设施不好影响性能大家肯定都知道,手机CPU一般通俗的讲就是手机芯片。运行内存8G用起来卡,换成16G可能就飞起了。你百兆网卡的电脑接的光纤网速再快也只能跑100M/s。
实际上硬件层面对性能的影响还远远不止我们了解到的上面这些概念。
1.1 CPU、Memory
现在硬件和软件的区分越来越不明显了,很多固件或者驱动我们有时也可以看成硬件。很多服务器都有CPU核的虚拟化功能,比如实际上4个物理CPU核,但是可以虚拟化出来让操作系统层面看到是8个核。但是CPU的这个虚拟化功能开启的时候性能好还是关闭的时候性能好呢? 这个要看具体应用,没有通用的答案,所以这就有性能调优的空间。
现在CPU多核后,所有的核通过总线访问内存,总线就成为瓶颈了,于是出现了NUMA架构,把CPU分组,每组分一块内存就近访问,不是通过总线统一访问。那分几个NUMA呢,以及有NUMA后怎么调优,网上会看到很多关于MySQL在使用NUMA时很多坑,有很多调优的推荐方案。
关于存储,很多传统的数据库大部分数据是放磁盘上的,访问太慢性能不能满足需要,现在就有很多内存数据库,比如Redis、HANA
1.2 Network
关于网卡,大家比较容易想到的是比如两个网卡组bond,配成主备模式相当只发挥了一个网卡的功能,另外一个没起作用,不过稳定可靠点,配成负载均衡的话两个网卡的能力都发挥了。
另外现在大型互联网公司每天处理海量的数据,传统的数据流是这样的: 物理网卡->网卡驱动->TCP/IP协议栈->Socket接口->上层应用,这里数据处理的路径比较长而且还涉及到linux内核空间(tcp/ip协议栈)到用户空间(socket接口)的切换,时延肯定太长,于是出现了intel推出的DPDK, 数据直接从物理网卡->用户空间的DPDK了。腾讯、华为很多后台处理就用到了DPDK。虽然有DPDK这么个框架给你用,但是实际用于生产可能就涉及到自己的一些客制化处理,性能调优了。
2、操作系统层面
操作系统层面涉及到的调优就太多了啊,先别说怎么调,关是选哪个就够头疼了,以Linux为例。Redhat、CentOS、SuSE你选哪个,用哪个版本?特别是你的应用比较偏底层处理的话会影响很大的,比如我自己测的产品跑性能测试时,SuSE 11 SP1结果比较好,升级到SuSE 11 SP2性能下降明显,调查发现新patch的一个功能会影响到功能,最后解决方案就改配置把那个功能禁用了。后面从SP2升级到SP3发现性能又降了,具体原因还在调查中…
另外一些操作系统常用的配置,比如你没有使用GUI的需求,那就直接禁用GUI,如果你的应用对磁盘操作比较多,那你得对比下不同文件系统的性能情况…
3、中间件、数据库
中间件的话比如Tomcat、Nginx这些东东有很多配置,设置不同的参数对性能影响很大,比如Nginx配置单个进程允许客户端最大连接数、绑定不同Nginx进程到不同CPU核。
数据库的调优就更复杂了,都够你去折腾一辈子的了,简单的比如不同SQL语句的写法性能差着十万八千里。一些常用的表的数据操作逻辑是放代码里面处理还是弄成存储过程放数据库上,这个不仅要从功能架构角度考虑还要从性能角度考虑了。
4、应用程序
我们平常说性能其实很多时候较少考虑上面提到的3点,狭义来讲主要关注应用程序本身。菜鸟写出来的代码比牛人写的差着几条街,除了功能、稳定性、可以扩展性外最能体现差别的还是性能,这个除了些通用的编程最佳实践外,就得根据具体的应用具体分析了。
在学校学数据结构和算法的课时大家知道有个时间复杂度,可以衡量下算法的性能是好事坏,这个确实有点用。不过你真正工作中写代码时打着灯笼可能也找不到哪个地方要你写个复杂算法,好不容易有个排序的需要一般调用个函数sort下就行,你可能感觉英雄无用武之地了。那就只能在很多细小的方面去考虑性能了,比如别太频繁写磁盘,先把数据放内存,达到多少再刷磁盘。别想着内存够够的想分配多少就多少,得抠门点省着用,能用一个字节解决的就别用两个字节,内存用完了就快点释放掉。