当前位置 : 首页 » 文章分类 :  开发  »  Apache-JMeter

Apache-JMeter

JMeter 使用笔记

使用 JMeter 进行压力测试

1、在 jmeter GUI 界面上配置好压测的 request 参数,保存为 jmx 文件
2、使用 jmeter 命令行读取 jmx 文件进行真正的压测过程。

官方提示尽量不要在 GUI 界面上直接进行压测。

jmeter -n -t es-load-test.jmx -l jmeter-nongui.log -e -o webreport

-n, --nongui 非 GUI 模式 -> 在非 GUI 模式下运行 JMeter
-t, --testfile {argument} 测试文件 -> 要运行的 JMeter jmx 脚本文件
-l, --logfile {argument} 日志文件 -> 记录结果的文件
-e 生成压测报告仪表盘 dashboard (html网页)
-o 指定 dashboard 仪表盘页面的生成文件夹,必须不存在或是空目录

-h 帮助 -> 打印出有用的信息并退出
-r 远程执行 -> 在Jmter.properties文件中指定的所有远程服务器
-H 代理主机 -> 设置 JMeter 使用的代理主机
-P 代理端口 -> 设置 JMeter 使用的代理主机的端口号

1.4.4 CLI Mode (Command Line mode was called NON GUI mode)
https://jmeter.apache.org/usermanual/get-started.html#non_gui

参数 ramp-up period 用于告知JMeter 要在多长时间内建立全部的线程。默认值是0。假如未指定ramp-up period ,也就是说ramp-up period 为零, JMeter 将立即建立所有线程,假设ramp-up period 设置成T 秒, 全部线程数设置成N个, JMeter 将每隔T/N秒建立一个线程。

假如设置成零,Jmeter将会在测试的开始就建立全部线程并立即发送访问请求, 这样一来就很轻易使服务器饱和,更重要的是会隐性地增加了负载,这就意味着服务器将可能过载,不是因为平均访问率高而是因为所有线程的第一次并发访问而引起的不正常的初始访问峰值,可以通过Jmeter的聚合报告监听器看到这种现象。
这种异常不是我们需要的,因此,确定一个合理的ramp-up period 的规则就是让初始点击率接近平均点击率。当然,也许需要运行一些测试来确定合理访问量。

使用 JMeter 进行压力测试
https://www.cnblogs.com/stulzq/p/8971531.html

JMeter使用CSV数据集

jmeter参数化、添加变量、生成随机数和导入csv文件数据
https://blog.csdn.net/zha6476003/article/details/80157874


BeanShell Java脚本

BeanShell是一种完全符合Java语法规范的脚本语言,并且又拥有自己的一些语法和方法;
BeanShell是一种松散类型的脚本语言(这点和JS类似);
BeanShell是用Java写成的,一个小型的、免费的、可以下载的、嵌入式的Java源代码解释器,具有对象脚本语言特性,非常精简的解释器jar文件大小为175k。
BeanShell执行标准Java语句和表达式,另外包括一些脚本命令和语法。

BeanShell 官网
http://www.beanshell.org/

beanshell / beanshell
https://github.com/beanshell/beanshell

Jmeter有哪些地方可以使用 Bean Shell?
定时器:  BeanShell Timer
前置处理器:BeanShell PreProcessor
采样器:  BeanShell Sampler
后置处理器:BeanShell PostProcessor
断言:   BeanShell断言
监听器:  BeanShell Listener

JMeter 中可以在请求前增加预处理器(PreProcessor),在请求后增加后处理器(PostProcessor)

比如我们想让变量 randomOption 是字符串 cat, dog, parakeet 三者中的随机一个,可以这样写:

String[] query = new String[]{"cat", "dog", "parakeet"};
Random random = new Random();
int i = random.nextInt(query.length);
vars.put("randomOption",query[i]);

Jmeter之Bean shell使用(一)
https://www.cnblogs.com/puresoul/p/4915350.html


JMeter 中 BeanShell 调用Java的三种方式

jar包

用法:
把需要的工具类打成 jar 包,放在 %JMETER_HOME%/lib/ext 目录下
import 类名; 即可使用

import com.MD5;

String strMd5 = MD5.GetMD5Code("123456");

class文件

用法
addClassPath(“ class 文件所在目录”);
import 类名;

addClassPath("C:\\");  //"可以是父级目录或者祖先级目录"
import com.MD5;

String strMd5 = MD5.GetMD5Code("123456");

java文件

语法
source(" java 文件路径")

source("E:\\eclipse\\workspace\\MD5\\src\\jmeter\\MD5.java");
// source("MD5.java");  //文件位于 jmeter bin 目录下

String strMd5 = MD5.GetMD5Code("123456");

【JMeter】Beanshell 调用 java 代码的三种方式
https://blog.csdn.net/lijing742180/article/details/86213875


JMeter 中使用 BeanShell 设置签名

Jmeter通过beanshell对http消息进行签名
https://www.cnblogs.com/zgq123456/articles/11146443.html


Mac brew 安装 JMeter

brew install jmeter

