(一) 性能测试需求分析
- 性能测试需求分析与传统的功能测试需求有所不同
- 功能测试需求分析:重点在于分析被测系统的功能是否满足产品功能需求规格(正向、逆向)
- 性能测试需求分析:重点在于分析被测系统是否能满足特定的业务需求场景(时间、资源) 需要从业务场景、程序代码、服务器、硬件配置等多个维度分析系统可能存在性能瓶颈
1、获取有效的需求
1、客户方提出
能够提出明确需求的一般是金融、银行、电信、医疗等企业,他们一般对系统的性能要求高,并且对性能也非常了解
2、根据历史数据分析
通过分析历史运营数据收集用户信息,如:
#注册用户数、日活、月活,计算用户的增长速度
#每月、每周、每天的峰值业务量是多少
#用户频繁使用的功能模块是哪些2、 性能测试点的提取
- 用户频繁使用的业务功能
- 非常关键的业务功能
- 特殊交易日或峰值交易的业务功能
- 核心业务发生重大调整的业务功能
- 资源占用非常高的业务功能
3、 确定性能测试目标
性能测试目标包括:
- 确定核心业务功能的TPS
- 对业务流程(多接口组合)进行压测
- 系统能在实际系统运行压力的情况下,稳定的运行24小时
(二)制定性能测试计划
1、测试背景
商城是公司新开发的一个电商项目,为了保证项目上线后能够稳定的运行,且在后期推广中能够承受用户的增长,需要对项目 进行性能测试
2、测试目的
对新电商项目进行性能测试的核心目的包括:
- 确定核心业务功能的TPS
- 对业务流程(多接口组合)进行压测
-
3、测试范围
4、测试策略
4.1 基准测试
先做基准测试,确定估算的标准。
4.2 负载测试
通过逐步增加系统负载,测试系统性能的变化,并最终确定在满足系统的性能指标情况下,系统所能够承受的最大负载量的 测试。
分别模拟5、10、30、50、100个用户对系统进行负载测试,查看不同并发时系统软件各项指标是否符合需求。
4.3 稳定性测试 用200用户对系统进行7*24小时的不间断稳定性测试,查看服务器日志内有无异常和报错;系统软件各项指标中间有无异常波动;是否存在内存溢出之类的问题。
- 验证系统长期运行的稳定性以及是否存在内存溢出之类的问题
5、风险控制
6、交付清单
性能测试计划、测试脚本、性能缺陷统计和性能测试报告等。7、进度与分工
(三)性能测试用例设计
(四)建立测试环境
在进行性能则试之前,需要先完成性能测试环境的搭建工作,测试环境一般包括硬件环境、软件环境及网络环境
一般情况下可以要求运维和开发工程师协助完成
- 性能测试环境的特点
性能测试对测试环境的独立性要求更高,更为严格
如果某环境下运行多个系统,就很难判断其中的某个环境对资源的占用情况
- 尽量保持性能测试环境与真实生产环境的一致性
- 如何保证测试环境与生产环境的一致性
硬件环境:
包括服务器环境、网络环境等
软件环境:
版本一致性:包括操作系统、数据库、被测应用程序、第三方软件等
配置一致性:包括操作系统、数据库、被测应用程序、第三方软件等
使用场景的一致性:
基础业务数据的一致性
业务操作模式的一致性:尽量模拟真实场景下用户的使用情况
- 构造测试数据
压测环境中的数据量尽量与生产环境中数据量一致,为了快速创建大量数据,可以直接操作数据库进行添加
案例:通过编写Python脚本,构造10万条商品记录
import pymysql
conn = pymysql.connect(host="127.0.0.1", user="litemall", password="litemall123456", database="litemall", port=3306)
cursor = conn.cursor()
goods_sql = """
INSERT INTO `litemall_goods` (`id`, `goods_sn`, `name`, `category_id`, `brand_id`, `gallery`,
`keywords`, `brief`, `is_on_sale`, `sort_order`, `pic_url`, `share_url`, `is_new`, `is_hot`, `unit`,
`counter_price`, `retail_price`, `detail`, `add_time`, `update_time`, `deleted`)
VALUES ('{}', '{}', '小米手机-{}', '1008016', '1001000', '[\"http://182.92.81.159:8080/wx/storage/fetch/0b5lpf15ee8c6o10vkd8.jpg\",\
"http://182.92.81.159:8080/wx/storage/fetch/ykaptr4vntbofoi9l2f5.jpg\",\"http://182.92.81.159:8080/wx/storage/fetch/u5zc8sp2t4f9y9uw
n179.jpg\"]',
'手机,Android', '小米10 双模5G 骁龙865 1亿像素8K电影相机', '1', '100', 'http://182.92.81.159:8080/wx/storage/fetch/re5jul69plklzusso97
t.png', '', '1', '0', '个', '100.00', '99.00', '<p>小米10 双模5G 骁龙865 1亿像素8K电影相机 对称式立体声 8GB+256GB 冰海蓝 拍照智能游戏手机
!!!!!!!!!!</p>',
'2020-03-11 14:19:50', '2020-03-26 14:55:58', '0');
"""
goods_attr_sql = """
INSERT INTO `litemall_goods_attribute` (`goods_id`, `attribute`, `value`, `add_time`, `update_time`, `deleted`)
VALUES
('{}', '产地', '中国山东', '2018-10-26 21:27:13', '2018-10-26 21:27:13', '0'),
('{}', '尺寸', '200*230cm/ 220*240cm', '2018-10-26 21:27:13', '2018-10-26 21:27:13', '0'),
('{}', '颜色', '条纹绿格', '2018-10-26 21:27:13', '2018-10-26 21:27:13', '0'),
('{}', '执行标准', 'GB/T 22844-2009', '2018-10-26 21:27:13', '2018-10-26 21:27:13', '0');
"""
goods_product_sql = """
INSERT INTO `litemall_goods_product` (`goods_id`, `specifications`, `price`, `number`, `url`, `add_time`, `update_time`, `deleted`)
VALUES ('{}', '[\"标准\"]', '999.00', '1000', 'http://182.92.81.159:8080/wx/storage/fetch/o4531ja3h9sgq5ib32f4.jpg', '2020-03-11 14:
19:50', '2020-03-11 14:19:50', '0');
"""
goods_spec_sql = """
INSERT INTO `litemall_goods_specification` (`goods_id`, `specification`, `value`, `pic_url`, `add_time`, `update_time`, `deleted`)
VALUES ('{}', '规格', '标准', '', '2020-03-11 14:19:50', '2020-03-11 14:19:50', '0');
"""
goods_id_start = 200000
for i in range(100000):
# 商品
goods_id = goods_id_start + i
print("i={} goods_id={}".format(i, goods_id))
sql = goods_sql.format(goods_id, goods_id, goods_id)
cursor.execute(sql)
# 商品参数
sql = goods_attr_sql.format(goods_id, goods_id, goods_id, goods_id)
cursor.execute(sql)
# 商品货品
sql = goods_product_sql.format(goods_id)
cursor.execute(sql)
# 商品规格表
sql = goods_spec_sql.format(goods_id)
cursor.execute(sql)
conn.commit()
cursor.close()
conn.close()
(五)执行测试脚本
先保证脚本调试通过之后,才能进入正式压测阶段。
分布式执行
如果单台压测机的并发量不能够满足要求,则可以通过分布式压测来提高并发量。 JMeter工具支持分布式压测,即多台机器同时执行同一个脚本,然后统计结果。
分布式压测条件
分布式压测,机器分为控制机和执行机,有几个条件必须满足:
执行机和控制机必须在同一个网段之内
压测机也必须安装相同版本的JMeter和JDK
修改JMeter配置信息
- 修改控制机jmeter.properties配置文件中的 remote_hosts=xx ,xx表示压力机的IP和端口,多个用英文逗号分隔
修改执行机jmeter.properties配置文件中的 server_port=1099 ,端口号要和控制机配置文件中保持一致
2.3 启动执行机
打开jmeter目录\bin\jmeter-server.bat文件进行启动
2.4 启动控制机
打开jmeter目录\bin\jmeter.bat,添加执行脚本,通过运行-->远程启动或者远程全部启动,即可启动对应执行机(六)性能测试监控
性能测试监控关键指标
系统指标:系统指标则与用户场景及需求直接相关
并发用户数:某一物理时刻同时向系统提交请求的用户数
平均响应时间:系统处理事务的响应时间的平均值。对于系统快速响应类页面,一般响应时间为3秒左右
吞吐量- 服务器资源指标:资源指标与硬件资源消耗直接相关
CPU使用率:一般可接受上限为85%
内存利用率:一般可接受上限为85%
磁盘I/O
网络带宽 - Java应用:
JVM监控:JVM内存、Full GC频率 - 数据库:
慢查询
缓存命中率
数据池连接数
mysql锁 - 压测机资源:
CPU
内存
网络
磁盘空间
性能监控工具
要对性能测试指标进行监控,可以使用系统自带的监控工具,也可以使用第三方监控工具或者监控平台。
- 系统指标:
通过性能测试工具(如LoadRunner、JMeter等)以图形化方式监控 - 服务器资源指标:
使用Jmeter性能监控插件PerfMon 进行监控
使用Linux命令监控:top、free、vmstat、sar、iostat等
Nmon:全面监控linux系统资源使用情况,包括CPU、内存、I/O等,可独立于应用监控。 - Java应用:
jvisualvm - 数据库
- 压测机资源:
Windows自带“任务管理器”
1、MySQL监控
慢查询SQL
慢查询:指执行速度低于设置的阀值的SQL语句
作用:帮助定位查询速度较慢的SQL语句,方便更好的优化数据库系统的性能
开启MySQL慢查询日志
参数说明:
slow_query_log: 慢查询日志开启状态[ON:开启,OFF:关闭]
slow_query_log_file: 慢查询日志存放位置
long_query_time: 慢查询时长设置(超过该时长才会被记录,单位:秒)
mysql> show variables like 'slow_query%';
+---------------------+---------------------------------------------------+
| Variable_name | Value |
+---------------------+---------------------------------------------------+
| slow_query_log | OFF |
| slow_query_log_file | /var/lib/mysql/iZ2ze6id2tww1o2zn0mznxZ-slow.log |
+---------------------+---------------------------------------------------+
2 rows in set
mysql> show variables like 'long_query_time';
+-----------------+-----------+
| Variable_name | Value |
+-----------------+-----------+
| long_query_time | 10.000000 |
+-----------------+-----
# 开启慢查询日志
mysql> set global slow_query_log='ON';
# 设置慢查询日志存放位置
mysql> set global slow_query_log_file='/data/slow_query.log';
# 设置慢查询时间标准,设置之后会在下次会话才生效
mysql> set global long_query_time=1;
2、JVM监控
使用本地jvisualvm远程监控服务器
添加应用程序启动参数,并启动服务
-Dcom.sun.management.jmxremote -Djava.rmi.server.hostname=182.92.81.159 -Dcom.sun.management.jmxremote.port=10086 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false
进入本地jdk安装目录bin目录,找到jvisualvm.exe并启动
- 右键“远程”选择“添加远程主机”,并输入主机IP
- 右键主机选择“添加JMX连接”,并输入JMX端口
- 连接成功后在主机下会有对应的连接显示,双击查看监控信息
如下图可见,堆中的内存使用长时间内呈现上升状态,说明在创建新的内存堆时,没有及时释放掉旧的堆,导致资源释放远远小于新建,最后内存泄漏,程序崩溃。