阿里巴巴在开源压测工具 JMeter 上的实践和优化

简介:Apache JMeter 是 Apach 旗下的开源压测工具,创建于 1999 年初,迄今已有超过 20 年历史。JMeter 功能丰富,社区(用户群体)庞大,是主流开源压测工具之一。

作者:灵苒、涧泉

Apache JMeter[1] 是 Apach 旗下的开源压测工具,创建于 1999 年初,迄今已有超过 20 年历史。JMeter 功能丰富,社区(用户群体)庞大,是主流开源压测工具之一。

性能测试通常集中在新系统上线或大型活动前(如电商大促,春节活动等),以验证系统能力,帮助排查定位性能瓶颈等问题。

一次压测活动可粗略分为几个步骤:

  1. 场景配置。配置压测场景模拟用户(业务)与系统的交互。
  2. 压测执行。按指定压力量级启动压测。
  3. 压测监控分析。压测中通常关注施压 RPS,成功率,业务响应时间(RT),网络带宽等关键指标。
  4. 报告总结。披露系统能力是否符合要求,同时沉淀记录系统性能演变和优化过程。

原生 JMeter 实施压测

在 JMeter 的 GUI 页面编辑压测脚本,点击开始按钮调试 JMeter 脚本,具体操作可参考 JMeter官网[1]

对于场景简单,要求测试并发量不高的情况下,JMeter 本地测试就能满足需求。但随着互联网用户的增加,对系统承载更大并发的需求日渐提升,而单台 JMeter 施压机的施压能力有一定上限,所以需要使用多台施压机,以提高 JMeter 的施压能力,这就要使用到 JMeter 的分布式施压功能。

JMeter 的分布式压测需要用户自己管理维护多台机器,使用过程中注意以下几点:

  • 施压机的防火墙已关闭或打开了正确的端口。为 RMI 设置了 SSL 或禁用了它。
  • 所有施压机都在同一个子网上。如果使用 192.xxx 或 10.xxx IP 地址,则服务器位于同一子网中。
  • 所有施压机上使用相同版本的 JMeter 和 Java。
  • 所有施压机都已经拷贝了切分好的 CSV 数据文件、依赖 jar 包等。
  • 压测过程中需要监控施压机是否正常发流量,保持压力与配置一致。
  • 施压前配置好监控数据的收集,方便压测结束后报告的生成。

由此可见 JMeter 的分布式压测需要协调各资源,前置准备以及施压过程维护施压引擎比较麻烦,对实施压测的人员来说压测效率低。

云上的 JMeter 实践

阿里巴巴有着非常丰富的业务形态,每一种业务形态背后都由一系列分布式的技术体系提供服务,随着业务的快速发展,特别是在双 11 等大促营销等活动场景下,准确评估整个业务站点的服务能力成为一大技术难题。

在这个过程中,我们打造了自己的全链路压测系统,以应对更复杂、更多样的压测需求,并将此技术输出到 性能测试 PTS 上,同时支持原生 JMeter 压测。

通过控制台实践 JMeter

上传脚本

打开 PTS 控制台[2] 主页,左侧导航栏选择压测中心 > 创建场景 > JMeter 压测 ,新建 JMeter 压测场景。填写场景名,如 jmeter-test 。场景配置页面点击上传文件按钮,上传本地测试通过的 test.jmx 脚本。

施压配置

施压配置 页面,并发数设置为 50,压测时长设置为 2 分钟。

保存压测

点击保存去压测,弹出提示框点击确认,PTS 即开始在云端引擎执行 JMeter 脚本发起压力。

压测中页面如下:

注意:因为机器配置和网络环境的差异(PTS 施压机默认为 4 核 8G,BGP 多线路公网),PTS 上压测结果可能与本地压测结果存在一定差异。另外,PTS 上的施压配置会覆盖原脚本中的配置,原脚本无论是写死固定配置还是使用 JMeter 属性配置都没关系。

通过 OpenAPI 实践 JMeter

