常听人说并发量高达多少多少,这个值是怎么测的?

前言

近期即将上线一个在线考试类的系统,由于甲方客户比较重视此次考试,所以各种准备工作也要做足。故此对线上系统做了一次比较全面的压力测试,也是通过这次测试,验证了之前的很多想法,自感收获颇丰,故留此文。

准备测试用例

正常来说,待测用例可能是接口,也可能是页面,或者是一连串的操作动作,比如先登录,再浏览某页面,再提交某表单等等。具体情况不同,准备用例的复杂程度也有区分。我这里就是准备了几个接口,然后把接口里实现了一些模拟真实情况的操作,这样准备的用例就会很简单。

概括一下就是,数据库读,缓存读,数据库写,数据库更新 4 个操作

具体代码就不贴了,都是些业务操作,只简单贴一下接口名和一些接口配置

#region 性能压力测试相关接口,模拟考试各种动作

        /// <summary>
        /// 模拟获取考试列表,并缓存
        /// </summary>
        /// <param name="associationId"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [ResponseCache(Duration = 100)]
        public async Task<IActionResult> TestGetExaminations(string token)
        {
            //业务动作
		}

        /// <summary>
        /// 模拟验证身份接口
        /// 这里只验证接口访问情况,故将所有情况返回值都设定为code=1
        /// </summary>
        /// <returns></returns>
        [AllowAnonymous]
        public async Task<IActionResult> TestInfoVerification(string token,string testExamId="",string testIdNumber="")
        {
            //业务动作
        }

        /// <summary>
        /// 模拟抽卷,
        /// 这里不实际抽题,执行一个相对的耗时插入操作,并标记为删除
        /// </summary>
        /// <returns></returns>
        [AllowAnonymous,HttpPost]
        public async Task<IActionResult> TestConfirmMyPaper(string token)
        {
            //业务动作
        }

        /// <summary>
        /// 模拟提交答题
        /// </summary>
        /// <returns></returns>
        [AllowAnonymous, HttpPost]
        public async Task<IActionResult> TestSubmitPaper(string token)
        {
            //业务动作
        }
        #endregion

注意,我把这几个接口的访问级别设定成了不需要验证即可访问,一是为了方便,二是由于我们的用户中心是隔离出去的,也是为了避免多个系统的影响,直接测试本系统性能。

搭建 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 都一样 

#...其他配置

remote_hosts=10.185.1.178:1029
server_port=1029
server.rmi.localport=1029
server.rmi.ssl.disable=true

#...其他配置

 配置完成后,我这里的压力机还要对 jmeter-server 文件修改下执行权限

chmod 777 jmeter-server

然后修改 jmeter-server 文件放开 RMI_HOST_DEF 参数的注释,并修改 hostname 为本机 ip(所有 slave 压力机都要修改)


DIRNAME=`dirname $0`

# If the client fails with:
# ERROR - jmeter.engine.ClientJMeterEngine: java.rmi.ConnectException: Connection refused to host: 127.0.0.1
# then it may be due to the server host returning 127.0.0.1 as its address

# One way to fix this is to define RMI_HOST_DEF below
RMI_HOST_DEF=-Djava.rmi.server.hostname=10.185.1.176

${DIRNAME}/jmeter ${RMI_HOST_DEF} -Dserver_port=${SERVER_PORT:-1099} -s -j jmeter-server.log "$@"

到这里,就可以执行压力机上的服务节点了

注意:由于数据传输问题,slave 机和 master 机的传输,需要把防火墙关闭掉,这个算是个坑把,开始我以为只放开端口就可以了,但后来数据回传一直有问题,就直接把整个防火墙关掉了,然后问题就解决了。

这个不知道是不是 JMeter 的问题,还是说有其他的解决方案。但不管怎么说关闭防火墙是一个非常危险的操作,非内网安全环境下,谨慎操作!

关闭命令如下

systemctl stop firewalld.service

解决到数据传输的问题后,进入 bin 目录启动服务

./jmeter-server

出现如下界面即为成功。

