性能测试流程
性能测试
0、整体概览
测试步骤
-
确定测试内容
- 确定测试范围和指标
- 确定测试目标(服务对象)
-
准备数据文件
- 导入文件
- 数据脚本(postgres)
-
准备压测脚本
-
部署测试环境
- 确定部署方式
- 部署想用的软件和服务
- 更改配置文件
- 启动相应服务
-
生成数据
-
压测
-
查看并记录测试相应指标、优化
- 分析相应的指标: 系统CPU使用率、系统内存使用量、系统平均负载、读写请求数、fullgc的频率和耗时、jvm内存使用率等等
- 优化
- 测试报告。
- 测试报告要记录很多数据, 参看附件
测试流程
1、测试目标确认
1、测试范围确认(测试场景、数据规模、并发档次)
结合实际产品情况,选取业务上压力较大的场景进行测试,一般包括导入、登录、离线下载,店面签到、报表查询等等。
数据规模:需要根据目前实际的项目情况总结得出。
并发档次:一般分为几个档次,根据数据规模和实际情况得出,实际生产环境中的最大并发量。
2、确定测试目标
性能测试目的是验证软件系统是否能够达到用户提出的性能指标,同时发现软件系统中存在的性能瓶颈,优化软件,最后起到优化系统的目的。包括以下几个方面1.评估系统的能力,测试中得到的负荷和响应时间数据可以被用于验证所计划的模型的能力,并帮助作出决策。2.识别体系中的弱点:受控的负荷可以被增加到一个极端的水平,并突破它,从而修复体系的瓶颈或薄弱的地方。3.系统调优:重复运行测试,验证调整系统的活动得到了预期的结果,从而改进性能。检测软件中的问题:长时间的测试执行可导致程序发生由于内存泄露引起的失败,揭示程序中的隐含的问题或冲突。4.验证稳定性(resilience)可靠性(reliability):在一个生产负荷下执行测试一定的时间是评估系统稳定性和可靠性是否满足要求的唯一方法。
本次测试最初的目的:差不多就如上所述,确定测试场景、并发量、部署方式和健康指标(业务指标和技术指标)之后,验证软件和平台服务是否能满足相应的指标。不满足则调整业务代码、硬件配置等等,使之满足相应的健康指标。
测试过程中,目标可能根据实际情况进行更改,由于:
1、目前标准产品的性能测试不能满足不同项目的需求,产品的逻辑更改对于项目来说意义并不是很大。 拿产品的测试场景来测不能体现平台服务的性能。
2、运维方面更加在意的是当前服务不做更改的情况下,我需要的什么样的硬件配置才能更好的节省资源。
综合以上内容,重新确认目标: 按照性能隔离原则,尽量选择能组成的最小颗粒度的服务部署在同一台服务器上,选择与产品业务逻辑关联不大的场景组成混合场景,使用当前已有的平台服务,调整硬件参数,得到当前场景和部署方式下最优的配置方式(最少资源获取最大效益)
总结: 确定服务对象 - 获得测试方式
性能测试场景设计:
混合测试场景: 多少人、多少并发、不同的使用场景结合。
不同场景分配的比例是多少,根据项目的实际运行情况。 取用户数量比较大的,并发量比较大的场景去测试
执行时长 分配多少,一些场景延时执行
资源监控:
脚本监控、 moon实时监控、linux命令直接监控、top、vmstat、iostat、free等等、阿里云平台监控、
脚本执行服务器使用 java自带 console监控工具查看内存。合理配置 jvm内容,防止内存溢出
业务指标就是 jmete生成的聚和报告
遇到问题:
1、造数据时: 数据库操作很慢(
- 更改数据库配置文件(最大并发连接数、共享缓存、effective_cache_size、maintenance_work_mem、checkpoint_segments。 http://blog.itpub.net/29487349/viewspace-2374748/ )
不如之前的效果好;
2、离线响应的时间慢。 网关流量限制
3、测试指标确认
业务指标大致包括: 平均响应时间、最大耗时时间、成功率、吞吐量、TPS等。
技术指标包括: 死锁、阻塞SQL数、系统CPU平均使用率、系统内存使用量、系统平均负载、读写请求数、fullgc频率、fullgc耗时、jvm内存使用率等等
具体的指标健康值,根据历史经验如下:
| 系统平均负载<cpu核*2 |
| fullgc频率≤1次/分 |
| fullgc耗时 ≤1秒/次 |
| 等等待补充 |
需要记录不同并发档次下每一个场景这些指标,不同的服务和服务器需要的指标和指标约束都不同的,可根据实际情况来确定。
2、准备数据脚本
准备数据原则: 业务复杂或者数据不多的可以直接使用后台导入的方式。 数据量多的使用脚本在数据库导入
脚本准备注意点:
- 需熟悉相应场景需要的数据关联的表结构。
- 不同类型的字段生成数据的方式,比如说 id字段、基础字段、业务对象、关联对象等等
- 基础字段可以直接造数据;
- 业务对象是1:n的关系,需要从其他表中获取数据。
- 关联对象是n:n的关系,需要插入中间表
- 造数据是最好给插入数据比较明显的标志,清除数据时比较方便。
- 造数据的循环结构需要关注性能,循环次数多的情况下性能容易出问题
造数据时还有很多sql的细节注意点,比如如何调试、变量设置和使用等;留个坑后续记录
3、准备测试脚本
jemeter测试: 请求、后置处理器、监听器、调试器
- 脚本准备的方式:
- 根据原有的脚本更改调试
- 使用录制工具录制并调试
- 录制之后会有很多的无效api,需要跟产品人员确认后,清除无用的api
- 环境准备注意点
- 脚本可能涉及到相应的jar包,须确保jmeter有相应的jar包才能启动成功
- jar包放入jemeter对应的jar包文件中
- 在配置文件中更改jmeter的原有字符编码方式,否则很容易出现乱码
- 脚本准备需要关注点(具体实现方式后续补充)
- 设置全局变量、登录账号文件、http请求默认值、http信息头管理器等,尽量减少在具体http请求中设置这些值,更改维护都比较方便
- 正则表达式获取token方式
- beanshell 后置处理器获取token
- beanshell 后置处理器 对请求返回内容进行分析并写入文件
- 监听器设置
- 查看结果树
- 聚合报告
- 关注相应时间和流量
4、部署测试环境
具体8系环境部署可参考 http://172.16.0.124/technology/193/ 独立部署的一般步骤
部署环境时,当首先确定两点:
- 测试环境服务器的个数以及配置;
- 不同服务需要以什么组合部署到那台服务器上
如图,即需要确认相应的服务部署的方式。
部署流程如下,大致有以下五步:
- 确定不同的服务在哪个服务器上之后,安装相应的安装包,并启动Nginx服务。
- 这里的服务包含环境服务和业务服务。环境服务安装,业务服务上传相应的服务部署包之后解压即可
- 在morelove网址上修改相应的配置信息并发布
- 在租户管理系统中修改资源配置
- 服务器上启动所有相关的服务。
- 冒烟测试
环境部署注意点:
- 配置文件更改之后需要重启服务
- 需关注Nginx的配置文件,关于外网映射等
- 需关注数据库的配置文件,调整相应的参数 是数据库配置适应当前的系统环境以及数据量
5、造数据
造数据具体包含以下几点:
- 备份种子数据库内容,还原到新环境
- 清除无关数据
- 导入相应的数据
- 使用脚本在数据库中生成相应的数据
- 数据导入非常慢: 对应的解决方案
- 删除导入表的索引
- 更改数据库配置文件(最大并发连接数、共享缓存、effective_cache_size、maintenance_work_mem、checkpoint_segments。 http://blog.itpub.net/29487349/viewspace-2374748/ )
- 更改更高读写能力的磁盘
数据库也算是一种服务,服务性能不好,要跟踪此服务的各项性能指标才能发现问题。 造数据时就发现数据库服务器iops达到瓶颈,所以才对磁盘进行更改
6、压测
压测过程中遇到不少问题,:
1、 压测服务器内存溢出:更改堆内存大小
2、 压测报错:Address already in use : connect 。
是因为windows本身提供的端口访问机制的问题。 Windows XP提供给 TCP/IP链接的端口为 1024-5000,并且要四分钟来循环回收他们。就导致我们在短时间内跑大量的请求时将端口占满了。
3、压测业务指标或者技术指标不达标
- 更改jvm堆内存配置,合理分配内存
- 更改硬件配置:CPU核数、内存等硬件配置
- 优化代码
7、查看测试相应指标并记录
测试指标可以使用linux相应的命令查看,也可以使用云监控平台查看。
主要监控的指标大致为: 死锁、阻塞SQL数、系统CPU平均使用率、系统内存使用量、系统平均负载、读写请求数、fullgc频率、fullgc耗时、jvm内存使用率
1 #查看cpu 2 3 top 4 5 #监控内存 6 7 free 8 9 #监控io 10 11 iostat 12 13 #查看磁盘 14 15 df 16 17 #根据进程名查看进程 18 19 ps -ef | grep 'keywords' 20 kill -9 pid 21 22 ps -aux 23 24 # 根据端口查看占用进程 25 netstat -nlp | grep 8080 26 27 #查看gc情况 28 29 jstat -gcutil 9482 10000 35 30 31 #查看系统配置 32 33 lscpu 34 35 #图形化格式查看内容和cpu 36 37 nmon
还可以使用nmon 命令进行可视化监控。
- 云平台监控:查看相应的图像
CPU、内存、系统负载
fullgc相关
jvm内存使用情况
注意:jvm内存设置会对性能影响较大。再次对jvm 堆内存相关参数做一个说明
数据库分析工具: 数据库堵塞,找出语句进行分析
8、测试报告
测试报告要记录不少数据, 具体可参考测试v8.4测试报告
备注:
1、 jvm
JVM按照其存储数据的内容将所需内存分配为堆区与非堆区两个部分:所谓堆区即为通过new的方式创建的对象(类实例)所占用的内存空间;非堆区即为代码、常量、外部访问(如文件访问流所占资源)等。
常见参数种类(配置内存):(-Xms 、-Xmx、-XX:newSize、-XX:MaxnewSize、-Xmn)、(-XX:PermSize、-XX:MaxPermSize)。参数的配置是分组的,前者是用来配置堆区的,后者是用来配置非堆区的。
第一组配置参数:-Xms 、-Xmx、-XX:newSize、-XX:MaxnewSize、-Xmn
1、-Xms :表示java虚拟机堆区内存初始内存分配的大小,通常为操作系统可用内存的1/64大小即可,但仍需按照实际情况进行分配。有可能真的按照这样的一个规则分配时,设计出的软件还没有能够运行得起来就挂了。
2、-Xmx: 表示java虚拟机堆区内存可被分配的最大上限,通常为操作系统可用内存的1/4大小。但是开发过程中,通常会将 -Xms 与 -Xmx两个参数的配置相同的值,其目的是为了能够在java垃圾回收机制清理完堆区后不需要重新分隔计算堆区的大小而浪费资源。
一般来讲对于堆区的内存分配只需要对上述两个参数进行合理配置即可,但是如果想要进行更加精细的分配还可以对堆区内存进一步的细化,那就要用到下面的三个参数了-XX:newSize、-XX:MaxnewSize、-Xmn。当然这源于对堆区的进一步细化分:新生代、中生代、老生代。java中每新new一个对象所占用的内存空间就是新生代的空间,当java垃圾回收机制对堆区进行资源回收后,那些新生代中没有被回收的资源将被转移到中生代,中生代的被转移到老生代。而接下来要讲述的三个参数是用来控制新生代内存大小的。
1、-XX:newSize:表示新生代初始内存的大小,应该小于 -Xms的值;
2、-XX:MaxnewSize:表示新生代可被分配的内存的最大上限;当然这个值应该小于 -Xmx的值;
3、-Xmn:至于这个参数则是对 -XX:newSize、-XX:MaxnewSize两个参数的同时配置,也就是说如果通过-Xmn来配置新生代的内存大小,那么-XX:newSize = -XX:MaxnewSize = -Xmn,虽然会很方便,但需要注意的是这个参数是在JDK1.4版本以后才使用的。
上面所述即为java虚拟机对外提供的可配置堆区的参数,接下来讲述java虚拟机对非堆区内存配置的两个参数:
1、-XX:PermSize:表示非堆区初始内存分配大小,其缩写为permanent size(持久化内存)
2、-XX:MaxPermSize:表示对非堆区分配的内存的最大上限。
这里面非常要注意的一点是:在配置之前一定要慎重的考虑一下自身软件所需要的非堆区内存大小,因为此处内存是不会被java垃圾回收机制进行处理的地方。并且更加要注意的是 最大堆内存与最大非堆内存的和绝对不能够超出操作系统的可用内存。
常见参数种类(配置内存):(-Xms 、-Xmx、-XX:newSize、-XX:MaxnewSize、-Xmn)、(-XX:PermSize、-XX:MaxPermSize)。参数的配置是分组的,前者是用来配置堆区的,后者是用来配置非堆区的。
第一组配置参数:-Xms 、-Xmx、-XX:newSize、-XX:MaxnewSize、-Xmn
1、-Xms :表示java虚拟机堆区内存初始内存分配的大小,通常为操作系统可用内存的1/64大小即可,但仍需按照实际情况进行分配。有可能真的按照这样的一个规则分配时,设计出的软件还没有能够运行得起来就挂了。
2、-Xmx: 表示java虚拟机堆区内存可被分配的最大上限,通常为操作系统可用内存的1/4大小。但是开发过程中,通常会将 -Xms 与 -Xmx两个参数的配置相同的值,其目的是为了能够在java垃圾回收机制清理完堆区后不需要重新分隔计算堆区的大小而浪费资源。
一般来讲对于堆区的内存分配只需要对上述两个参数进行合理配置即可,但是如果想要进行更加精细的分配还可以对堆区内存进一步的细化,那就要用到下面的三个参数了-XX:newSize、-XX:MaxnewSize、-Xmn。当然这源于对堆区的进一步细化分:新生代、中生代、老生代。java中每新new一个对象所占用的内存空间就是新生代的空间,当java垃圾回收机制对堆区进行资源回收后,那些新生代中没有被回收的资源将被转移到中生代,中生代的被转移到老生代。而接下来要讲述的三个参数是用来控制新生代内存大小的。
1、-XX:newSize:表示新生代初始内存的大小,应该小于 -Xms的值;
2、-XX:MaxnewSize:表示新生代可被分配的内存的最大上限;当然这个值应该小于 -Xmx的值;
3、-Xmn:至于这个参数则是对 -XX:newSize、-XX:MaxnewSize两个参数的同时配置,也就是说如果通过-Xmn来配置新生代的内存大小,那么-XX:newSize = -XX:MaxnewSize = -Xmn,虽然会很方便,但需要注意的是这个参数是在JDK1.4版本以后才使用的。
上面所述即为java虚拟机对外提供的可配置堆区的参数,接下来讲述java虚拟机对非堆区内存配置的两个参数:
1、-XX:PermSize:表示非堆区初始内存分配大小,其缩写为permanent size(持久化内存)
2、-XX:MaxPermSize:表示对非堆区分配的内存的最大上限。
这里面非常要注意的一点是:在配置之前一定要慎重的考虑一下自身软件所需要的非堆区内存大小,因为此处内存是不会被java垃圾回收机制进行处理的地方。并且更加要注意的是 最大堆内存与最大非堆内存的和绝对不能够超出操作系统的可用内存。

浙公网安备 33010602011771号