性能测试(23)——完整性能项目案例

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群版 2核4GB 100GB
推荐场景:
搭建个人博客
日志服务 SLS,月写入数据量 50GB 1个月
简介: 性能测试需求分析与传统的功能测试需求有所不同功能测试需求分析:重点在于分析被测系统的功能是否满足产品功能需求规格(正向、逆向)性能测试需求分析:重点在于分析被测系统是否能满足特定的业务需求场景(时间、资源) 需要从业务场景、程序代码、服务器、硬件配置等多个维度分析系统可能存在性能瓶颈

(一) 性能测试需求分析

  • 性能测试需求分析与传统的功能测试需求有所不同
  • 功能测试需求分析:重点在于分析被测系统的功能是否满足产品功能需求规格(正向、逆向)
  • 性能测试需求分析:重点在于分析被测系统是否能满足特定的业务需求场景(时间、资源) 需要从业务场景、程序代码、服务器、硬件配置等多个维度分析系统可能存在性能瓶颈

    1、获取有效的需求

    1、客户方提出
    能够提出明确需求的一般是金融、银行、电信、医疗等企业,他们一般对系统的性能要求高,并且对性能也非常了解
    2、根据历史数据分析
    通过分析历史运营数据收集用户信息,如:
    #注册用户数、日活、月活,计算用户的增长速度
    #每月、每周、每天的峰值业务量是多少
    #用户频繁使用的功能模块是哪些

    2、 性能测试点的提取

  1. 用户频繁使用的业务功能
  2. 非常关键的业务功能
  3. 特殊交易日或峰值交易的业务功能
  4. 核心业务发生重大调整的业务功能
  5. 资源占用非常高的业务功能

商城性能测试点的提取
image.png

3、 确定性能测试目标

性能测试目标包括:

  1. 确定核心业务功能的TPS
  2. 对业务流程(多接口组合)进行压测
  3. 系统能在实际系统运行压力的情况下,稳定的运行24小时

image.png

(二)制定性能测试计划

1、测试背景

商城是公司新开发的一个电商项目,为了保证项目上线后能够稳定的运行,且在后期推广中能够承受用户的增长,需要对项目 进行性能测试

2、测试目的

对新电商项目进行性能测试的核心目的包括:

  • 确定核心业务功能的TPS
  • 对业务流程(多接口组合)进行压测
  • 系统能在实际系统运行压力的情况下,稳定的运行24小时

    3、测试范围

    通过对性能测试需求的调研和分析,确定被测系统的测试范围如下
    image.png

    4、测试策略

    4.1 基准测试
    先做基准测试,确定估算的标准。
    4.2 负载测试
    通过逐步增加系统负载,测试系统性能的变化,并最终确定在满足系统的性能指标情况下,系统所能够承受的最大负载量的 测试。
    分别模拟5、10、30、50、100个用户对系统进行负载测试,查看不同并发时系统软件各项指标是否符合需求。
    4.3 稳定性测试

  • 用200用户对系统进行7*24小时的不间断稳定性测试,查看服务器日志内有无异常和报错;系统软件各项指标中间有无异常波动;是否存在内存溢出之类的问题。

  • 验证系统长期运行的稳定性以及是否存在内存溢出之类的问题

    5、风险控制

    image.png

    6、交付清单

    性能测试计划、测试脚本、性能缺陷统计和性能测试报告等。

    7、进度与分工

    image.png

(三)性能测试用例设计

image.png

(四)建立测试环境

在进行性能则试之前,需要先完成性能测试环境的搭建工作,测试环境一般包括硬件环境、软件环境及网络环境
一般情况下可以要求运维和开发工程师协助完成

  1. 性能测试环境的特点

性能测试对测试环境的独立性要求更高,更为严格
如果某环境下运行多个系统,就很难判断其中的某个环境对资源的占用情况

  1. 尽量保持性能测试环境与真实生产环境的一致性
  2. 如何保证测试环境与生产环境的一致性

硬件环境:
包括服务器环境、网络环境等
软件环境:
版本一致性:包括操作系统、数据库、被测应用程序、第三方软件等
配置一致性:包括操作系统、数据库、被测应用程序、第三方软件等
使用场景的一致性:
基础业务数据的一致性
业务操作模式的一致性:尽量模拟真实场景下用户的使用情况

  1. 构造测试数据

压测环境中的数据量尽量与生产环境中数据量一致,为了快速创建大量数据,可以直接操作数据库进行添加
案例:通过编写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配置信息

  1. 修改控制机jmeter.properties配置文件中的 remote_hosts=xx ,xx表示压力机的IP和端口,多个用英文逗号分隔
  2. 修改执行机jmeter.properties配置文件中的 server_port=1099 ,端口号要和控制机配置文件中保持一致
    2.3 启动执行机
    打开jmeter目录\bin\jmeter-server.bat文件进行启动
    2.4 启动控制机
    打开jmeter目录\bin\jmeter.bat,添加执行脚本,通过运行-->远程启动或者远程全部启动,即可启动对应执行机

    (六)性能测试监控

    性能测试监控关键指标

  3. 系统指标:系统指标则与用户场景及需求直接相关
    并发用户数:某一物理时刻同时向系统提交请求的用户数
    平均响应时间:系统处理事务的响应时间的平均值。对于系统快速响应类页面,一般响应时间为3秒左右
    吞吐量

  4. 服务器资源指标:资源指标与硬件资源消耗直接相关
    CPU使用率:一般可接受上限为85%
    内存利用率:一般可接受上限为85%
    磁盘I/O
    网络带宽
  5. Java应用:
    JVM监控:JVM内存、Full GC频率
  6. 数据库:
    慢查询
    缓存命中率
    数据池连接数
    mysql锁
  7. 压测机资源:
    CPU
    内存
    网络
    磁盘空间

