关于java:如何快速调度-PTS-的百万并发能力

1次阅读

共计 7058 个字符,预计需要花费 18 分钟才能阅读完成。

简介:压测是通过模仿用户行为对业务零碎发动申请,测算出零碎的承载能力,并对系统做一次全面的体检,压测后可依据压测体现优化零碎瓶颈,防止出现线上故障。

作者:灵苒

在理论的业务场景中,压测是必不可少的一环,无论是对服务器、数据库、网络等性能瓶颈的评估,还是如浏览、下单、领取等重要流量节点的业务连续性保障,亦或是搬站上云整体业务稳定性的预估,这些都须要性能压测来帮忙你建设对系统和业务的残缺认知。依据 Google 的统计,如果网站关上慢每 500 毫秒,用户访问量将降落 20%。依据 Amazon 统计,每慢 100 毫秒,交易额降落 1%。这些事件和统计数据为大家敲响了警钟,也主观阐明了性能压测对于企业应用的重要性。

压测是通过模仿用户行为对业务零碎发动申请,测算出零碎的承载能力,并对系统做一次全面的体检,压测后可依据压测体现优化零碎瓶颈,防止出现线上故障。

业界常见的压测软件 JMeter 和 PTS

目前 JMeter 是性能压测畛域利用最宽泛的开源软件。

对于场景简略,要求测试并发量不高的状况下,JMeter 本地测试就能满足需要。但随着互联网用户的减少,对系统承载更大并发的需要日渐晋升,而单台 JMeter 施压机的施压能力有肯定下限,所以须要应用多台施压机,以进步 JMeter 的施压能力,这就要应用到 JMeter 的分布式施压性能。

但 JMeter 的分布式压测前置筹备较多,须要留神以下几点:

施压机的防火墙已敞开或关上了正确的端口。为 RMI 设置了 SSL 或禁用了它。

所有施压机都在同一个子网上。如果应用 192.xxx 或 10.xxx IP 地址,则服务器位于同一子网中。

所有施压机上应用雷同版本的 JMeter 和 Java。

所有施压机都曾经拷贝了切分好的 CSV 数据文件、依赖 jar 包等。

已配置好监控数据的收集。

由此可见 JMeter 的分布式压测须要本人协调各资源,前置筹备比拟麻烦,对施行压测的人员来说压测效率低。

PTS 是阿里云研发的性能测试工具,最后次要为了模仿双十一流量洪峰,现在已走过十个年头,在场景编排、压测执行、压测监控剖析、报告总结等各方面能力绝对欠缺,可提供百万并发、千万 TPS 流量发动能力,并且还能齐全兼容 JMeter,可人造补救 JMeter 在性能压测中的劣势。对应用 JMerer 无奈绕过集群问题的用户是一个很好的抉择。

PTS 的 JMeter 压测极大的简化了 JMeter 分布式压测流程,同时也升高了压测过程中对施压机的保护老本。应用 PTS 的 JMeter 压测,用户只须要在控制台配置须要应用的机器数,毋庸用户提前准备多台已装置雷同 Java 和 JMeter 版本的施压机。同时毋庸用户依据施压机数量去切分 CSV 参数文件;压测完结后,PTS 会将监控数据汇总产生一个具体的压测报告供用户查阅。

相比于间接在命令行执行 JMeter 脚本来说,PTS 应用更加不便,可按需提供海量的施压能力,并且能提供简洁直观的监控和报告。


如何发动 PTS 的 JMeter 压测

和所有压测的外围步骤一样,应用 PTS 的 JMeter 压测,也次要集中在创立场景、压测场景和查看报告三个步骤中。

1、创立场景:PTS 的 JMeter 压测以场景为外围,压测对象为一个场景,场景中包含 JMeter(原生)脚本、JMeter 依赖(一系列依赖 jar 包和一系列 properties 配置)、及一些压测配置(PTS 压测的配置,例如公网 /VPC 压测、并发量、引擎数量、压测时长等)。

2、压测场景:对场景的操作分为两方面,一是对场景配置的增删改查,二是对场景的压测和调试。

3、生成报告:每次对场景压测都会生成一个压测工作,同时生成一个报告,其中包含压测的要害指标,如 TPS、RT、成功率等,可辅助用户排查零碎性能瓶颈。此外,PTS 默认将报告保留 30 天,能够随时查看历史报告,并且提供导出 PDF 格局的报告。

在压测畛域,随着压测需要日益多样化,更多用户心愿将云上的压测能力继承到本人的零碎,或者依据本人的业务零碎,编排自定义的压测平台,从而实现自动化定制化压测需要。

所以,为了不便用户便捷调度 PTS 百万并发的能力,PTS 开明了 JMeter 的 OpenAPI,提供了如下几类压测的外围性能:编辑场景、调试场景、压测场景、查看运行时数据、查看报告。

通过集成 OpenAPI,客户能够更加不便的在本人的业务场景实现 PTS 百万级并发压测的能力,实现场景的增、删、改、查等各种操作,一键启动压测,并在压测过程中,随时进行压测。同时生成的压测报告中,除了 JMeter 原生的日志外,还有 PTS 针对某个采样器的成功率、TPS、RT 指标的聚合数据。另外还能够对报告进行查看报告列表、JMeter 原生日志以及 PTS 对 JMeter 采样器压测指标的聚合数据等性能。

那么还等什么呢?来,试着用 PTS 中 JMeter 的 OpenAPI 写一个属于你的百万级并发压测能力的压测平台吧!

附录:

具体步骤如下:

引入 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();
        // 设置报告 id
        request.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);
        // 设置压测持续时间 60s
        scene.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/SK
        String 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

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

正文完
 0