Jmeter的客户端实现与Keep-Alive

没有时间的朋友直接读结论即可。

0. 结论

  1. 当客户端实现为Java,使用Keep-alive时

    1. Vuser越大,保持的时间越短,且tcp连接会断不完全,造成双倍甚至3倍Vuser连接的情况。

    2. Vuser越小,保持的时间越长,但过几分钟甚至10几分钟后,tcp连接还是会变。

      这个现象的原因不详。

  2. 当客户端实现为HC4,使用Keep-alive时

    1. 修改jmeter.properties的httpclient4.time_to_live的数值即可保持连接时间。单位为ms
    2. 当httpclient4.time_to_live的值为0时,为永久保持。
    3. Jmetr 5.3以下的版本,默认保持间为2s,5.3以上版本更改为60s。

以上的结论都基于服务端快速响应,不涉及超时时间等问题。

1.缘起

1.1 起因

起因是我需要使用Jmeter发送HTTP请求,并且保持长连接。

再细化下需求,保持多久的长连接?

  1. 固定时长,到时间自动释放
  2. 永久时长,只要不空闲超时

1.2 初步尝试

既然要做Jmeter的HTTP长连接,肯定就是要勾选keep-alive

接着就去进行测试压测了,结果发现压测的端口在不断的变化,并没有实现一个长连接的效果。

查看Jmeter压力机 查看具体端口

  • windows的话使用 netstat -ano | find "ip端口" | find "ESTABLISHED" | find "IP地址"

  • linux的话使用 ss -ant | grep "ip端口" | grep "ES" | grep"IP地址"

只看端口变化还是有一定的问题,遂抓取压测时候的包查看。

抓包命令:

  • windows 使用wireshark抓包
  • linux 使用 tcpdump tcpdump -i 网卡名 -w 保存的报文名字.pcap 之后使用wireshark解析

一看果然,只有在一个时间段进行了保持连接,之后客户端就主动释放了

看下图,我只有3个Vuser,如果一直保持了连接,是不可能建立出7个连接的。

观察了下时间,正好2秒释放掉的。

如法炮制,我观察了好几个tcp连接,都是2秒钟就主动释放了。

所以有理由推测,这个保持时间是个可配置项。

1.3 Jmeter客户端实现

想到时间可以配置,我来到了HTTP的高级页面,在这里,发现了HTTP的客户端实现方式。

  • HttpClient4 简称HC4
  • Java
  • 空

为什么会有3个客户端实现方式呢?我查询了官方文档,贴在下面。

Jmeter客户端3种实现方式官方文档

简单的来说就是:

  • HC4 实现 -----多数情况都在使用的,功能丰富且细化。
  • Java实现 -----在实现HTTP时候会有限制
  • 空 ---- 读取配置文件来决定使用什么,默认是HC4

1.4 Java+keep-alive?

之前使用的是HC4+keep-alive 无法一直保持,那么Java + keep-alive呢?抱着这个想法,我测试了下。

Vuser 我依然给了3个,下面是线程组配置

结果非常惊喜,抓包查看可以一直保持!

此处其实是有问题的,先埋个坑。

2. 压力测试

2.1 测试

基于前面的测试报文,很开心,于是直接将这种方式进行了压力测试。

设置Vuser为200,诡异的事情发生了,压力机报了好多异常错误信息,查看jmeter.log也没有报错信息。一时间不知所措。

日志就不截图了,和上图一样。

于是,我开始抓包,抓包看。

结果发现长连接没有保持住,能过滤出tcp的连接好几百,正常应该就是200个连接一直在保持。

但是报文还是看出几个点:

  • tcp保持时间:有的保持了2s,有的10s,有的15s,没有规律,
  • tcp释放:每次都是由Jmeter主动释放(主动发送Fin)。

查看压力机的端口使用情况:

明显是TIME_WAIT过多,为了更进一步的确定,我产生了jtl 和 debug级的log。

2.1 产生jtl和debug级日志

修改日志等级

修改bin/log4j2.xml 将info 修改为debug

产生jtl和log

linux 执行命令 jmeter -n -t ./xxxxx.jmx -l test.jtl -j debug.log

使用GUI的Jmeter查看jtl

在测试计划里添加 查看结果树,导入产生的 jtl

确实是产生了好多失败的请求,查看某一个请求,发现HTTP的Message为 无法分配请求地址。

这也侧面证明了确实是端口不够用,导致无法请求了。

2.3 迷惑点

到目前为止,我们需要解决的问题

  1. HC4 的长连接时间 怎么设置?
  2. 永久连接(使用Java实现)为什么会主动释放tcp?

3. stack overflow&看源码

查看Jmeter的源码源码和版本下载地址,

3.1 HTTPJava

