作者回复: 你好,我们可以回顾一下文中的状态变换表格和状态机,其中每个状态都有成功的条件和失败的条件,具体状态是保存在数据库中的,我们可以通过轮询这一状态,根据结果决定是否执行后续步骤。整个逻辑都是状态机管理的,Agent只负责执行指令。 举个例子,当用户触发一次压测,系统会同时建立三个任务:配置、执行和运行。配置任务在成功完成后会将状态置为BOOTED,失败则置为BOOTERROR。与此同时,执行任务在不断轮询状态,一旦轮询到状态为BOOTED,立刻执行触发逻辑,如果轮询到状态为BOOTERROR,则终止,并取消后续运行任务。运行任务的原理也是一样的。最后,有一个收集任务做兜底清理工作。 值得注意的是,平台的视角是压测的状态管理,并非局限于JMeter的工作状态。
作者回复: 你好,这个agent是一个用Java编写的轻量级Lib,使用Netty与服务器进行通信,自身持有的资源很少。此外,agent所做的工作是低频的,例如:每轮测试中的同一类文件只需要传输一次,各个状态变换时下发的指令也是有限的。唯一比较消耗资源的是结果文件的聚合(消耗CPU)和回传(消耗带宽),但这一操作是在压测结束后异步进行的,因此资源消耗是错时的。 另外,agent的JVM进程和JMeter的JVM进程是隔离的,两者都有自己的堆大小和栈大小控制,只要相加不超过总的内存大小,一般不会互相影响。
作者回复: 你好,你的问题关注的是如何获取压测流量的响应信息,我们的压测平台是通过对接JMeter的“查看结果树”控件来实现的,激活“Save Response Data”,同时勾选“仅错误日志”(一般来说,只有排障时才需要关注详细的响应信息),生成的结果文件以固定的文件名保存,压测平台的服务器会在压测后统一回传至文件存储组件供下载,默认保存7天。当然,由于查看结果树的结果文件是以流的形式实时构建的,因此我们也提供了实时查看的功能,压测平台服务器提供了后端接口,将文件内容实时读取出来,前端得到结果后展示在页面上。 查看结果树本身提供了设置响应数据最大展示大小,以及最大文档大小等参数,基于这些考虑,我们并不需要以抽样的方式获得数据。
作者回复: 你好,启动方式是后者。我们完全放弃了JMeter的分布式执行策略,因此也就不再使用jmeter-server的启动方式,所有JMeter节点都视为是Master由平台统一调度。
作者回复: 你好,我确实早有开源的计划,但因为一些限制暂时无法达成,一旦能够开源,我会及时更新,感谢你的关注
作者回复: 你好,mc工具我不太熟悉,无法提供专业的指导,非常抱歉
作者回复: 你好,如果需要调节QPS,线程数一般适当设大点就行了(线程数是固定值),如果线程数设的太小,达不到目标QPS,那么调节也就没意义了。当然,也不要把线程数设的太夸张,一方面压测资源不一定够,另一方面JMeter是通过间隔抛弃请求达到控制QPS的效果的,线程数太大可能会造成抖动。
作者回复: 为你的认真细致点赞!我说下我个人的理解。 对于实时数据,一般来说我们其实只需要观察一个宏观的指标概要,判断压测时的大致状况,有无风险等。而对于非实时数据,则需要计算出精确的指标(如99线等),因为我们要输出结论供详细分析和其他决策参考(限流等)。 这是压测平台将数据进行冷热分离最原始的初衷,越精确的结果,必然会带来越昂贵的计算量和资源消耗,我相信JMeter的InfluxdbBackendListener的这种处理方式,肯定也有这方面的考量。 原始的采样数据,在生成的JTL文件中都有,精确到了每个请求,我们在压测后统一回传服务器做异步处理,不存在资源瓶颈问题,用户最多只需等待几分钟。
作者回复: 不是传统的master-slave模式。 实时数据的采样,是每个slave在压测时直接将数据上报至InfluxDB的。每一轮压测,平台都会生成一个唯一的triggerId,所有slave上报数据时均带上值为这个triggerId的TAG,以便InfluxDB聚合。 master则是直接从InfluxDB中取出数据,进行一定的加工(根据具体指标进行求和或求平均值等),再推送数据展示到前端。 显然,master的计算量不大(而且都是用了InfluxDB自带的聚合方法),所以瓶颈一般不会出现在master。反倒是slave在上报数据时,如果TPS很高可能会出现瓶颈,关于这一点可以看一下JMeter的InfluxdbBackendListener的实现,简单说,数据上报是通过消息队列异步进行的,且这个队列是有长度上限的(可以设置),通过这种方式避免过多的影响slave的压测资源消耗。