云计算会发展成像水电煤一样,成为社会的基础设施。OpenAPI 好比一条条快速管道,连接着企业和阿里云,把资源源源不断的输送给企业。使用云计算来构建 IT 基础设施是未来的发展趋势,这一点已经成为社会共识。OpenAPI 是云服务开放的重要窗口,没有 OpenAPI 的云服务将很难被客户的系统所集成,既影响了用户体验,也制约了云厂商本身的发展。同样的,在压测领域,随着压测需求日益多样化,更多用户希望将云上的压测能力继承到自己的系统,或者根据自己的业务系统,编排自定义的压测平台,从而实现自动化定制化压测需求。

以下代码实现了使用 PTS 的 OpenAPI 一键启动 JMeter 压测场景,并且在完成压测后查看压测报告。

引入 pom 依赖

<!--创建PTS场景需要的实体类,如果只使用JMeter压测则不需要引入-->
<dependency><groupId>com.aliyun</groupId><artifactId>pts-api-entity</artifactId><version>1.0.1</version>
</dependency>
<!--PTS Java SDK依赖。-->
<dependency><groupId>com.aliyun</groupId><artifactId>pts20201020</artifactId><version>1.8.10</version>
</dependency>
<!--阿里云核心库。-->
<dependency><groupId>com.aliyun</groupId><artifactId>aliyun-java-sdk-core</artifactId><version>4.5.2</version>
</dependency>

复制下列代码