首先我去看了使用Java实现HTTP? 直接看HTTPJavaImpl.java即可

在论坛看到这么个帖子

我的web后台是没有设置60s超时时间的,查看http的报文也没有max的参数。-----至此,问题无法解决

配置参数

通过HTTPJavaImpl.java可以看出,只有httpsampler.obey_contentlength和http.java.sampler.retries参数是影响JavaHttp的实现的。

通过字面和Jmeter手册

  • httpsampler.obey_contentlength : 服从内容长度
  • http.java.sampler.retries :重试次数,默认为0,不进行重试

无关紧要,往下走。

sample函数

sample为核心函数,负责创建连接,接收信息的

结合debug的日志,我们几乎可以断定就是在块发生了IO异常。

谁抛出的异常呢?应该是setupConnection函数

setupConnection函数

猜测是这里出了问题。

看源码也是没能找到为什么java的会主动释放tcp。影响java的http实现就是2个参数,之后又看到了一个bugbug55023,说的是一个其他参数影响了Java实现的HTTP的吞吐值,这里怀疑也可能是某个未知bug。并且论坛在讨论相关实现的时候都在推荐HC4,不推荐JAVA(实现的功能少)。

至此,我仍然没有找到为什么在使用JAVA实现 + keep-alive时候,会不断的释放+新建TCP连接,如果有大佬清楚,麻烦留个言,讨论下

3.2 HTTP HC4

既然JAVA的路走不通了,转回头研究下HC4的实现

查看Jmeter的配置文件jmeter.properties发现几个参数很是可疑。

378 httpclient.timeout
437 httpclient4.idletimeout
445 httpclient4.time_to_live

去手册查看得知

也即是

  • httpclient.timeout : 这个是socket的连接超时 时间,默认0是不超时的
  • httpclient4.idletimeout:在服务器没有发keep-alive的情况下,http的连接超时时间,也就是在服务器没有发keep-alive的情况下,还能保持多少秒。默认是不保持。
  • httpclient4.time_to_live: http的生存时间,默认时间60s。

这个httpclient4.time_to_live好像是决定的参数,看了Jmeter的配置,怎么是2000,不是6000呢?

2000? 想起了第一次抓包的tcp时间就是2s。看来就是这个参数了。那怎么是2000,不是6000呢?

我查看了Jmeter版本,原来本地用的是5.2.1版本,而5.3.1时候Jmeter将这个视作bug进行更改了。

bug64289、变更记录

接下来就是实验,改httpclient4.time_to_live之后确实可以固定长度的连接时长,但是如何大的时长和永久呢?

TIME_TO_LIVE

看了下Jmeter源码HTTPHC4Impl.java,发现了下面的语句。

这个语句很有意思,这定义了一个 **int **类型的 int类型的最大值是 2 的 31 次方 - 1 = 2147483648 - 1 = 2147483647 Integer.MIN_VALUE = -2147483648

2147483647/1000/3600/24 = 24.8 也就是说可以保持24.8天,已经满足使用了。

但是我们仍往下查看,发现只是将TIME_TO_LIVE传给了HttpClientBuilder

接下来去看下HttpClient的源码 HttpClientBuilder类。

可以看到,HC4是以long进行接收的,但是Jmeter把范围缩小了,变为了int。

但是还是没解决永久的连接啊,于是突发奇想,试试值为0呢,没想到竟然可以使用,

我测试了半天发现仍可以保持连接,其实感觉也就是不合法的值为MAX_VALUE了,这个属于猜测,我没有找到异常数值的相关的代码。

小结

要保持长连接选择 HC4 实现,不要选择JAVA,连接时长设置httpclient4.time_to_live该参数。

在回过头看看官方的解释文档,无法控制如何重新使用连接,这句话好像有所解释,但是我理解的不深入。所以还是使用HC4吧,别用Java了

参考

文章1

