TECHNOLOGY_FRONTIER

>> 已收录 ${postCount} 项技术方案

性能测试八:Jmeter测试脚本(二) 协议、分布式发压

一、协议


 

 

协议类别 具体协议 协议说明 测试场景 测试工具
应用层协议 HTTP/HTTPS 模拟Web页面请求、API接口调用 Web应用性能测试(如用户登录、表单提交、页面加载) JMeter、LoadRunner、Gatling、Locust
WebSocket 测试实时通信应用(如在线聊天、股票行情推送、游戏交互 长连接通信的并发能力、消息延迟、吞吐量 JMeter(插件)、k6
gRPC 测试基于HTTP/2的微服务接口性能(如高并发RPC调用,大数据 微服务架构的延迟、吞吐量、负载均衡能力 JMeter(插件)、k6
FTP/SFTP 测试文件上传/下载的性能(如大文件传输速度、并发传输) 云存储服务、文件服务器压力测试 JMeter、Curl、自定义脚本
传输层协议 TCP 测试网络传输的可靠性、延迟、带宽利用率(如数据库连接、长连接服务) 验证TCP拥塞控制、最大连接数、丢包重传性能 iperf、netperf、Wireshark、自定义脚本
UDP 测试实时性要求高的场景(如音视频流、在线游戏、IoT设备通信) 丢包率、延迟抖动、最大吞吐量 iperf、kpps(Kernel Packet Per Second测试)
数据库协议 SQL 测试数据库查询性能、连接池压力、事务处理能力。 高并发SQL查询、批量插入/更新操作的TPS(每秒事务数) SysBench、HammerDB、JMeter自定义JDBC脚本
NoSQL Redis(RESP协议)测试缓存读写性能(如GET/SET操作的吞吐量)   redis-benchmark
  MongoDB(BSON协议)测试文档数据库的CRUD性能、集群扩展能力   YCSB(Yahoo! Cloud Serving Benchmark)
消息队列协议 AMQP(RabbitMQ) 测试消息生产/消费的吞吐量、队列堆积能力 异步任务处理、系统解耦性能验证 JMeter(插件)、自定义生产者/消费者脚本
MQTT 测试物联网设备消息传输性能(低带宽、高并发连接、物联网 设备连接数上限、消息发布/订阅延迟 JMeter(插件)、MQTT.fx、EMQ X Benchmark
Kafka 测试高吞吐量消息系统的分区处理能力、持久化性能(如大数据 日志处理、实时流数据的生产和消费速率 Kafka自带的kafka-producer-perf-testkafka-consumer-perf-test
流媒体协议  RTMP/HLS/DASH 测试直播或点播服务的流畅性、卡顿率、并发观看能力。 视频流的分发延迟、CDN节点负载能力 FFmpeg(推流/拉流)、LoadRunner(流媒体模块)
WebRTC 测试实时音视频通话的端到端延迟、带宽适应性。 视频会议的P2P连接成功率、抗丢包能力 Sipp、自定义WebRTC测试工具
其他协议 DNS 测试DNS服务器的解析速度、抗DDoS攻击能力   dnsperf、JMeter(DNS请求插件)
SMTP/POP3/IMAP 测试邮件服务器的并发发送/接收性能 批量邮件处理、附件传输速度 JMeter(邮件协议插件)、Apache James
LDAP 测试目录服务的认证和查询性能(如企业用户管理系统)   JMeter(LDAP插件)、ldap-bench

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1.1 应用层协议


 

1.1.1 HTTP协议


 

  • HTTP(Hyper text Transfer Protocol)协议,即超文本传输协议。
  • 无法验证服务器身份,存在钓鱼网站风险。
  • 适用于内部测试环境、静态信息展示(无需敏感交互)
  • 数据(如密码、银行卡号)以未加密的文本形式传输,易被中间人窃听或篡改。
  • 端口号:80
  • 直接运行在 TCP协议 之上(应用层)

 

HTTP请求头各字段含义

HTTP请求头帮助客户端与服务器高效交互,传递上下文信息(如认证、缓存、内容偏好等)。实际开发中需根据场景选择合适的头字段,例如:
缓存优化:Cache-Control、If-Modified-Since
跨域请求:Origin、Access-Control-Request-Headers
数据压缩:Accept-Encoding
安全认证:Authorization、Cookie

基础字段

Host
含义:目标服务器的域名和端口号。
用途:HTTP/1.1 要求必须包含此字段,用于区分同一IP上的多个虚拟主机。
示例:Host: www.example.com:8080

User-Agent
含义:客户端(浏览器、应用等)的类型、版本和操作系统信息。
用途:服务器可根据此字段返回适配的内容(如移动端/PC端页面)。
示例:User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0.4472.124

Accept
含义:客户端可接受的响应内容类型(MIME类型)。
用途:内容协商(如优先返回JSON或XML)。
示例:Accept: text/html, application/json

Accept-Encoding
含义:客户端支持的压缩算法(如gzip、deflate)。
用途:服务器可选择压缩响应以节省带宽。
示例:Accept-Encoding: gzip, deflate, br

Accept-Language
含义:客户端优先接受的自然语言(如中文、英文)。
用途:服务器返回对应语言的页面。
示例:Accept-Language: zh-CN, en-US;q=0.9

请求控制

Connection
含义:控制是否保持长连接(HTTP Keep-Alive)。
示例:
保持连接:Connection: keep-alive(HTTP/1.1默认开启)
关闭连接:Connection: close

Cache-Control
含义:控制缓存行为(如是否缓存、缓存时间)。
示例:
不缓存:Cache-Control: no-cache
最大缓存时间:Cache-Control: max-age=3600

If-Modified-Since
含义:资源上次修改时间(与服务器资源对比,决定是否返回新内容)。
用途:减少重复传输(若未修改,返回 304 Not Modified)。
示例:If-Modified-Since: Wed, 21 Oct 2022 07:28:00 GMT

认证与会话

Authorization
含义:携带认证凭证(如Bearer Token、Basic认证)。
示例:
Basic认证:Authorization: Basic base64(username:password)
JWT:Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Cookie
含义:客户端存储的会话信息(由服务器通过 Set-Cookie 响应头设置)。
示例:Cookie: sessionId=abc123; theme=dark

请求体相关

Content-Type
含义:请求体的数据类型(仅用于POST/PUT等携带Body的请求)。
示例:
JSON数据:Content-Type: application/json
表单提交:Content-Type: application/x-www-form-urlencoded

Content-Length
含义:请求体的字节长度。
示例:Content-Length: 348

Content-Encoding
含义:请求体使用的压缩算法(如客户端压缩数据)。
示例:Content-Encoding: gzip

跨域与安全

Origin
含义:请求的来源域名(用于CORS跨域请求)。
示例:Origin: https://www.example.com

Referer
含义:当前请求的来源页面的URL。
用途:防盗链、统计分析。
示例:Referer: https://www.example.com/home

Upgrade-Insecure-Requests
含义:客户端希望将HTTP资源自动升级为HTTPS(安全请求)。
示例:Upgrade-Insecure-Requests: 1

其他常见字段

Range
含义:请求部分内容(用于断点续传或分片下载)。
示例:Range: bytes=0-499(请求前500字节)。

DNT (Do Not Track)
含义:客户端请求不追踪用户行为(隐私保护)。
示例:DNT: 1

 

1.1.2 HTTPS


 

  • HTTPS是HTTP通过证书颁发机构(CA)颁发SSL/TLS加密证书,保证协议安全性。
  • 通过 SSL/TLS 协议对数据进行加密(如AES、RSA等算法),即使被截获也无法解密。
  • 适用于所有涉及隐私的场景:登录、支付、表单提交、API通信等,现代浏览器已强制要求HTTPS(如WebRTC、地理位置功能)
  • 依赖 数字证书(由CA颁发,免费或收费),确保用户访问的是真实服务器,而非仿冒站点。
  • 默认使用 443端口
  • 在 HTTP 和 TCP 之间增加 SSL/TLS 加密层(传输层安全协议)
  • 因加密计算和握手流程(如TLS握手)会略微增加延迟(约10%-20%),现代硬件优化(如HTTP/2、HTTP/3)已大幅缩小性能差距

 

1.2 传输层协议


 

Jmeter基于JAVA实现TCP协议

· 步骤1:开发已经写好测试实现类,且已经自测完毕;测试类与实现类放在同一目录下
· 步骤2:Jmeter需要jar包/lib/ext:ApacheJmeter_core.jar ApacheJmeter_java.jar
- 步骤3:取样器添加java请求,根据JAVA实现类设置断言
//导入jar包
improt org.apache.jmeter.config.Arguments;
improt org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
improt org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
improt org.apache.jmeter.sampler.SampleResult;

//测试类
public class JmetetTest extends AbstractJavaSamplerClient(){
//创建实现类
TestJMter client;

//自定义java方法入参
@Override
public Arguments getDefaultParamters(){
Arguments args = new Arguments();
args.addArguments("userName","");
args.addArguments("passWd","");
....
return args;
}

//每个线程测试前执行一次,做一些初始化
//获取输入的参数,赋值给变量,参数也可以在下面的runTest方法中获取,这里是为了展示该方法的作用
public void setupTest(JavaSamplerContext context){
client = new TestJMeter();
}

//测试结束后调用
@Override
public void teardownTest(JavaSamplerContext context){
}

@Override
public SampleResult runTest(JavaSamplerContext context){
 String resultStr = "";
       SampleResult sampleResult = new SampleResult();
       //获取JMeter获取的参数
       String filePath = context.getParameter("filePath");
       Integer numOfUpload = Integer.valueOf(context.getParameter("NumOfUpload"));
 String ip = context.getParameter("IP");
    String startDate = context.getParameter("startDate");
    String fileType = context.getParameter("fileType");
    String modelPart = context.getParameter("modelPart");
    String modelCode = context.getParameter("modelCode");
    String col = context.getParameter("col");
//设置请求信息
    String reqHeader = ("filePath:" + filePath + "\n" + "NumOfUpload:" + numOfUpload + "\n"+"IP:" + ip + "\n"+"startDate:" + startDate + "\n"+"fileType:" + fileType + "\n"+"modelPart:" + modelPart + "\n"+"modelCode:" + modelCode);
    
 //jmeter 开始统计响应时间标记
    sampleResult.sampleStart();
    try {
        String result = client.uploadExample(filePath,numOfUpload,ip,startDate,fileType,modelPart,modelCode,col);
        String flag = result.split(TransOptionkey.SPLITSYM)[0];
        if ("SUCESS".equals(flag)){
//设置响应执行成功
            sampleResult.setSuccessful(true);
            resultStr += result;
        }else {
            sampleResult.setSuccessful(false);
            resultStr += result;
        }
    }catch (Exception e){
  //有异常,执行失败
        sampleResult.setSuccessful(false);
        resultStr+=e.toString();
    }
//打印请求信息
    sampleResult.setRequestHeaders(reqHeader);
//通过下面的操作就可以将被测方法的响应输出到Jmeter的察看结果树中的响应数据里面了
    sampleResult.setResponseData(resultStr,"utf-8");
    sampleResult.setDataType(SampleResult.TEXT);
//jmeter 结束统计响应时间标记
    sampleResult.connectEnd();
    return sampleResult;
}
}

- 步骤4:打jar包并部署到JMeter/lib/ext,重启JMTER

-步骤5:线程组 → Java请求 → JmetetTest → 配置UserName 、PassWd

 

1.3 数据库协议


 

JMETER使用JDBC压测数据库

步骤1:获取响应数据库驱动jar包,放至Jmeter/lib目录下

步骤2测试计划->添加->配置元件->JDBC Connection Configuration

连接池参数配置 Connection pool Configuration

Max Number of Connection       数据库最大链接数,一般可设置为0,意思是每个线程都使用单独的数据库连接,线程之间数据库连接不共享
Max Wait (ms)             在连接池中取回连接最大等待时间
Time Between Eviction Runs(ms)  线程可空闲时间如果当前连接池中某个连接在空闲了 time Between Eviction Runs Millis 时间后任然没有使用,则被物理性的关闭掉
Auto Commit              自动提交sql语句
Read timeout(ms)          等待服务器响应的超时时间
Transaction isolation       事务隔离级别,主要有如下几个选项:
(对JMX加解密) TRANSACTION_NODE 事务节点 、TRANSACTION_READ_UNCOMMITTED 事务未提交读、TRANSACTION_READ_COMMITTED 事务已提交读 、TRANSACTION_SERIALIZABLE 事务序列化 、DEFAULT 默认、TRANSACTION_REPEATABLE_READ 事务重复读 Preinit Pool             立即初始化连接池如果为 False,则第一个 JDBC 请求的响应时间会较长,因为包含了连接池建立的时间

验证连接池是否能响应  Connection Validation by Pool

Test While Idle                当连接空闲时测试是否断开
Soft Min Evictable Idle Time(ms)     连接在池中处于空闲状态的最短时间,默认值为5000(5秒)
Validation Query              一个简单的查询,用于确定数据库是否仍在响应

数据库连接配置  Database Connection Configuration

Database URL          数据库连接 URL,具体说明见注1
JDBC Driver class       数据库JDBC驱动类名,选择对应数据库的数据驱动
Username            数据库登录用户名
Password            数据库登录密码
Connection Properties    建立连接时要设置的连接属性

 

步骤3线程组->添加->取样器->JDBC Request

 数据库连接池配置  Variable Name Bound to pool

Variable Name for pool declared in JDBC Connection Configuration
数据库连接池的名称,和JDBC Connection Configuration的Variable Name for created pool名字保持一致

数据库操作 SQL Query 查询为例

Query Type          sql语句类型,这里的语句选择的select statement,根据实际测试sql来选择
Query             填写的sql语句,多条语句中间用;分割,语句末尾不加;
JDBC Request         要传输的值
Parameter types       传输值的类型
Variable names        sql执行结果变量名
Result variable names    所有结果当做一个对象存储
Query timeouts(s)      查询超时时间
Limit Result Set       限制 sql 语句返回结果集的行数
Handle Result Set      如何定义 callable statements 返回的结果集;默认是存储为字符串

步骤4:脚本执行

 

1.4 消息队列协议


 

Jmeter基于组件实现RocketMQ协议

- 步骤1下载 RocketMQ 客户端 JAR 包(如 rocketmq-client-5.x.x.jar),将 RocketMQ 客户端 JAR 文件放入 JMeter 的 lib/ext 目录,重启Jmeter

1.4.1 生产者压测


 

- 步骤2:Thread Group → Add → Sampler → JSR223 Sampler

- 步骤3:选择语言 Groovy

- 步骤4:编写脚本

 1 import org.apache.rocketmq.client.apis.*;
 2 import org.apache.rocketmq.client.apis.message.*;
 3 import org.apache.rocketmq.client.apis.producer.*;
 4 
 5 // 1. 初始化 Producer
 6 def endpoints = "localhost:9876" // NameServer 地址
 7 def clientConfiguration = ClientConfiguration.newBuilder().setEndpoints(endpoints).build()
 8 def producer = Producer.newBuilder()
 9     .setClientConfiguration(clientConfiguration)
10     .setTopics("YourTopicName") // 目标 Topic
11     .build()
12 
13 // 2. 构造消息
14 def messageBuilder = MessageBuilder.newBuilder()
15     .setTopic("YourTopicName")
16     .setBody("JMeterTestMessage".getBytes()) // 消息内容
17     .setTag("TagA") // 可选 Tag
18 def message = messageBuilder.build()
19 
20 // 3. 发送消息
21 try {
22     def sendReceipt = producer.send(message)
23     log.info("Message sent: " + sendReceipt.getMessageId())
24 } catch (ClientException e) {
25     log.error("Send failed: " + e.toString())
26     SampleResult.setSuccessful(false) // 标记失败
27     SampleResult.setResponseMessage(e.getMessage())
28 }
29 
30 // 4. 关闭 Producer(可选,压测时建议不关闭)
31 // producer.close()

 

1.4.2 消费者压测

 1 import org.apache.rocketmq.client.apis.*;
 2 import org.apache.rocketmq.client.apis.consumer.*;
 3 
 4 // 1. 初始化 Consumer
 5 def endpoints = "localhost:9876"
 6 def clientConfiguration = ClientConfiguration.newBuilder().setEndpoints(endpoints).build()
 7 def consumer = Consumer.newBuilder()
 8     .setClientConfiguration(clientConfiguration)
 9     .setSubscriptionExpressions(["YourTopicName": FilterExpression.SUB_ALL] as Map)
10     .setMessageListener(new MessageListener() {
11         @Override
12         ConsumeResult consume(MessageView messageView) {
13             log.info("Received message: " + messageView.getMessageId())
14             return ConsumeResult.SUCCESS // 确认消费成功
15         }
16     })
17     .build()
18 
19 // 2. 启动消费者(需保持长运行,压测时可能需要循环或定时器)
20 consumer.start()
21 // 阻塞线程,避免 JMeter 提前结束(根据压测时长调整)
22 sleep(60000) // 持续运行 60 秒
23 consumer.close()

若需持续消费,右键 Thread Group → Add → Timer → Constant Timer,设置间隔时间

 

1.4.3 结果分析


 

生产者指标

  • TPS:每秒发送的消息数。
  • 平均响应时间:消息从生产到 Broker 确认的时间。
  • 错误率:消息发送失败比例。

消费者指标

  • 消费速率:每秒处理的消息数。
  • 消息延迟:消息从生产到消费的时间差

 

Jmeter基于JAVA实现RocketMQ协议

- Jmeter需要jar包/lib/ext:ApacheJmeter_core.jar ApacheJmeter_java.jar

 - 步骤1:添加依赖  在Maven项目中添加RocketMQ客户端依赖
<dependency>
    <groupId>org.apache.rocketmq</groupId>
    <artifactId>rocketmq-client</artifactId>
    <version>4.9.4</version>
</dependency>

- 步骤2:编写生产者压测代码

 1 import org.apache.jmeter.config.Arguments;
 2 import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
 3 import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
 4 import org.apache.jmeter.samplers.SampleResult;
 5 import org.apache.rocketmq.client.producer.DefaultMQProducer;
 6 import org.apache.rocketmq.common.message.Message;
 7 
 8 public class RocketMQProducerTest extends AbstractJavaSamplerClient {
 9     private DefaultMQProducer producer;
10 
11     @Override
12     public Arguments getDefaultParameters() {
13         Arguments params = new Arguments();
14         params.addArgument("namesrvAddr", "localhost:9876");
15         params.addArgument("topic", "TestTopic");
16         params.addArgument("tag", "TestTag");
17         params.addArgument("messageBody", "Hello RocketMQ");
18         return params;
19     }
20 
21     @Override
22     public void setupTest(JavaSamplerContext context) {
23         try {
24             producer = new DefaultMQProducer("ProducerGroup");
25             producer.setNamesrvAddr(context.getParameter("namesrvAddr"));
26             producer.start();
27         } catch (Exception e) {
28             throw new RuntimeException("Failed to start producer", e);
29         }
30     }
31 
32     @Override
33     public SampleResult runTest(JavaSamplerContext context) {
34         SampleResult result = new SampleResult();
35         result.sampleStart();
36 
37         try {
38             String topic = context.getParameter("topic");
39             String tag = context.getParameter("tag");
40             String body = context.getParameter("messageBody");
41 
42             Message msg = new Message(topic, tag, body.getBytes());
43             producer.send(msg);
44 
45             result.setSuccessful(true);
46             result.setResponseCodeOK();
47             result.setResponseMessage("Message sent successfully");
48         } catch (Exception e) {
49             result.setSuccessful(false);
50             result.setResponseMessage("Error: " + e.getMessage());
51         } finally {
52             result.sampleEnd();
53         }
54         return result;
55     }
56 
57     @Override
58     public void teardownTest(JavaSamplerContext context) {
59         producer.shutdown();
60     }
61 }

- 步骤3:编写消费者压测代码

 1 import org.apache.jmeter.config.Arguments;
 2 import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
 3 import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
 4 import org.apache.jmeter.samplers.SampleResult;
 5 import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
 6 import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
 7 import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
 8 
 9 public class RocketMQConsumerTest extends AbstractJavaSamplerClient {
10     private DefaultMQPushConsumer consumer;
11 
12     @Override
13     public Arguments getDefaultParameters() {
14         Arguments params = new Arguments();
15         params.addArgument("namesrvAddr", "localhost:9876");
16         params.addArgument("topic", "TestTopic");
17         params.addArgument("consumerGroup", "TestConsumerGroup");
18         return params;
19     }
20 
21     @Override
22     public void setupTest(JavaSamplerContext context) {
23         try {
24             consumer = new DefaultMQPushConsumer(context.getParameter("consumerGroup"));
25             consumer.setNamesrvAddr(context.getParameter("namesrvAddr"));
26             consumer.subscribe(context.getParameter("topic"), "*");
27             consumer.registerMessageListener((MessageListenerConcurrently) (msgs, context) -> {
28                 // 处理消息逻辑
29                 return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
30             });
31             consumer.start();
32         } catch (Exception e) {
33             throw new RuntimeException("Failed to start consumer", e);
34         }
35     }
36 
37     @Override
38     public SampleResult runTest(JavaSamplerContext context) {
39         SampleResult result = new SampleResult();
40         result.sampleStart();
41         // 通常消费者为异步监听,此处仅模拟触发逻辑
42         result.setSuccessful(true);
43         result.sampleEnd();
44         return result;
45     }
46 
47     @Override
48     public void teardownTest(JavaSamplerContext context) {
49         consumer.shutdown();
50     }
51 }

- 步骤4:打包并部署到Jmeter

  • 将代码打包为jar文件(包含所有依赖)。

  • jar文件放入JMeter的lib/ext目录。

  • 重启JMeter

-步骤 5:配置JMeter测试计划

  • 添加 线程组 设置并发数。

  • 添加 Java请求 选择RocketMQProducerTest类。

  • 在参数中配置namesrvAddrtopic等值。

  • 添加监听器(如:查看结果树、聚合报告)

注意事项

  • 资源管理:确保每个线程正确初始化和关闭Producer/Consumer。

  • 参数化:通过JMeter参数传递动态值(如消息内容)。

  • 结果验证:使用断言验证消息是否成功发送/消费。

  • 监控:结合RocketMQ控制台监控Broker状态。

 

1.5 流媒体协议

 

1.6 其他协议

 

 

二、Jmeter分布式发压


2.1 为什么使用分布式发压?

1. windows发压对客户机资源使用较高,且支持300-500Vu受限于Jmeter本身机制和硬件配置(4c8g)
2. Cmd或linux发压频繁变更脚本、参数化文件,如果jtl结果文件较大更耗时
 

2.2 分布式发压原理


1. 选择一台管理机Controller,其他机器作为代理机Slave Agent
2. 测试执行时由Controller通过命令将测试脚本发给Slave Agent,然后Agent执行,同时将测试结果发给Controller
3. 测试完成,可以在Controller上监听器看到Agent发来的测试结果,结果为多个Agent汇聚而成
 

2.3 开始前的准备


1. 系统上的防火墙已关闭或者已经打开正确的端口
2. 所有客户端都在同一子网上
3. 确保Jmeter可以访问服务器
4. 确保所有系统上使用相同版本的Java和Jmeter
5. 确保已经为RML设置是SSL或将其禁用
 

2.4 配置Jmeter相关文件(需修改Master和slave机配置)


2.4.1.Master控制机修改(以Windows为例)


 

编辑Jmeter/bin/Jmeter.properties,如图:

①查看Linux执行机的ip地址,然后设置remote_hosts=执行机1:端口号,执行机2:端口号
②修改server_port=1099 执行启动远程连接的端口号 ,remote_hosts配置成一致的端口号
③server.rmi.ssl.disable=false改为 server.rmi.ssl.disable=true
④server.rmi.localport=4000执行机Jmeter_server启动显示的端口启动的端口号 
⑤查找到mode=Standard 项,将其前边的注释去掉(解决Jmeter进行分布式测试,远程机器来运行脚本,在察看结果树中的响应数据项为空白)

 

 

编辑Jmeter/bin/Jmeter-server.sh

RMI_HOST_DEF=-Djava.rmi.server.hostname=10.8.18.168(地址改成本机的ip地址,执行和控制机都需要改
 
编辑Jmeter/bin/Jmeter.bat
新增set rmi_host=-Djava.rmi.server.hostname=本机ip
修改set ARGS=%DUMP% %HEAP% %NEW% %SURVIVOR% %TENURING% %PERM% %DDRAW%%rmi_host%
 
 

2.4.2.slave机配置(以linux为例)


编辑Jmeter/bin/Jmeter.propertie,如图

①修改server_port=1099 表示控制机要远程连接通信的端口号,即Master配置文件Jmeter.properties的remote_hosts配置的端口号
②server.rmi.localport=4000执行机Jmeter_server启动显示的端口启动的端口号
③server.rmi.ssl.disable=false改为 server.rmi.ssl.disable=true

 

 编辑Jmeter/bin/Jmeter-server.sh

RMI_HOST_DEF=-Djava.rmi.server.hostname=10.8.18.168 (地址改成本机的ip地址,执行和控制机都需要改
 
备注:如果Linux服务器自身性能优越,可以单台Linux部署多个Jmeter进行测试,具体操作如下:
复制Jmeter安装包,
修改Jmeter.properties文件的端口号 server_port=1099和server.rmi.localport=4000,更改为未被占用的端口号
然后修改Jmeter-server文件的启动端口号,1039即自己指定的端口号,和Jmeter.properties的server_port一致。
RMI_HOST_DEF=-Djava.rmi.server.hostname=10.1.1.14 
DIRNAME/Jmeter{RMI_HOST_DEF} -Dserver_port=SERVERPORT:−1039−s−jJmeter−server.log"
 
完成后./Jmeter-server 启动服务
操作Master发起指令,进行测试
测试完成后,Master收集测试数据,并生成测试报告
 

2.5 压测停止


 Master是Linux系统:

cd 进入到JMeter 的 bin 目录下
输入 ./shutdown.sh 命令停止脚本
注:如果在分布式压测过程中,想要终止压测,千万不要在Linux上按 ctrl + c 强制终止程序,这样会知道主程序挂了之后,从机未接受到执行,会一直持续运行。当你再次从主机上运行脚本,从机仍然会在上一个脚本的程序中运行。
如果想要终止程序,可以执行命令行./shutdown.sh ,通知master终止程序,然后master 再去通知salve停止运行。
 
Master是Windows系统:
菜单栏选择运行 → 远程停止所有 Alt+X
 

2.6 其他说明


参数文件:如果使用csv进行参数化,那么需要把参数文件在每台slave上拷一份且路径需要设置成一样的。
②每台机器上安装的Jmeter版本和插件最好都一致,否则会出一些意外的问题。
③Jmter非GUI界面
jmeter -n -t /data/jmx/1.jmx -l /data/result/result_20240507_10vu.jtl -e -o /home/jmeter/ResultReporte
#非GUI本机作为Mater+slave机,Mater需要配置slaveip
./jmeter -n -t /data/jmx/2.jmx -R 10.23.0.1:1099,10.23.0.2:1099 -l /data/result/3.jtl
参数说明
-n : 非GUI 模式执行JMeter nongui 
-t : 执行测试文件所在的位置及文件名 testfile 
-r : 远程将所有agent启动用在分布式测试场景下,不是分布式测试只是单点就不需要-r -R
-l : 指定生成测试结果的保存文件, jtl 文件格式 logfile 
-e : 测试结束后,生成测试报告
-o : 指定测试报告的存放位置
-o 指定的文件及文件夹,必须不存在 ,否则执行会失败,对应上面的命令就是resultReport文件夹必须不存在否则报错
 
 

2.7 配置执行中问题汇总


2.7.1.启动Master报错


 

问题1:在使用java远程启动linux服务器上的jmeter服务是报错

Neither the JAVA_HOME nor the JRE_HOME environment variable is defined
解决办法
jmeter/bin/jmeter-server文件,在顶部添加JAVA_HOME和JRE_HOME
export JAVA_HOME=/usr/java/jdk1.8.0_131
export JRE_HOME=$JAVA_HOME/jre
 
问题2

 解决办法

将执行机(slave)上的端口设置为固定端口即可(在之前的部署中已经说明如何自定义端口了,参考上文)
 
问题3:Java.net.ConnectionException: Connection refused:connect
解决办法:
在执行机上重新启动Jmeter-server服务,或者是你这个服务压根就没有启动(如果解决不了,请仔细查看执行机上的Jmeter-server.log中的报错信息
 
问题4:windows启动卡住salve报错
0
解决办法
①尝试关闭防火墙 systemctl status firewalld
②telnet 192.168.20.115:1099  -bash: telnet: command not found
③./jmeter-server -Djava.rmi.server.hostname=192.168.20.109(本机ip)
 
 

2.7.2.启动slave报错


问题1

[test@localhost bin]$ ./jmeter-server 
Writing log file to: /home/test/jmeter/apache-jmeter-3.1/bin/jmeter-server.log
Created remote object: UnicastServerRef [liveRef: [endpoint:[127.0.0.1:37863](local),objID:[-3217392f:17b104e6552:-7fff, 742049333908920389]]]
Server failed to start: java.rmi.RemoteException: Cannot start. localhost.localdomain is a loopback address.
An error occurred: Cannot start. localhost.localdomain is a loopback address.

解决办法

执行命令中指定本地IP ./jmeter-server -Djava.rmi.server.hostname=xxx.xxx.xxx.xxx
 
问题2
[root@iZwz95j86y235aroi85ht0Z bin]# ./jmeter-server
Created remote object: UnicastServerRef2 [liveRef: [endpoint:[:39308](local),objID:[24e78a63:16243c70661:-7fff, 7492480871343944173]]]
Server failed to start: java.rmi.RemoteException: Cannot start. Unable to get local host IP address.; nested exception is:
java.net.UnknownHostException: iZwz95j86y235aroi85ht0Z: iZwz95j86y235aroi85ht0Z: Name or service not known
An error occurred: Cannot start. Unable to get local host IP address.; nested exception is:
java.net.UnknownHostException: iZwz95j86y235aroi85ht0Z: iZwz95j86y235aroi85ht0Z: Name or service not known

解决办法

使用hostname命令获取机器名称,追加一个映射iZwz95j86y235aroi85ht0Z
[root@iZwz95j86y235aroi85ht0Z bin]# vi /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
120.79.160.143 iZwz95j86y235aroi85ht0Z

 

问题3

slave机器无法启动或者没有返回执行数据
解决办法
1、检查master机器和slave机器能否ping通
2、检查防火墙
3、检查master机器和slave机器的服务器时间是否一致
 
问题4
[admin@nesb-rm-m bin] Created remote object: UnicastServerRef2 [endpoint:[127.0.0.1:28679](local),objID:[-1252db5:18fa38b78e4:-7fff,-3603352543234507157]]]
Server failed to start: java.rmi.RemoteException: Cannot start. nesb-rp-m is a loopback address.
An error occurred: Cannot start. nesb-rp-m is aloopback address.

解决办法

sudo vi ./jmeter-server
编辑jmeter-server,取消RMI_HOST_DEF的注释项,固定设置当前Linux主机查询到的IP:
 
问题5
last login: fri May 14 14:02:12 2024 form jumpl.corp.cedex.cn
[admin@ftpc~]cd /usr/SoftWare/Jmeter/apache-jmeter-5.1/bin

[admin@ftpc~]sudo ./jmeter-server
[sudo]password for admin:
Server failed to start: java.rmi.server ExportException: Listen failed on port:0; nested exception is:
java.io.FileNotFoundException:rmi_keystore.jks(No such file or directory)
An error occurred: listen failed on port: 0; nested exception is:
java.io.FileNotFoundException: rmi_keystore.jks(No such file or directory)

解决办法

拥有RMI over SSL的有效密钥库,或者禁用了SSL。
1、找到JMETER_HOME\bin\jmeter.properties
2、修改server.rmi.ssl.disable=true (记得去除server.rmi.ssl.disable=true前的#),重新启动jmeter-server.bat
 

报错6

[root@iZ949uw2xehZ bin]# ./jmeter
Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x00000000c0000000, 1073741824, 0) failed; error='Cannot allocate memory' (errno=12)
#
# There is insufficient memory for the Java Runtime Environment to continue.
# Native memory allocation (mmap) failed to map 1073741824 bytes for committing reserved memory.
# An error report file with more information is saved as:
# /usr/local/jmeter/apache-jmeter-4.0/bin/hs_err_pid5855.log

解决办法:

编辑jmeter
搜索 : "${HEAP:="-Xms1g -Xmx1g -XX:MaxMetaspaceSize=256m"}"
改变初始堆内存和最大堆内存
posted on 2025-03-21 16:23  王元安  阅读(117)  评论(0)    收藏  举报