常听人说并发量高达多少多少,这个值是怎么测的?
前言
近期即将上线一个在线考试类的系统,由于甲方客户比较重视此次考试,所以各种准备工作也要做足。故此对线上系统做了一次比较全面的压力测试,也是通过这次测试,验证了之前的很多想法,自感收获颇丰,故留此文。
准备测试用例
正常来说,待测用例可能是接口,也可能是页面,或者是一连串的操作动作,比如先登录,再浏览某页面,再提交某表单等等。具体情况不同,准备用例的复杂程度也有区分。我这里就是准备了几个接口,然后把接口里实现了一些模拟真实情况的操作,这样准备的用例就会很简单。概括一下就是,数据库读,缓存读,数据库写,数据库更新 4 个操作
具体代码就不贴了,都是些业务操作,只简单贴一下接口名和一些接口配置
注意,我把这几个接口的访问级别设定成了不需要验证即可访问,一是为了方便,二是由于我们的用户中心是隔离出去的,也是为了避免多个系统的影响,直接测试本系统性能。
搭建 JMeter 分布式压测环境
Why?
JMeter 不用多介绍,官方文档在这里👉:https://jmeter.apache.org/,目前最新版本是 5.5。
之所以要搭建分布式的压测环境,主要还是想最大限度的模拟真实情况,因为 JMeter 是用 Java 语言编写的,对资源的消耗不算低,单机能模拟的最高 UVs 是有上限的,设定的值太高软件自身就会崩溃。为了解决这个问题,JMeter 官方提供了分布式部署的解决方案。
准备依赖环境
JMeter 必备的依赖环境就是 JDK,但由于 JDK1.8 以后的版本商用会有一定的风险,所以我这里使用的版本是微软构建的 OpenJDK 17 这里呢,微软也为用户提供了详细的安装手册,包含市面上几乎所有的主流系统,地址在这里👉:https://learn.microsoft.com/zh-cn/java/openjdk/install
我这里是 CentOS 环境和 Windows 环境,安装好后的截图如下
注意,所有终端机器的 jdk 版本要保持一致!
下载 JMeter
到官方网站下载最新版本的 JMeter,目前是 5.5,地址👉:https://jmeter.apache.org/download_jmeter.cgi具体下载过程不再细说,centos 可用 wget,也可以在 windows 下载好后通过熟悉的 GUI 工具上传到 Linux 环境
配置压力机
我这里是把 2 台 CentOS 机器配置成了压力机(Slave),配置过程如下进入 bin 目录,打开 jmeter.properties 文件分别查找并修改以下几个参数
language:放开注释并设置成 zh_CN,这个不是必须的,这样操作后,用到 GUI 界面的时候会显示中文。
remote_hosts:修改为当前压力机 ip 地址+端口,端口默认是 1099,可以改成任意未被占用的端口
server_port:跟随上面的端口设置,注释或者不设置则未 1099
server.rmi.localport:跟随上面端口设置,这个需要放开注释
server.rmi.ssl.disable:为了方便设置成 true 即可,
若考虑安全因素,可到 bin 目录下找到‘create-rmi-keystore.bat’或者‘create-rmi-keystore.sh’文件,以 bat 文件为例,拷贝该文件到 jdk 的 bin 目录下,执行该文件,根据控制台提示,输入完成后会得到一个 rmi_keystore.jks 文件,把这个文件拷贝到所有压力机和控制机上。
我这里为了方便,就直接把 server.rmi.ssl.disable 设置成了 true。最后我这里的压力机主要配置如下,2 台配置除了 ip 都一样
配置完成后,我这里的压力机还要对 jmeter-server 文件修改下执行权限
然后修改 jmeter-server 文件放开 RMI_HOST_DEF 参数的注释,并修改 hostname 为本机 ip(所有 slave 压力机都要修改)
到这里,就可以执行压力机上的服务节点了
注意:由于数据传输问题,slave 机和 master 机的传输,需要把防火墙关闭掉,这个算是个坑把,开始我以为只放开端口就可以了,但后来数据回传一直有问题,就直接把整个防火墙关掉了,然后问题就解决了。
这个不知道是不是 JMeter 的问题,还是说有其他的解决方案。但不管怎么说关闭防火墙是一个非常危险的操作,非内网安全环境下,谨慎操作!
关闭命令如下
systemctl stop firewalld.service
解决到数据传输的问题后,进入 bin 目录启动服务
出现如下界面即为成功。
这里,还要注意,为了尽可能提高单台压力机的压测性能上限,可以把默认的 jvm 内存限制调高,这里根据官方文档的建议,增加 setenv.sh 文件(Windows 是 sentenv.bat)写入下面代码即可
这里具体的解释可以参照官网介绍,进入该地址:https://jmeter.apache.org/usermanual/get-started.html,搜索 jvm 关键字即可
配置控制机
控制机建议在一台熟悉且方便的系统环境上配置,我这里用的 Windows,配置内容和压力机略有不同进入 bin 目录,打开 jmeter.properties 文件
remote_hosts:配置为所有压力机的 ip+端口
server.rmi.ssl.disable:配置为 true,注意事项跟压力机配置部分描述的内容相同
因为控制机不承担压测任务,只配置好这些参数,其他保持默认就好
控制机也可以作为压力机和 slave 节点一起工作,配置上就放开端口,并把当前 ip 配置到 remote_hosts 上即可
准备压测配置文件
这里有多种方式配置,可以在控制机上启动 GUI,设置好接口,监视器等,然后保存为 jmx 文件;也可以依托一些第三方的工具,比如 ApiFox,配置好测试场景后,就可以在性能测试窗口,直接导出配置文件。
JMeter GUI 配置界面如下
ApiFox 的配置界面如下
这部分也不多介绍了,最后生成的文件就是一个 xml 风格的 jmx 文件~长这样👇
开始压力测试
注意,正式压力测试的时候就不能用 GUI 模式了。
上面的流程配置完成后,执行压力测试就非常简单了,我这里写了一个 bat 文件,供参考我这里在 jmeter 根目录下新建了个 result 文件夹,然后把 jmx 测试文件和下面这个可执行文件放到一起
执行 bat 文件后,正常情况下可以在控制机上看到下面信息
对应的压力机上
根据我们设定的压测参数,包括持续时长,线程数(UVs),ramp-up 等,待程序执行完成后,会在我们设定的地址生成(在上面的 bat 文件里有配置)一个报告目录,然后点击 index.html,就可以查看压测的数据报告了
至此,分布式压测的环境搭建和执行环节就结束了。
后续我们就可以动态的调整参数,进行不同参数条件下的压力测试了。
比如,单机负载下, 最大可以有多大并发,双机,多机呢?
再比如,对照不同部署环境,比如 apache,iis,kestrel,nginx
这里多说一句,我这里实测了 iis 和 kestrel 两种情况,iis 真的是渣!
再比如,对照增加缓存和不增加缓存的情况
再比如,数据库单机,数据库集群的情况等等
得到了每次测试的图表数据之后,就对各个项目进行分析,比如响应时长(RT),吞吐量(QPS),每秒接收流量,发送流量,样本量等各项数据指标,就像看体检报告单。
通过一轮轮的测试,可以慢慢找到我们系统的性能瓶颈,除了帮助我们优化系统,优化硬件配置,还可以额给到用户一个可靠的,客观的并发承载规模,避免扯皮。
总而言之,压力测试在一些直接 ToC,或者用户规模相对较高的却又不好估量的场景,是非常必要的一个环节!
附加推荐
最后,想在介绍几款 SaaS 类的压测工具。
当我们手头上没有压力机资源,或者准备资源不是很方便的时候,就可以考虑一些第三方的 SaaS 类工具。比如阿里云,腾讯云这些大厂,他们都提供了压测类的性能测试工具,而且有具体的操作文档(我在自己搞压测的时候,就经常看他们的文档,一是看看他们的工具怎么用,更主要的是学习压测类的知识,毕竟咱也不是专业测试~哈哈)。
我个人用过腾讯云的云压测产品,整体来说还是非常好用的,关键它支持直接导入 jmx 配置文件,更加方便。图表什么的也比 jmeter 自己生成的要丰富,而且新用户赠送 2 万 UVs 额度,推荐大家试一试,传送门👉:https://cloud.tencent.com/act/cps/redirect?redirect=36087&cps_key=d30dc71682a3d05b5b23f0925ba51d98
除了腾讯云的云压测,上面提到的APIFox也提供压力测试能力,界面非常酷。
还有一个国产做的非常不错的压测工具,RunnerGo,他的底层是用 go 语言实现的,我试了一下也非常不错,可以自定义各种测试场景,增加了一些控制机制,更加贴近真实,也推荐大家去尝试一下。
版权声明: 本文为 InfoQ 作者【为自己带盐】的原创文章。
原文链接:【http://xie.infoq.cn/article/9c156894b7374e1bd9bc6271f】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论