性能监控工具
要对性能测试指标进行监控,可以使用系统自带的监控工具,也可以使用第三方监控工具或者监控平台。

  1. 系统指标:
    通过性能测试工具(如LoadRunner、JMeter等)以图形化方式监控
  2. 服务器资源指标:
    使用Jmeter性能监控插件PerfMon 进行监控
    使用Linux命令监控:top、free、vmstat、sar、iostat等
    Nmon:全面监控linux系统资源使用情况,包括CPU、内存、I/O等,可独立于应用监控。
  3. Java应用:
    jvisualvm
  4. 数据库
  5. 压测机资源:
    Windows自带“任务管理器”

image.png

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远程监控服务器

  1. 添加应用程序启动参数,并启动服务

    -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
    
  2. 进入本地jdk安装目录bin目录,找到jvisualvm.exe并启动

  3. 右键“远程”选择“添加远程主机”,并输入主机IP

image.png

  1. 右键主机选择“添加JMX连接”,并输入JMX端口

image.png

  1. 连接成功后在主机下会有对应的连接显示,双击查看监控信息

image.png
如下图可见,堆中的内存使用长时间内呈现上升状态,说明在创建新的内存堆时,没有及时释放掉旧的堆,导致资源释放远远小于新建,最后内存泄漏,程序崩溃。
image.png

(七)性能测试报告

性能测试报告模板.doc

相关实践学习
通过性能测试PTS对云服务器ECS进行规格选择与性能压测
本文为您介绍如何利用性能测试PTS对云服务器ECS进行规格选择与性能压测。
目录
相关文章
|
7天前
|
运维 Java 测试技术
Spring运维之boo项目表现层测试加载测试的专用配置属性以及在JUnit中启动web服务器发送虚拟请求
Spring运维之boo项目表现层测试加载测试的专用配置属性以及在JUnit中启动web服务器发送虚拟请求
13 3
|
28天前
|
测试技术 UED
课题项目结题测试通常会采用的方法
课题项目结题测试确保项目准确稳定,涉及功能测试、性能测试、安全测试、兼容性测试、用户验收测试及文档审查。这些方法全面评估项目各方面,保证顺利交付和使用,同时促进项目改进。标签:结题测试、软件测试报告。
课题项目结题测试通常会采用的方法
|
11天前
|
SQL 安全 Java
探索软件测试的多维策略:从单元到集成,再到性能与安全
在软件开发过程中,测试是确保产品质量和用户满意度的关键步骤。本文将深入探讨软件测试的多维策略,包括单元测试、集成测试、性能测试和安全测试。我们将分析每种测试方法的优势和局限性,并讨论如何将这些策略整合到一个全面的测试计划中,以提高软件的可靠性和安全性。文章还将提供实用的例子和最佳实践,帮助读者更好地理解和应用这些测试技术。
|
19天前
|
编译器 测试技术 Linux
技术洞察:循环语句细微差异下的性能探索(测试while(u--);和while(u)u--;的区别)
该文探讨了两种循环语句(`while(u--);` vs. `while(u) u--;`)在性能上的微妙差异。通过实验发现,后者比前者平均执行速度快约20%,原因在于循环条件检查的顺序影响了指令数量。尽管差异可能在多数情况下不显著,但在性能关键的代码中,选择合适的循环结构能优化执行效率。建议开发者在编写循环时考虑编译器优化和效率。未来研究可扩展到不同编译器、优化级别及硬件架构的影响。
|
19天前
|
算法 Linux 测试技术
Linux编程:测试-高效内存复制与随机数生成的性能
该文探讨了软件工程中的性能优化,重点关注内存复制和随机数生成。文章通过测试指出,`g_memmove`在内存复制中表现出显著优势,比简单for循环快约32倍。在随机数生成方面,`GRand`库在1000万次循环中的效率超过传统`rand()`。文中提供了测试代码和Makefile,建议在性能关键场景中使用`memcpy`、`g_memmove`以及高效的随机数生成库。
|
2天前
|
关系型数据库 MySQL 测试技术
《阿里云产品四月刊》—瑶池数据库微课堂|RDS MySQL 经济版 vs 自建 MySQL 性能压测与性价比分析
阿里云瑶池数据库云原生化和一体化产品能力升级,多款产品更新迭代
|
27天前
|
安全 测试技术
软件测试项目式学习二(认识软件测试及软件测试分类与案例分析)
软件测试项目式学习二(认识软件测试及软件测试分类与案例分析)
25 1
|
27天前
|
NoSQL 关系型数据库 MySQL
软件测试之【基于开源商城系统fecmall功能测试项目实例】
软件测试之【基于开源商城系统fecmall功能测试项目实例】
54 0
软件测试之【基于开源商城系统fecmall功能测试项目实例】
|
24天前
|
Java
JavaSE——集合框架二(6/6)-(案例)补充知识:集合的嵌套(需求与分析、问题解决、运行测试)
JavaSE——集合框架二(6/6)-(案例)补充知识:集合的嵌套(需求与分析、问题解决、运行测试)
59 0
|
24天前
|
XML Java 测试技术
Maven 构建 & 项目测试
在本节中,我们学习了如何使用Maven构建和测试Java应用。在`C:/MVN/consumerBanking`项目中,`pom.xml`配置了JUnit为测试框架。通过命令行运行`mvn clean package`,Maven执行清理、编译、运行测试和打包成`consumerBanking-1.0-SNAPSHOT.jar`。测试报告位于`target/surefire-reports`。新增`Util.java`类后,更新`App.java`以调用它。执行`mvn clean compile`后,运行结果显示&quot;Hello World!&quot;。