又是压测惹的祸,错误姿势引发JMeter+InfluxDB写入问题

最近有一段时间没搞压测了,团队里的同学也在搭建线上压测平台,想着今年七、八月份能够在业务压测中线上实战一把。

这段时间正好在验证新压测系统,也和旧的压测平台做一些对比验证。讲道理旧系统已经比较稳定,应该不会出什么问题。

然鹅,当你以为没有问题的时候,问题就来了。

全链路压测小队和测试的同学反馈,用旧系统压着压着,就会出现超时的情况,中间没有任何特殊操作。

这就很奇怪了,旧系统已经稳定操作那么久,我自己也没遇到这个情况。

那么,这背后到底发生了什么呢?

问题现象

最直接的问题现象,就是这个异常。

图片

可以看出,JMeter在测试结束时会将请求相关的metrics写入到InfluxDB,而在getResult等到返回时,出现了3s的SocketTimeoutExcetpion

中间没有任何特殊变更,就是一直在做压测对比实验。

问题分析

这么看来,中间出现问题的地方可能有很多,从肉鸡请求到数据持久化到InfluxDB中,可能是网络、SLB、连接池、慢SQLInfluxDB负载等。

既然可能性比较多,那就从最直接的异常点开始反查。

InfluxDB

既然出现3s超时,而且是在getResult阶段,那么比较大概率是InfluxDB的问题,先排查该时间段InfluxDB的状态。

图片

从基础的负载指标来看,好像一切正常,基本可以判断不是负载的问题。

再顺着监控往下查,突然看到这样一段内容。

图片

emmmmm。。。。

Series类似于关系型数据库里的数据行,每一条Series类似于数据表中某个tag在某个时间点的数据,有4000W+倒是有可能,毕竟是压测环境在用,压测数据比较多,逻辑上能接受。

但是这个Measurements类似于关系型数据库里的表,有。。。1600W+。。。这好像就不太对劲了。。

抱着试一试的态度,我把InfluxDB的旧库删了,重建了压测库,初始化完也只有2个Measurements,这才符合预期。

那么问题来了,肉鸡和压测控制面同样的代码啥都没改,之前一点问题都没有,这次怎么搞出这么多Measurements呢?

先来简单了解一下InfluxDB的基础知识。

InfluxDB中的数据

InfluxDB是一种时间序列数据库,每一条数据都是一个数据点,数据点由不同的部分组成。

图片

这么看可能有点难以理解,举个栗子。

例如,在监控环境中,用一个measurement来存储服务器监控数据,其中每个数据点使用tag来标识服务器的名称、操作系统版本、数据中心等信息,使用多个field来记录CPU、内存、网络等指标。这样,可以方便地查询、过滤和计算特定标签和字段的数据。

Measurements

了解的InfluxDB的基础知识后,顺着上面的疑问,先看看这1000多万个Measurements都是啥。

图片

????

怎么Measurement的名字都是JSON格式的字符串,而且内容还不完整?

但是不管怎么说,至少有了方向,在InfluxDB数据写入模块的代码里搜搜JSON字符串中的关键字,应该就能找到问题触发的代码,debug一把应该就能知道原因了。

但是。。

图片

难道和代码无关?

JMeter脚本

再翻看了所有可能和压测有关的代码、脚本后,最终我找到了这段内容的原始出处。

图片

对,在JMeter的断言脚本里,脚本逻辑也很简单,在程序返回非2XX时,会把responseBody记录下来,格式化后并打印出来,记录到AssertionResult里。

好像也没什么不妥,但是通过异常信息反推,还是能发现一些端倪。

最终异常和InfluxDB有关,InfluxDB会记录请求异常时的结果数据,中间能产生关联的方式只有通过AssertionResult

异常的Measurement名称与格式化后的字符串并不完全相同,缺少了”assertion failed! response data: %s,并且还多了一个}。

我们一个一个来看。

JMeter InfluxDB模块

先来看第一点,JMeter执行完一次采样请求后,会处理其结果。

在我们的场景中,因为使用的InfluxDB模块记录采样数据,最终会进入到InfluxdbBackendListenerClient.handleSampleResults()中。

图片