Jmeter的客户端实现与Keep-Alive的更多相关文章

  1. JMeter 分布式部署

    Jmeter 是java 应用,对于CPU和内存的消耗比较大,使用单台机器模拟以千计的并发用户就有些力不从心,甚至会引起JAVA内存溢出错误. 为了让jmeter工具提供更大的负载能力,jmeter短 ...

  2. 不制作证书是否能加密SQLSERVER与客户端之间传输的数据?

    不制作证书是否能加密SQLSERVER与客户端之间传输的数据? 在做实验之前请先下载network monitor抓包工具 微软官网下载:http://www.microsoft.com/en-us/ ...

  3. 【转】jmeter 进行java request测试

    本周使用jmeter进行一个远程dubbo接口的性能测试,因为没有访问页面,本来开发可以写一个页面,进行http请求的调用,不过已经看到jmeter可以直接对java request进行测试,所以尝试 ...

  4. 性能测试四十七:jmeter性能监控工具ServerAgent

    在liunx压力机进行压测的时候,可以在widows下开一个jmeter,只进行监控用,不产生压力,监控效果和dstat差不多 jmeter安装客户端插件 把工具放到服务端任意目录并解压,我这里放到了 ...

  5. Jmeter远程测试

    11.3 详解JMeter远程测试(1) 2012-04-09 09:14 温素剑 电子工业出版社 字号:T | T 综合评级: 想读(7)  在读(2)  已读(0)   品书斋鉴(0)   已有9 ...

  6. JMeter学习(十二)分布式部署(转载)

    转载自 http://www.cnblogs.com/yangxia-test Jmeter 是java 应用,对于CPU和内存的消耗比较大,因此,当需要模拟数以千计的并发用户时,使用单台机器模拟所有 ...

  7. Jmeter进行性能测试时多台负载机的配置方法

    参考:https://blog.csdn.net/russ44/article/details/54729461 Jmeter进行性能测试时多台负载机的配置方法 Jmeter 是java 应用,对于C ...

  8. [Jmeter]用Jmeter做压力测试(分布式)

    Jmeter 是Java应用,对于CPU和内存的消耗比较大,因此,当需要模拟数以千计的并发用户时,使用单台机器模拟所有的并发用户就有些力不从心,甚至会引起JAVA内存溢出错误.为了让jmeter工具提 ...

  9. JMeter基础之-使用技巧

    在这此对新版本jmeter的学习+温习的过程,发现了一些以前不知道的功能,所以,整理出来与大分享.本文内容如下. 如何使用英文界面的jmeter 如何使用镜像服务器 Jmeter分布式测试 启动Deb ...

随机推荐

  1. [leetcode]109. Convert Sorted List to Binary Search Tree链表构建二叉搜索树

    二叉树的各种遍历方式都是可以建立二叉树的,例如中序遍历,就是在第一步建立左子树,中间第二步建立新的节点,第三步构建右子树 此题利用二叉搜索树的中序遍历是递增序列的特点,而链表正好就是递增序列,从左子树 ...

  2. ESP8266-01烧录神器,ESP8266-01S烧录程序 ESP-01烧录固件

    如下图所示:"USB转ESP8266",在某宝上可以买到,但是建议买两个! 为什么要买两个呢?一个用于测试AT指令.接电呀什么的.另外一个通过焊接就可以改造成烧录器了. 引脚说明: ...

  3. Spring Cloud Sleuth链路监控应用(十四)

    https://docs.spring.io/spring-cloud-sleuth/docs/2.2.5.RELEASE/reference/html/ 一.Sleuth介绍   为什么要使用微服务 ...

  4. vue中携带token以及发送ajax

    在项目中基本登录都会存在token,而我们也就需要在每次发送ajax的时候就必须携带他.从而最有效的办法,就是在设置请求头携带token,这样设置一次后面的每一次都会携带着这个token. 一:设置请 ...

  5. 远程分支删除后,git branch -a还能看到的解决方法

    详情https://www.cnblogs.com/wangiqngpei557/p/6058115.html 大家在删除远程分支后 git branch -a 还是可以看到已删除的远程分支,时间一长 ...

  6. dede织梦技巧:教你彻底解决dede按权重排序的问题(转)

    dede排序对网站来说一直存在问题,默认是按照最新发布时间排序.这样排序有个问题,一旦更新之后即被视为最新发布,于是原本做好的排序瞬间就乱了. 这种时候,按权重排序是个很好的选择,但按权重排序到处存在 ...

  7. 你知道 react-color 的实现原理吗

    一.前言 ReactColor 是一个优秀的 React 颜色选择器组件,官方给了多种布局供开发者选择. 笔者常用的主题为 Sketch,这种主题涵盖了颜色面板.推荐色块.RGB颜色输入等功能,比较完 ...

  8. 并发编程--锁--Lock和Synchronized

    说说对于 synchronized 关键字的了解? synchronized关键字解决的是多个线程之间访问资源的同步性: synchronized 关键字可以保证被它修饰的方法或者代码块在任意时刻只能 ...

  9. 多年经验总结,写出最惊艳的 Markdown 高级用法

    点赞再看,养成习惯,微信搜索[高级前端进阶]关注我. 本文 GitHub https://github.com/yygmind 已收录,有一线大厂面试完整考点和系列文章,欢迎 Star. 最近在学习的 ...

  10. 你还不知道mysql中空值和null值的区别吗?

    前言 最近发现带的小伙伴写sql对于空值的判断方法不正确,导致程序里面的数据产生错误,在此进行一下整理,方便大家以后正确的判断空值.以下带来示例给大家进行讲解. 建表 create table tes ...