You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过IBM MQ JMS点对点模式结合JMeter测量SuT的响应处理时间

方案验证与疑问解答

你设计的逻辑完全可行,是JMeter做异步JMS请求响应测试的标准实现方案,复杂度合理,以下是具体问题的解答和代码示例:


疑问1:Correlation ID的获取方法

你不需要通过读属性的方式获取Correlation ID,直接用JMS规范的标准API即可,避免拼写错误(你之前写的JMS_CorreationID拼写有误,很容易踩坑):

  • 发送端:自己生成唯一ID作为Correlation ID,推荐用UUID,设置到待发送消息中即可,同时要求被测系统处理完请求后,将收到的Correlation ID原样写入响应消息的Correlation ID字段(这是MQ异步通信的通用约定)
  • 消费端:收到响应消息后,直接调用msg.getJMSCorrelationID()方法即可拿到对应的ID

发送端设置示例:

// 生成唯一Correlation ID
def corrId = UUID.randomUUID().toString()
// 消息对象设置Correlation ID
message.setJMSCorrelationID(corrId)

疑问2:存储结构设计

不需要用ID列表,推荐用线程安全的ConcurrentHashMap存储键值对,键为Correlation ID,值为消息发送的时间戳,比列表查询效率更高(O(1)复杂度),完全适配高并发场景:

  • 存储结构需要放在JMeter的全局props对象中,因为你是跨线程组共享数据,线程私有vars对象无法实现跨线程组通信
  • 你的判断逻辑是对的:消费到消息后拿ID去Map里查询,命中后删除对应键,再计算时间差
  • 小优化:可以额外加定时清理逻辑,删掉超过超时时间的无效ID,避免内存泄漏
  • 额外建议:直接存JMeter本地的发送时间戳,比读JMS_IBM_PUTTIME更简单,还能避免MQ服务器和JMeter服务器时钟不同步导致的计算误差

疑问3:自定义SampleResult的响应时间

JSR223 Sampler内置的SampleResult对象提供了直接修改响应时间的方法,你不需要管采样器自身的执行时间,直接把计算出来的被测系统处理时间赋值即可:

def globalCorrMap = props.get("globalCorrMap")
def corrId = msg.getJMSCorrelationID()
def sendTime = globalCorrMap.get(corrId)
// 计算被测系统处理时间
def sutProcessTime = System.currentTimeMillis() - sendTime
// 直接设置采样结果的响应时间,单位为毫秒
SampleResult.setTime(sutProcessTime)
// 可选配置:设置请求成功/失败状态、响应内容
SampleResult.setSuccessful(true)
SampleResult.setResponseData(msg.getBody(String.class), "UTF-8")
// 处理完移除ID
globalCorrMap.remove(corrId)

疑问4:报告仅保留消费端结果

两种最简单的实现方式:

  1. 发送端的JSR223 Sampler直接调用SampleResult.setIgnore()方法,该采样器的结果会完全被忽略,不会进入任何监听器和报告
  2. 如果需要保留发送端结果做排查,只需要在Aggregate Report监听器的配置项中,勾选「仅显示名称匹配的样本」,填写消费端Sampler的名称即可;生成HTML报告时可以在user.properties中配置jmeter.reportgenerator.exporter.html.series_filter参数过滤样本

完整代码示例

setUp线程组JSR223元件(初始化)

// 初始化全局线程安全的Correlation ID存储Map
props.put("globalCorrMap", new java.util.concurrent.ConcurrentHashMap<String, Long>())
// 这里放你原有的OUTBOUND.QUEUE消费连接初始化代码,连接对象也存在props中共享

发送端线程组JSR223 Sampler

import javax.jms.*
def corrId = UUID.randomUUID().toString()
// 这里放你原有创建消息、连接INBOUND.QUEUE的代码
Message message = session.createTextMessage("你的测试消息内容")
message.setJMSCorrelationID(corrId)
// 发送消息
producer.send(message)
// 存储ID和发送时间
props.get("globalCorrMap").put(corrId, System.currentTimeMillis())
// 忽略发送端采样结果,不进入报告
SampleResult.setIgnore()

消费端线程组JSR223 Sampler

import javax.jms.*
def globalCorrMap = props.get("globalCorrMap")
// 按你需要的超时时间设置receive的参数,单位为毫秒,比如10秒超时
Message msg = consumer.receive(10000)
if (msg == null) {
    SampleResult.setSuccessful(false)
    SampleResult.setResponseMessage("响应超时")
    return
}
def corrId = msg.getJMSCorrelationID()
if (!globalCorrMap.containsKey(corrId)) {
    // 非本次测试的消息直接忽略
    SampleResult.setIgnore()
    return
}
def sendTime = globalCorrMap.get(corrId)
SampleResult.setTime(System.currentTimeMillis() - sendTime)
SampleResult.setSuccessful(true)
SampleResult.setResponseData(msg.getBody(String.class), "UTF-8")
globalCorrMap.remove(corrId)

tearDown线程组JSR223元件(清理)

// 这里放你原有关闭MQ连接的代码
// 清空全局存储
props.remove("globalCorrMap")

内容的提问来源于stack exchange,提问作者JustNatural

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 00:24:03