该方法会将采样结果中的关键信息进行提取和保存。

图片

在提取采样结果的过程中,会区分采样请求是否成功,如果不成功,就会创建ErrorMetric

图片

在构造过程中,responseCode还未设置,值为空字符串,而我们在JMeter断言脚本中,采样请求失败时设置了AssertionResult.setFailureMessage,因此会走入第一个逻辑分支,responseCoderesponseMessage均会被赋值。

最终,创建成功的ErrorMetric会被放入HttpMetricSender中进行请求,发送给InfluxDB

图片

在这个过程中,你会发现存入HttpMetricSender中的待发送metric是一个拼接好的字符串,而里面就有responseCoderesponseMessage

那这就奇怪了,为什么要组装成一个字符串交给HttpMetriceSender呢?

InfluxDB Line Protocol

InfluxDB Line Protocol是一种轻量级文本协议,用于向InfluxDB中写入数据。

相对于其他协议,Line Protocol更加简单易用,以单行形式描述一个数据点,适用于以时间序列方式进行的数据采集和存储场景。

其语法也比较简单,以约定好的格式进行单行写入即可。

// Syntax<measurement>[,<tag_key>=<tag_value>[,<tag_key>=<tag_value>]] <field_key>=<field_value>[,<field_key>=<field_value>] [<timestamp>]
// ExamplemyMeasurement,tag1=value1,tag2=value2 fieldKey="fieldValue" 1556813561098000000

图片

所以,上文提到的ErrorMetric会拼接成一个Line Protocol协议格式的文本数据,由HttpMetriceSender发送给InfluxDB进行写入。

再回到下面这张图,我们可以看看具体写入的tagfield是怎样的。

图片

fagent,application={application},transaction={transaction},responseCode={responseCode},responseMessage={responseMessage},userTag={userTag} metric_count={count} {timestamp}

其中,tag部分到userTag截止,field只有metricCount,最后加上时间戳,这样看好像也并没有什么问题。

那我们再回到这张异常measurement图。

图片

里面的异常measurement的名字,都是前文JMeter断言脚本中的一部分。

图片

而被截断的部分,正好是在断言脚本中response data: %s的后面。

那么,有没有一种可能,response data记录的是接口的实际返回数据,而接口返回的是格式化后的json数据,如果该数据中有换行符,又被整合到拼接到ErrorMetric生成的字符串中,按照InfluxDBLine Protocol定义,就会被当成多条数据写入。

举个栗子,顺着上面的数据格式,我们把responseMessage带入进去,即responseMesssage中的response data是一个格式化后的json数据。

假设responseMessage的值为assertion failed! response data: {\n    "code":0,\n    "message":"ok"\n}, not contains: xxx, token: xxx, traceId: xxx

fagent,application={application},transaction={transaction},responseCode={responseCode},responseMessage=assertion failed! response data: {    "code":0,    "message":"ok"}, not contains: xxx, token: xxx, traceId: xxx ,userTag={userTag} metric_count={count} {timestamp}

带入后,由于格式化json中有换行符,最终原本单行的数据,被拆分成4行,而在最后一行中,其格式正好是符合Line Protocol,变成了一条单独写入的行数据,即下面的内容:

}, note contains: xxx, token: xxx, traceId: xxx ,userTag={userTag} metric_count={count} {timestamp}

图片

这正好和我们的现象一致,基本可以断定就是这个问题导致的。

问题根因

综上看来,根本原因是我们的断言脚本中,会在请求状态码非200时,将请求的返回的json异常信息记录到failureMessage中,而JMeter的会将采样异常的请求记录为ErrorMetric,其中包含了断言结果中的错误信息AssertionResult.failureMessage,以Line Protocol写入到InfluxDB的时候,由于格式错误导致新建了大量的measurement,影响了查询性能,导致大量查询3s超时。

解决方法

解决方法其实也很简单。

由于测试的同学确实希望记录采样请求异常时的failureMessage,所以这个内容需要保留。

在保留的同时,对failureMessage进行处理,移除其中的换行符,保证以Line Protocol写入InfluxDB时不会出现格式错误就行。

最终问题也彻底解决。

总结