这里,还要注意,为了尽可能提高单台压力机的压测性能上限,可以把默认的 jvm 内存限制调高,这里根据官方文档的建议,增加 setenv.sh 文件(Windows 是 sentenv.bat)写入下面代码即可

export JVM_ARGS="-Xms1G -Xmx1G -XX:MaxMetaspaceSize=192m"
# 默认是 -Xms256m -Xmx256m -XX:MaxMetaspaceSize=256m

这里具体的解释可以参照官网介绍,进入该地址: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 文件~长这样👇

开始压力测试

上面的流程配置完成后,执行压力测试就非常简单了,我这里写了一个 bat 文件,供参考我这里在 jmeter 根目录下新建了个 result 文件夹,然后把 jmx 测试文件和下面这个可执行文件放到一起

@echo off
cd /d %~dp0
call ..\bin\jmeter.bat -n -t exam.jmx -r -l testResult%date:~0,4%%date:~5,2%%date:~8,2%%time:~0,2%%time:~3,2%.jtl -e -o ResultReport_%date:~0,4%%date:~5,2%%date:~8,2%%time:~0,2%%time:~3,2%
echo %date:~0,4%%date:~5,2%%date:~8,2%%time:~0,2%%time:~3,2%%time:~6,2% jmeter ok! >> log.txt

 执行 bat 文件后,正常情况下可以在控制机上看到下面信息

 对应的压力机上

 根据我们设定的压测参数,包括持续时长,线程数(UVs),ramp-up 等,待程序执行完成后,会在我们设定的地址生成(在上面的 bat 文件里有配置)一个报告目录,然后点击 index.html,就可以查看压测的数据报告了

至此,分布式压测的环境搭建和执行环节就结束了。

后续我们就可以动态的调整参数,进行不同参数条件下的压力测试了。

比如,单机负载下, 最大可以有多大并发,双机,多机呢?

再比如,对照不同部署环境,比如 apache,iis,kestrel,nginx

这里多说一句,我这里实测了 iis 和 kestrel 两种情况,iis 真的是渣!

再比如,对照增加缓存和不增加缓存的情况

再比如,数据库单机,数据库集群的情况等等

得到了每次测试的图表数据之后,就对各个项目进行分析,比如响应时长(RT),吞吐量(QPS),每秒接收流量,发送流量,样本量等各项数据指标,就像看体检报告单。

通过一轮轮的测试,可以慢慢找到我们系统的性能瓶颈,除了帮助我们优化系统,优化硬件配置,还可以额给到用户一个可靠的,客观的并发承载规模,避免扯皮。

总而言之,压力测试在一些直接 ToC,或者用户规模相对较高的却又不好估量的场景,是非常必要的一个环节!

附加推荐

最后,想在介绍几款SaaS 类的压测工具。

当我们手头上没有压力机资源,或者准备资源不是很方便的时候,就可以考虑一些第三方的SaaS类工具。比如阿里云,腾讯云这些大厂,他们都提供了压测类的性能测试工具,而且有具体的操作文档(我在自己搞压测的时候,就经常看他们的文档,一是看看他们的工具怎么用,更主要的是学习压测类的知识,毕竟咱也不是专业测试~哈哈)。

我个人用过腾讯云的云压测产品,整体来说还是非常好用的,关键它支持直接导入jmx配置文件,更加方便。图表什么的也比jmeter自己生成的要丰富,而且新用户赠送2万UVs额度,推荐大家试一试,传送门👉:腾讯云运营活动 - 腾讯云

除了腾讯云的云压测,上面提到的APIFox也提供压力测试能力,界面非常酷。

还有一个国产做的非常不错的压测工具,RunnerGo,他的底层是用go语言实现的,我试了一下也非常不错,可以自定义各种测试场景,增加了一些控制机制,更加贴近真实,也推荐大家去尝试一下。

同步转发于infoq:高并发高并发,多高算高?这个值是怎么来的?_Jmeter_为自己带盐_InfoQ写作社区

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

为自己_带盐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值