brew install jmeter --with-plugins
默认安装到 /usr/local/Cellar/jmeter/5.0
同时会有 /usr/local/bin/jmeter 链接到 /usr/local/Cellar/jmeter/5.0/bin/jmeter

运行JMeter图形界面

运行 /usr/local/Cellar/jmeter/5.0/bin/jmeter
或 /usr/local/bin/jmeter
由于启动命令已安装到 /usr/local/bin 目录下,所以在任意目录执行 jmeter 即可启动JMeter界面

~: jmeter
================================================================================
Don't use GUI mode for load testing !, only for Test creation and Test debugging.
For load testing, use NON GUI Mode:
  jmeter -n -t [jmx file] -l [results file] -e -o [Path to web report folder]
& increase Java Heap to meet your test requirements:
  Modify current env variable HEAP="-Xms1g -Xmx1g -XX:MaxMetaspaceSize=256m" in the jmeter batch file
Check : https://jmeter.apache.org/usermanual/best-practices.html
================================================================================

异常

java.io.IOException: Connection reset by peer

这个错误和 java.io.IOException: Broken pipe 差不多,也是一端主动关闭了连接,另一端再发送数据时就报这个错。
如果一端的Socket被关闭(或主动关闭,或因为异常退出而 引起的关闭),另一端仍发送数据,发送的第一个数据包引发该异常(Connect reset by peer)。

常见的原因
比如 nginx 网关设有超时时间,超时时间内后端服务没有返回,网关主动断开了连接,等后端服务处理完请求发送响应时,就会报这个错。
比如如果发起一个http请求,但是这个响应很慢,然后客户端关闭了连接,服务端发送消息体的时候,发现连接被关闭了,会抛出这个异常

java.io.IOException: Connection reset by peer
        at sun.nio.ch.FileDispatcherImpl.writev0(Native Method) ~[?:1.8.0_181]
        at sun.nio.ch.SocketDispatcher.writev(SocketDispatcher.java:51) ~[?:1.8.0_181]
        at sun.nio.ch.IOUtil.write(IOUtil.java:148) ~[?:1.8.0_181]
        at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:504) ~[?:1.8.0_181]
        at org.xnio.nio.NioSocketConduit.write(NioSocketConduit.java:184) ~[xnio-nio-3.3.8.Final.jar!/:3.3.8.Final]
        at io.undertow.server.protocol.http.HttpResponseConduit.write(HttpResponseConduit.java:647) ~[undertow-core-1.4.26.Final.jar!/:1.4.26.Final]
        at org.xnio.conduits.AbstractStreamSinkConduit.write(AbstractStreamSinkConduit.java:55) ~[xnio-api-3.3.8.Final.jar!/:3.3.8.Final]
        at org.xnio.conduits.ConduitStreamSinkChannel.write(ConduitStreamSinkChannel.java:158) ~[xnio-api-3.3.8.Final.jar!/:3.3.8.Final]
        at io.undertow.channels.DetachableStreamSinkChannel.write(DetachableStreamSinkChannel.java:179) ~[undertow-core-1.4.26.Final.jar!/:1.4.26.Final]
        at io.undertow.server.HttpServerExchange$WriteDispatchChannel.write(HttpServerExchange.java:2070) ~[undertow-core-1.4.26.Final.jar!/:1.4.26.Final]
        at org.xnio.channels.Channels.writeBlocking(Channels.java:152) ~[xnio-api-3.3.8.Final.jar!/:3.3.8.Final]
        at io.undertow.servlet.spec.ServletOutputStreamImpl.writeTooLargeForBuffer(ServletOutputStreamImpl.java:198) ~[undertow-servlet-1.4.26.Final.jar!/:1.4.26.Final]
        at io.undertow.servlet.spec.ServletOutputStreamImpl.write(ServletOutputStreamImpl.java:146) ~[undertow-servlet-1.4.26.Final.jar!/:1.4.26.Final]

java.io.IOException: Broken pipe 断开的管道

断开的管道 Broken pipe 异常一般由于 tcp连接一方关闭了连接,另一方继续写入数据。

可能的原因:
客户端由于某种原因断开了连接(比如读取超时,比如网关设置了60秒超时,超过60秒后网关直接返回超时并断开连接),而这时候服务器还在处理请求,它并不知道客户端已经断开了连接,处理完请求后再将处理结果发给客户端,就 broken pipe 了;
客户端读取超时关闭了连接,这时候服务器端再向客户端已经断开的连接写数据时就发生了broken pipe异常!

注意,并不是只有超时才会导致这个问题,只要是连接断开,再往这个断开的连接上去执行写操作,都会出现这个异常,客户端超时断开只是其中的一种情况

java.io.IOException: Broken pipe
https://stackoverflow.com/questions/15785175/java-io-ioexception-broken-pipe/15785439

java.io.IOException 断开的管道 解决方法 ClientAbortException: java.io.IOException: Broken pipe
https://blog.csdn.net/zqz_zqz/article/details/52235479

java.io.IOException: UT010029: Stream is closed

因为一个流关闭了但是你又试着使用它就会报这个异常