其实问题并不复杂,主要是中间涉及到的细节点比较多,如果了解InfluxDBLine Protocol,确实很难想到会和这里的写入格式错误有关。

同时,这里也涉及JMeter底层对于异常数据的采集和聚合问题,从逻辑上来说failureMessage可以用作InfluxDB的数据行tag但是如果对其底层不了解的话,也容易带来数据聚合无法收敛的问题,例如异常中包含了唯一键信息。

    总结

如果你对此文有任何疑问,如果你也需要接口项目实战,如果你对软件测试、接口测试、自动化测试、面试经验交流感兴趣欢迎加入我们,加入方式在文章的最后面

  自动化测试相关教程推荐:

2023最新自动化测试自学教程新手小白26天入门最详细教程,目前已有300多人通过学习这套教程入职大厂!!_哔哩哔哩_bilibili

2023最新合集Python自动化测试开发框架【全栈/实战/教程】合集精华,学完年薪40W+_哔哩哔哩_bilibili

测试开发相关教程推荐

2023全网最牛,字节测试开发大佬现场教学,从零开始教你成为年薪百万的测试开发工程师_哔哩哔哩_bilibili

postman/jmeter/fiddler测试工具类教程推荐

讲的最详细JMeter接口测试/接口自动化测试项目实战合集教程,学jmeter接口测试一套教程就够了!!_哔哩哔哩_bilibili

2023自学fiddler抓包,请一定要看完【如何1天学会fiddler抓包】的全网最详细视频教程!!_哔哩哔哩_bilibili

2023全网封神,B站讲的最详细的Postman接口测试实战教学,小白都能学会_哔哩哔哩_bilibili

  总结:

 光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

​​​

​​​

如果对你有帮助的话,点个赞收个藏,给作者一个鼓励。也方便你下次能够快速查找。

如有不懂还要咨询下方小卡片,博主也希望和志同道合的测试人员一起学习进步

在适当的年龄,选择适当的岗位,尽量去发挥好自己的优势。

我的自动化测试开发之路,一路走来都离不每个阶段的计划,因为自己喜欢规划和总结,

测试开发视频教程、学习笔记领取传送门!!

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面我会为您详细讲解 jmeter+influxdb+grafana 的监控实例。 首先,JMeter 是一个用于性能测试的工具,可以进行压力测试、负载测试、功能测试等。它可以模拟多种不同的用户行为,以便评估系统的性能和稳定性。 InfluxDB 是一个高性能的时序数据库,可以存储和查询大量的时间序列数据。它具有高度可扩展性和灵活性,可以轻松地处理海量数据。 Grafana 是一个流行的开源数据可视化工具,可以连接多种数据源并将其可视化。它提供了灵活的图表和仪表板,可以帮助用户更好地理解数据。 下面是 jmeter+influxdb+grafana 监控实例的具体步骤: 1. 安装 InfluxDB 和 Grafana 在官网下载最新版的 InfluxDB 和 Grafana,然后按照官方文档进行安装和配置。 2. 配置 InfluxDB 数据库 在 InfluxDB 中创建一个新的数据库,并为其设置一个名称和一个保存策略。保存策略可以指定数据的保存时间和数据的复制系数。 3. 配置 JMeter 插件 在 JMeter 中安装 InfluxDB 和 Grafana 插件,然后配置插件以连接到 InfluxDB 数据库。 4. 在 JMeter 中添加聚合器 在 JMeter 中添加聚合器,以便收集数据并将其发送到 InfluxDB 数据库中。 5. 创建 Grafana 仪表板 在 Grafana 中创建一个新的仪表板,并添加一个新的数据源。选择 InfluxDB 数据库作为数据源,并输入数据库的详细信息。 6. 创建 Grafana 图表 在 Grafana 中创建一个新的图表,并选择要显示的数据。可以使用不同的图表类型和样式来显示数据。 7. 测试 JMeter 脚本 使用 JMeter 运行测试脚本,并在 Grafana 中查看结果。可以使用 Grafana 的仪表板和图表来分析数据,识别瓶颈和优化性能。 以上就是 jmeter+influxdb+grafana 监控实例的具体步骤。希望可以对您有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值