IBM MQ与JMeter:获取MQMD关联ID/消息ID并验证消息一致性
搞定JMeter里IBM MQ消息的关联ID校验
第一步:从发送线程组抓系统生成的CorrelationID
你之前自己用MQPutMessageOptions、MQMD生成关联ID是错的——应该抓IBM MQ系统给消息分配的那个CorrelationID,而不是自己造。
做法很简单:在发送消息的Sampler(不管是JMS Publisher还是IBM MQ原生Put Sampler)后面加个JSR223 PostProcessor,用Groovy脚本把系统生成的CorrelationID存成全局属性(跨线程组必须用全局属性,普通变量传不过去)。
如果用的是JMS Sampler,脚本这么写:
def sentMsg = prev.getJMSMessage() if (sentMsg) { def corrId = sentMsg.getJMSCorrelationID() // 存到全局属性,给接收线程组用 props.put("SEND_CORRELATION_ID", corrId) log.info("发送端拿到的CorrelationID: " + corrId) } else { log.error("没抓到发送的JMS消息") }
要是用的IBM MQ原生Put Sampler,就改抓MQMD里的CorrelationID:
def mqmd = prev.getMQMD() if (mqmd) { // 把字节数组转成字符串 def corrId = new String(mqmd.getCorrelationId()) props.put("SEND_CORRELATION_ID", corrId) log.info("发送端MQMD CorrelationID: " + corrId) }
第二步:接收线程组里校验关联ID
接收端要定期轮询队列,拿到消息后对比CorrelationID是不是发送端的那个。
配置接收逻辑
- 加个JMS Subscriber或者IBM MQ Get Sampler,填好队列的连接信息。
- 要是想模拟定期检查,给接收Sampler加个JSR223 PreProcessor设置等待时间:
// 等5秒再接收,单位毫秒 prev.setProperty("WAIT_INTERVAL", 5000)
- 关键的校验部分:在接收Sampler后面加JSR223 PostProcessor,写校验脚本:
// 先拿发送端存的全局CorrelationID def expectedCorrId = props.get("SEND_CORRELATION_ID") if (!expectedCorrId) { log.error("没拿到发送端的CorrelationID,没法校验") prev.setSuccessful(false) return } // 抓接收的消息 def receivedMsg = prev.getJMSMessage() if (!receivedMsg) { log.error("队列里没拿到消息") prev.setSuccessful(false) return } // 拿接收消息的CorrelationID def receivedCorrId = receivedMsg.getJMSCorrelationID() // 对比校验 if (receivedCorrId == expectedCorrId) { log.info("校验通过!消息就是JMeter发的") prev.setSuccessful(true) } else { log.error("校验失败:发送端ID是[" + expectedCorrId + "],接收端是[" + receivedCorrId + "]") prev.setSuccessful(false) }
用IBM MQ原生Get Sampler的话,改下CorrelationID的提取方式:
def mqmd = prev.getMQMD() def receivedCorrId = new String(mqmd.getCorrelationId()) // 后面的对比逻辑和上面一样
解决你遇到的两个坑
1. 按关联ID匹配报错
- 先确认格式统一:IBM MQ的CorrelationID是字节数组,转字符串的时候要统一用UTF-8编码,别这边转成十六进制那边转成普通字符串。
- 嫌校验麻烦的话,直接在IBM MQ Get Sampler的MQMD标签里,勾选CorrelationId,然后填
${__property(SEND_CORRELATION_ID)},这样Sampler只会拉取匹配这个ID的消息,不用事后校验。
2. JMSMessageID不匹配
- JMSMessageID是每条消息的唯一标识,同一条消息的发送端和接收端ID肯定是一样的——你拿到不同的,说明接收的不是你刚发的那条消息。要么队列里有旧消息没清,要么你没过滤,拉到了别的消息。用上面的CorrelationID过滤接收,就能避免这个问题。
跨线程组传值注意点
- 普通JMeter变量只能在当前线程组用,所以必须用
props.put()存全局属性,或者用__setProperty函数也行。 - 接收线程组里可以直接用
${__property(SEND_CORRELATION_ID)}引用,或者在Groovy里用props.get()拿。
内容的提问来源于stack exchange,提问作者Sachin Patel
相关产品推荐
相关产品推荐