https://stackoverflow.com/questions/38692035/java-io-ioexception-ut010029-stream-is-closed

Failed to invoke @ExceptionHandler method: public com.nio.common.web.HttpResponse com.nio.common.web.ErrorHandler.handleAllException(java.lang.Exception,javax.servlet.http.HttpServletRequest)
java.io.IOException: UT010029: Stream is closed
at io.undertow.servlet.spec.ServletOutputStreamImpl.write(ServletOutputStreamImpl.java:137) ~[undertow-servlet-1.4.26.Final.jar!/:1.4.26.Final]
at com.fasterxml.jackson.core.json.UTF8JsonGenerator._flushBuffer(UTF8JsonGenerator.java:2039) ~[jackson-core-2.8.11.jar!/:2.8.11]
at com.fasterxml.jackson.core.json.UTF8JsonGenerator.flush(UTF8JsonGenerator.java:1051) ~[jackson-core-2.8.11.jar!/:2.8.11]
at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:953) ~[jackson-databind-2.8.11.3.jar!/:2.8.11.3]
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:285) ~[spring-web-4.3.22.RELEASE.jar!/:4.3.22.RELEASE]
at org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:106) ~[spring-web-4.3.22.RELEASE.jar!/:4.3.22.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:231) ~[spring-webmvc-4.3.22.RELEASE.jar!/:4.3.22.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:174) ~[spring-webmvc-4.3.22.RELEASE.jar!/:4.3.22.RELEASE]
at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:81) ~[spring-web-4.3.22.RELEASE.jar!/:4.3.22.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:113) ~[spring-webmvc-4.3.22.RELEASE.jar!/:4.3.22.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver.doResolveHandlerMethodException(ExceptionHandlerExceptionResolver.java:385) ~[spring-webmvc-4.3.22.RELEASE.jar!/:4.3.22.RELEASE]
at org.springframework.web.servlet.handler.AbstractHandlerMethodExceptionResolver.doResolveException(AbstractHandlerMethodExceptionResolver.java:59) ~[spring-webmvc-4.3.22.RELEASE.jar!/:4.3.22.RELEASE]
at org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.resolveException(AbstractHandlerExceptionResolver.java:132) ~[spring-webmvc-4.3.22.RELEASE.jar!/:4.3.22.RELEASE]
at org.springframework.web.servlet.handler.HandlerExceptionResolverComposite.resolveException(HandlerExceptionResolverComposite.java:76) ~[spring-webmvc-4.3.22.RELEASE.jar!/:4.3.22.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.processHandlerException(DispatcherServlet.java:1222) ~[spring-webmvc-4.3.22.RELEASE.jar!/:4.3.22.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1034) ~[spring-webmvc-4.3.22.RELEASE.jar!/:4.3.22.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:984) ~[spring-webmvc-4.3.22.RELEASE.jar!/:4.3.22.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901) ~[spring-webmvc-4.3.22.RELEASE.jar!/:4.3.22.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) ~[spring-webmvc-4.3.22.RELEASE.jar!/:4.3.22.RELEASE]

NoRouteToHostException

在使用Jmeter压测时,遇到日志中有大量的错误:
Non HTTP response code: java.net.NoRouteToHostException/Non HTTP response message: 无法指定被请求的地址 (Address not available)
Non HTTP response code: java.net.NoRouteToHostException/Non HTTP response message: Can’t assign requested address (Address not available)

原因:Jmeter 发压机的端口不够用,即客户端的端口不够用。

解决:
一、Linux 上
(1) 修改 ipv4.ip_local_port_range,增大可用端口范围
cat /proc/sys/net/ipv4/ip_local_port_range 查看可使用的端口范围,默认值是 net.ipv4.ip_local_port_range = 32768 61000
改为 net.ipv4.ip_local_port_range = 1024 65535
执行:sudo sysctl -p ,使设置立即生效。

(2) 修改 /etc/sysctl.conf 编辑文件,加入以下内容:
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 30
然后执行 sudo sysctl -p 让参数生效。
net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;
net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。
net.ipv4.tcp_fin_timeout 修改系統默认的 TIMEOUT 时间

二、Mac OS 上
参考 MAC使用笔记 Mac OS 最大连接数和端口范围配置

Jmeter 遇到的问题:rc=”Non HTTP response code: java.net.NoRouteToHostException” rm=”Non HTTP response message: Cannot assign requested address”
http://ferriswheelgyh.blogspot.com/2016/12/jmeter-rcnon-http-response-code.html

JMeter 进行压力测试
https://my.oschina.net/shichangcheng/blog/1560864

How to avoid a NoRouteToHostException?
https://stackoverflow.com/questions/1572215/how-to-avoid-a-noroutetohostexception


上一篇 QPS和TPS

下一篇 OLTP和OLAP

阅读
评论
2,807
阅读预计13分钟
创建日期 2018-12-08
修改日期 2020-07-06
类别

页面信息

location:
protocol:
host:
hostname:
origin:
pathname:
href:
document:
referrer:
navigator:
platform:
userAgent:

评论