侧边栏壁纸
博主头像
一朵云的博客博主等级

拥抱生活,向阳而生。

  • 累计撰写 67 篇文章
  • 累计创建 25 个标签
  • 累计收到 7 条评论

目 录CONTENT

文章目录

JMeter -- 记一次协助开发跑量

一朵云
2023-09-27 / 1 评论 / 0 点赞 / 8025 阅读 / 5745 字

背景:

  最近投放业务为了优化游戏广告投放效果,要求我们接入腾讯的“一方数据”。功能是开发好了,但经沟通,考虑历史数据也需要上传,好几百万的数据(激活、注册、登录、付费行为)。

  一波沟通,这活我接下了。我考虑基于linux服务器,使用jmeter去跑量,接着就发生了下面一系列的“趣事”,且听我娓娓道来。

环境:

linux 系统 8核 16G
已配置 JDK 1.8
已配置 JMeter 环境变量
csv 文件 登录事件 100w行

第一次尝试:

  直接100w个线程,3333秒启动完,心想tps大概每秒30个,应该没啥问题,慢慢跑它9个多小时。

image-1695809064512

image-1695809541331

  结果,跑到3w多线程后,jmeter毫无征兆的结束了。

  查看脚本执行期间,云服务器的压力情况,并未出现达到 linux 瓶颈的情况。

  查看 jmeter.log 日志,末尾未看到异常信息,但查到了个内存溢出outofMemoryError的信息。

第二次尝试:

  调整jmeter配置文件,增加jvm内存。
  进入jmeter 的bin目录下,执行
  vim jmeter 命令(注意不是 jmeter.sh 文件)
  修改HEAP 的值,根据机器的性能设置,这里我调整到8g。

image-1695812923912

  csv文件移除已执行的行数,对应调整线程组的线程数与Ramp-Up时间,最终目的还是以tps 30/s 去请求。

  结果,还是跑到3w多线程后,jmeter又毫无征兆的结束了,这下jmeter.log日志内没看到任何error、Exception的关键字了,挠头ing …

排查思路:

1、端口问题?

  起初,我怀疑linux端口被占用完了,但百度一查linux有6万多个端口,我只跑到3万就挂了!接着各种搜索,有人说可能是 linux 内核限制了,于是一顿检查。

#在压测时查看服务器和客户机等待的端口数量
netstat -na|grep TIME_WAIT | wc -l

#查看开发的端口范围
cat /proc/sys/net/ipv4/ip_local_port_range
#如果范围很小,则通过echo进行修改
echo “1024 65535” > /proc/sys/net/ipv4/ip_local_port_range

#查看端口释放后的等待时间
cat /proc/sys/net/ipv4/tcp_fin_timeout
#调低端口释放后的等待时间, 默认为60s, 修改为15~30s
echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout

#查看释放的time_wait端口是否可给新连接使用
cat /proc/sys/net/ipv4/tcp_tw_resue
#修改tcp/ip协议配置, 通过配置/proc/sys/net/ipv4/tcp_tw_resue, 默认为0, 修改为1, 释放TIME_WAIT端口给新连接使用。
echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse

#查看tcp/ip协议配置是否支持快速回收socket资源
cat /proc/sys/net/ipv4/tcp_tw_recycle
#修改tcp/ip协议配置,快速回收socket资源, 默认为0, 修改为1.
echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle

#执行:sysctl -p ,使设置立即生效。
sysctl -p

结论:

  经过上述查询,发现linux内核都已经完成优化配置了,所以端口占用问题排除了。

2、脚本问题?

  接着,我开始反思Http取样器中 KeepAlive 勾选项的作用。

  理论情况下,开启KeepAlive选项可以优化性能,大致意思:发起HTTP请求时,需要建立TCP连接,对于普通非keep-alive请求,即不包含请求头Connection: keep-alive的请求,请求完成后,会关闭该TCP连接,再次发起同类请求时,需要再次建立TCP连接,高并发的情况下,会增加服务器资源消耗,对于keep-alive请求,则会告诉服务器,HTTP请求结束后,在条件允许的情况下,保持TCP连接,下次发送请求时,使用上次建立的TCP连接进行数据传输。

  会不会是保持了太多TCP连接,导致未及时释放资源,最终导致资源不足,致使 jmeter异常结束呢?去掉 KeepAlive ,再试试就知道了。

第三次尝试:

  csv文件再次移除已执行的行数,调整对应线程组的线程数与Ramp-Up时间,Http取样器去掉“KeepAlive”选项,还是以tps 30/s 去请求。

  结果:这次跑到2w多次请求就挂掉了,说明也不是这个问题。

排查思路:

  这下可以排除 jmeter运存不足、linux 端口不足、jmeter 中 KeppAlive 选项问题。

  继续挠头反思,这脚本和之前那些脚本对比,最大的区别就是:量起来了,线程量起来了(线程数)

  经百度查询,Linux线程的最大限制是每个进程的最大限制的一半。在Linux系统里,一个进程可以分配最多64000字节的内存,其中最多可以有32000个线程。(卧槽,怎么这么像我的情况。)

  我怀疑jmeter线程释放速度比jmeter启动线程速度慢,最终导致线程达到瓶颈,线程数不足。

第四次尝试:

  缩减 jmeter 线程数,采用循环的方式运行。

image-1695818359053

  csv文件再次移除已执行的行数,调整对应线程组的线程数与Ramp-Up时间,Http取样器勾上“KeepAlive”选项,还是以tps 30/s 去请求。

image-1695818437361

  结果: jmeter 脚本终于正常运行了。

image-1695866709249

image-1695866806461

总结:

  压测线程数过大时,可采用分布式压测,不可盲目觉得线程越多越好,设置过大的线程数。

  像我的情况,其实并不是为了并发压测,只为了稳定的跑量,那就可以考虑配合循环次数,结合公式:并发数 =(线程数*循环次数)/ ramp-Up 进行 tps 的设置即可。

  至此,本篇踩坑总结结束,吃一垫长一智。

0

评论区