import com.aliyun.pts20201020.Client;
import com.aliyun.pts20201020.models.*;
import com.aliyun.teaopenapi.models.Config;import java.util.ArrayList;
import java.util.List;
import java.util.Map;public class StartingDemo {public static void main(String[] args) throws Exception {Client client = getClient();// 创建场景String sceneId = createScene(client);// 启动场景String reportId = startTesting(client, sceneId);// 最多等待次数int count = 0;// 查询是否已生成报告while (!hasReport(client, reportId) && count++ < 20) {// 若报告还未生成,则等待(30s)一段时间再查询// 根据压测时间酌情等待Thread.sleep(30 * 1000);}// 查看报告getJMeterReport(client, reportId);}private static boolean hasReport(Client client, String reportId) throws Exception {ListJMeterReportsRequest request = new ListJMeterReportsRequest();// 分页设置request.setPageNumber(1);request.setPageSize(1);// 查询条件设置request.setReportId(reportId);ListJMeterReportsResponse response = client.listJMeterReports(request);return response.getBody().getReports().size() > 0;}private static void getJMeterReport(Client client, String reportId) throws Exception {// 查看机器日志GetJMeterLogsResponse getJMeterLogsResponse = getJMeterLogs(client, reportId);List<Map<String, ?>> logs = getJMeterLogsResponse.getBody().getLogs();// 查看采样器聚合数据GetJMeterSampleMetricsResponse getJMeterSampleMetrics = getJMeterSampleMetrics(client, reportId);List<String> sampleMetricList = getJMeterSampleMetrics.getBody().getSampleMetricList();// 查看采样日志GetJMeterSamplingLogsResponse getJMeterSamplingLogs = getJMeterSamplingLogs(client, reportId);List<String> sampleResults = getJMeterSamplingLogs.getBody().getSampleResults();}private static GetJMeterSamplingLogsResponse getJMeterSamplingLogs(Client client, String reportId) throws Exception {GetJMeterSamplingLogsRequest request = new GetJMeterSamplingLogsRequest();// 分页设置request.setPageNumber(1);request.setPageSize(10);// 条件设置request.setReportId(reportId);GetJMeterSamplingLogsResponse response = client.getJMeterSamplingLogs(request);return response;}private static GetJMeterSampleMetricsResponse getJMeterSampleMetrics(Client client, String reportId) throws Exception {GetJMeterSampleMetricsRequest request = new GetJMeterSampleMetricsRequest();// 设置报告idrequest.setReportId(reportId);GetJMeterSampleMetricsResponse response = client.getJMeterSampleMetrics(request);return response;}private static GetJMeterLogsResponse getJMeterLogs(Client client, String reportId) throws Exception {GetJMeterLogsRequest request = new GetJMeterLogsRequest();// 分页设置request.setPageNumber(1);request.setPageSize(10);// 查询的压测引擎索引request.setReportId(reportId);GetJMeterLogsResponse response = client.getJMeterLogs(request);return response;}private static String startTesting(Client client, String sceneId) throws Exception {StartTestingJMeterSceneResponse startTestingSceneResponse = startTestingScene(client, sceneId);String reportId = startTestingSceneResponse.getBody().getReportId();return reportId;}private static StartTestingJMeterSceneResponse startTestingScene(Client client, String sceneId) throws Exception {StartTestingJMeterSceneRequest request = new StartTestingJMeterSceneRequest();request.setSceneId(sceneId);StartTestingJMeterSceneResponse response = client.startTestingJMeterScene(request);return response;}private static String createScene(Client client) throws Exception {SaveOpenJMeterSceneRequest request = new SaveOpenJMeterSceneRequest();// 定义场景SaveOpenJMeterSceneRequest.SaveOpenJMeterSceneRequestOpenJMeterScene scene = new SaveOpenJMeterSceneRequest.SaveOpenJMeterSceneRequestOpenJMeterScene();// 设置场景名scene.setSceneName("test");// 设置文件列表,包括JMeter脚本、JMeter压测依赖jar包、配置额度数据文件等List<SaveOpenJMeterSceneRequest.SaveOpenJMeterSceneRequestOpenJMeterSceneFileList> fileList = new ArrayList<SaveOpenJMeterSceneRequest.SaveOpenJMeterSceneRequestOpenJMeterSceneFileList>();// 设置文件的属性 需要设置文件的名称和文件公网可访问的oss地址SaveOpenJMeterSceneRequest.SaveOpenJMeterSceneRequestOpenJMeterSceneFileList testFile = new SaveOpenJMeterSceneRequest.SaveOpenJMeterSceneRequestOpenJMeterSceneFileList();testFile.setFileName("baidu.jmx");testFile.setFileOssAddress("https://pts-openapi-test.oss-cn-shanghai.aliyuncs.com/baidu.jmx");fileList.add(testFile);scene.setFileList(fileList);// 设置场景并发,可设置为100万scene.setConcurrency(1000000);// 设置引擎数量 说明:一台引擎最多能发500并发,最少1并发所以此处能设置的引擎数为[2,1000],另外引擎数量越多消耗vum越快scene.setAgentCount(2000);// 设置压测持续时间 60sscene.setDuration(60);// 设置测试文件的名称,这个文件需包括在文件列表中scene.setTestFile("baidu.jmx");request.setOpenJMeterScene(scene);SaveOpenJMeterSceneResponse response = client.saveOpenJMeterScene(request);return response.getBody().getSceneId();}private static Client getClient() throws Exception {// 填写自己的AK/SKString accessKeyId = "ak";String accessKeySecret = "sk";Config config = new Config();config.setAccessKeyId(accessKeyId);config.setAccessKeySecret(accessKeySecret);Client client = new Client(config);return client;}
}

填写自己的 ak/sk

在上述代码的 getClient 中填写正确的 ak/sk

点击启动

点击 main 方法启动

通过插件实践 JMeter

对于长期使用 JMeter 的用户来说,学习一款新的压测工具还是需要一定的时间成本。因此,PTS  开发了一款 PTS-JMeter 插件,可帮助 JMeter 用户在不改变原来的压测行为下直接使用 PTS 的压测资源。用户几乎不感知 PTS-JMeter 插件的存在,与原生 JMeter 使用方式一致,保存/打开 JMeter 脚本点击启动压测即可。

下载安装

点击链接下载最新版本 jar 包[3]

将 jar 包拷贝到 JMeter 主目录下的 lib/ext 扩展目录下

点击压测

新建 JMeter 脚本,或者打开已有 JMeter 脚本,点击 PTS-JMeter 启动按钮开始压测

查看报告

压测过程中,JMeter 图形界面会显示部分压测指标,用户可随时去控制台查看压测进程。压测结束后,PTS 会生成更加详细的压测报告,默认保留 30 天,用户可随时去控制台查看。

其他

PTS-JMeter 插件更详细的使用方式可以去 PTS 帮助文档[4]中查看。

压测监控分析

性能测试不仅仅是简单的发起压力,对压力负载(RPS,网络带宽等)和业务表现(RT,成功率等)的监控和分析也是压测活动的重要组成部分。JMeter 脚本中每个请求节点(Sampler)可设置一个具有业务含义的名字(如 home 和 download page ),我们可称之为业务 API 。JMeter 监控统计按业务 API 名字汇总,如两个名字相同的请求节点将汇总统计为一个业务 API 。配置脚本时需注意,不同业务 API 节点应配置为不同的名字。

业务 API 压力负载和表现

实际工作中,不同业务 API 的统计数据可能存在巨大差异(如浏览商品 RT 通常比提交订单快很多),因此 PTS 默认将各个业务 API 独立统计展示(如上述压测中页面展示的 home 和 download page)。

压测中每个时间点的数据 PTS 都在后台记录了下来,最终将形成完整直观的压测报告。点击业务 API 实时监控趋势图按钮 ,即可查看对应的 RPS,成功率,响应时间,网络带宽等监控数据的变化趋势图。

业务 API 采样日志

很多时候我们还希望看到一个具体请求执行的详细信息。如有 1% 的请求失败,需要查看完整的请求、响应内容,以排查失败原因等。JMeter 图形界面下测试脚本时,可添加 View Results Tree 查看单个请求的详细信息,但执行压力测试时,对每个请求都记录详细信息,不仅没有必要,而且非常耗费资源,影响施压性能。

阿里云 PTS 采取了一个折中的办法,施压引擎间隔一段时间对每个业务 API(压测Sampler)分别采样记录一条成功和失败(如果有)的请求详细信息。在压测中或压测报告页面,点击查看采样日志按钮即可查询记录的请求采样信息,并支持按业务 API(压测Sampler),响应状态(是否成功),请求时间等进行搜索过滤。

点击查看详情即可看到单个请求的详细信息。目前对详细信息提供了通用和 HTTP 两种展示模板,HTTP 展示模板可针对 HTTP 请求进行更友好的排版展示,展示内容包括请求 URL,请求方法,返回码,完整的请求头、请求体,响应头、响应体等。

因为页面上只展示文本内容,请求体或响应体包含图片等无法识别为文本的内容时,可能显示为乱码。另外当请求体或响应体很大时,对应的内容可能被截断。

JMeter 日志

本地执行 JMeter 脚本时,默认将日志记录到 jmeter.log 文件。在 PTS 上执行 JMeter 脚本时,可通过 JMeter 日志页面实时查看 JMeter 日志,并支持根据日志级别、时间或线程名进行查询过滤。

JMeter 日志主要用于脚本执行报错时排查错误原因。一些插件可能通过 JMeter 日志输出一些重要信息,用户在 groovy 脚本等代码中也可以直接打印日志。

报告总结

压测结束后,PTS 将汇总监控数据形成压测报告。用户根据压测报告分析评估系统性能是否符合要求,如 RPS,成功率和 RT(响应时间)是否符合期望。并可辅助用户排查分析业务系统性能瓶颈。

PTS 压测报告页面可查询历史压测报告列表。

点击查看报告打开查看报告详情。压测报告在 PTS 上默认保存 30 天,可点击报告导出按钮,导出保存 PDF 版压测报告到本地。压测报告概要信息包括压测执行时间,RPS,RT,成功率等概要数据。场景详情包含全场景维度和业务 API 维度的监控统计信息。

相比手动命令行执行 JMeter 脚本,PTS 更加简单易用,提供简单直观的监控,并提供海量施压能力 。

原文链接

本文为阿里云原创内容,未经允许不得转载。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/511274.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

普洛斯荣获两项“数据中心绿色等级评估”5A级认证

7月29日&#xff0c;由工业和信息化部及山东省人民政府主办的首届中国算力大会在济南成功举办&#xff0c;会上同时公布了本年度“数据中心绿色等级评估”评审结果。普洛斯常熟东南数据中心B栋及普洛斯怀来数据中心3号楼均荣获“数据中心绿色等级评估”&#xff08;规划类/基础…

深度解读企业云上办公利器「无影云电脑」

简介&#xff1a;信息化进程高速发展的今天&#xff0c;用户桌面办公的需求正不断发生变化&#xff1a;远程办公&#xff0c;BYOD的需求不断增长&#xff1b;快速交付&#xff0c;高效运维的需求接连上升&#xff1b;数据及网络安全的关注度持续提高&#xff1b;整体办公成本在…

云风:不加班、不炫技,把复杂的问题简单化

小学时跟随母亲去成人大学学习编程&#xff0c;初中开始参加信息学奥赛&#xff0c;高中写出人生中第一个成熟软件——Cview&#xff0c;大学发布开源软件风魂系列&#xff0c;后用于网易开发的《大话西游》《梦幻西游》等热门游戏&#xff0c;离开网易创立简悦科技……随着云风…

Timing:在线自习室快速搭建

通过超低延迟的音视频通信技术、视频连麦、弱网传输算法&#xff0c;快速搭建自习场景&#xff0c;提升自习效率。 客户简介 氪细胞主打产品Timing&#xff0c;是国内最早推出&#xff0c;也是规模最大的在线自习室&#xff0c;是新一代的教育与社交融合平台&#xff0c;主打高…

Nacos2.0的K8s服务发现生态应用及规划

简介&#xff1a;Nacos 是阿里巴巴于 2018 年开源的注册中心及配置中心产品&#xff0c;帮助用户的分布式微服务应用进行服务发现和配置管理功能。随着 Nacos2.0 版本的发布&#xff0c;在性能和扩展性上取得较大突破后&#xff0c;社区开始考虑如何提供更加云原生方向的功能和…

webview 和 React Native 中吸顶效果实现

作者 | &#x1f47d;来源 | Sharing一、前言 在跨端开发中&#xff0c;离不开一些吸顶的交互场景&#xff0c;可以参考淘宝或是京东类电商 app 中一些 tab &#xff0c;在整个容器滑动的过程中&#xff0c;吸顶效果非常的连贯和丝滑的&#xff0c;当然这些 tab 可能是用 nativ…

AHPA:开启 Kubernetes 弹性预测之门

简介&#xff1a;阿里巴巴云原生团队和阿里达摩院决策智能时序团队合作开发 AHPA 弹性预测产品&#xff0c;该产品主要出发点是基于检测到的周期做“定时规划”&#xff0c;通过规划实现提前扩容的目的&#xff0c;在保证业务稳定的情况下&#xff0c;让你真正实现按需使用。 …

Kubernetes 在科技革命中的演变

作者 | Anthony Spiteri仅在一两年前&#xff0c;对于那些希望通过向现代数据平台转型走在前沿的企业来讲&#xff0c;容器化可是热门词汇。Kubernetes&#xff0c;也被称为 K8s&#xff0c;当时还不成熟&#xff0c;仅处于起步阶段&#xff0c;对更广泛的IT界来说仍然有些陌生…

在阿里巴巴,我们如何先于用户发现和定位 Kubernetes 集群问题?

简介&#xff1a;本文整理自阿里云高级研发工程师彭南光(光南) 在 KubeCon China 2021 大会的演讲实录&#xff0c;分享了阿里巴巴是如何通过自研通用链路探测定向巡检工具 KubeProbe 应对大规模集群的稳定性挑战的。关于阿里云云原生团队在本次 KubeCon 上分享的全部内容沉淀于…

“虎力全开”采购季,存储产品已就位

简介&#xff1a;两百多年前&#xff0c;有个叫吴锡麒的少年&#xff0c;在“江南三月听莺天&#xff0c;买酒莫论钱”。如今又逢暮春三月&#xff0c;一年一度的开年大促——阿里云上云采购季也拉开了序幕。 两百多年前&#xff0c;有个叫吴锡麒的少年&#xff0c;在“江南三月…

武汉高性能计算大会2022举办,高性能计算生态发展再添新动力

武汉高性能计算大会2022会上&#xff0c;华为重磅发布了鲲鹏高性能计算解决方案&#xff0c;为了进一步推进高性能产业的生态繁荣&#xff0c;武汉高性能计算产业联盟成立启动&#xff0c;长江欧拉生态创新中心签约并揭牌&#xff0c;首批鲲鹏科研创新使能计划成员也正式亮相。…

学信网:研究生云复试平台快速搭建上线

通过覆盖全球的音视频通信服务&#xff0c;支撑学信网视频面试稳定运行和效率提升。 案例简介 研究生复试工作碰到疫情&#xff0c;各大院校先后发布复试流程调整通知&#xff0c;将复试工作从线下搬到了线上&#xff0c;这也是历史上的第一次。要在短期内完成视频面试系统的…

企业深入使用微服务后会面临哪些问题?云原生全链路灰度给了新思路

简介&#xff1a;如何落地可灰度、可观测、可回滚的安全生产三板斧能力&#xff0c;满足业务高速发展情况下快速迭代和小心验证的诉求&#xff0c;是企业在微服务化深入过程中必须要面对的问题。在云原生流行的当下&#xff0c;这个问题又有了一些新的思路与解法。 作者&#…

40 张图 详解 Docker 容器监控

作者 | 飞向星的客机来源 | CSDN博客前言在企业中&#xff0c;通常业务是不允许随意停止的&#xff0c;否则将给企业带来巨大的经济损失。运维工程师要保证业务正常运行&#xff0c;就必须利用工具时刻监控业务的运行状态&#xff0c;容器中的业务也不例外。除了容器自身的监控…

Spring Cloud Gateway 突发高危漏洞,下一代云原生网关恰逢其时?

简介&#xff1a;Log4j2 的漏洞刚告一段落&#xff0c;Spring 官方在 2022 年 3 月 1 日发布了 Spring Cloud Gateway 的两个 CVE 漏洞&#xff1a;分别为 CVE-2022-22946&#xff08;严重性&#xff1a;Medium&#xff09;与 CVE-2022-22947&#xff08;代码注入漏洞&#xff…

云小蜜 Dubbo3.0 实践:从微服务迁移上云到流量治理

简介&#xff1a;阿里云-达摩院-云小蜜对话机器人产品基于深度机器学习技术、自然语言理解技术和对话管理技术&#xff0c;为企业提供多引擎、多渠道、多模态的对话机器人服务。17 年云小蜜对话机器人在公共云开始公测&#xff0c;同期在混合云场景也不断拓展。为了同时保证公共…

解析并执行 shell 命令

‍‍作者 | 闪客来源 | 低并发编程新建一个非常简单的 info.txt 文件。name:flash age:28 language:java在命令行输入一条十分简单的命令。[rootlinux0.11] cat info.txt | wc -l 3这条命令的意思是读取刚刚的 info.txt 文件&#xff0c;输出它的行数。 在上一回中&#xff0c;…

EventBridge消息路由|高效构建消息路由能力

简介&#xff1a;企业数字化转型过程中&#xff0c;天然会遇到消息路由&#xff0c;异地多活&#xff0c;协议适配&#xff0c;消息备份等场景。本篇主要通过 EventBridge 消息路由的应用场景和应用实验介绍&#xff0c;帮助大家了解如何通过 EventBridge 的消息路由高效构建消…

哪吒汽车选择BlackBerry QNX为中国新能源轿跑——哪吒S保驾护航

BlackBerry与合众新能源汽车有限公司近日宣布达成合作&#xff0c;合众汽车旗下汽车品牌——中国造车新势力哪吒汽车&#xff0c;在其即将量产的运动型智享轿跑——哪吒S中搭载了BlackBerry QNX为其保驾护航&#xff0c;旨在确保关键系统的功能安全、网络安全与可靠性的同时&am…

异步请求积压可视化|如何 1 分钟内快速定位函数计算积压问题

简介&#xff1a;本文分为三个部分&#xff1a;概述中引入了积压问题&#xff0c;并介绍了函数计算异步调用基本链路&#xff1b;并在指标介绍部分详细介绍了指标查看方式&#xff0c;分类解读了不同的指标含义&#xff1b;最后以一个常见的异步请求积压场景为例&#xff0c;介…