1. 前言
消息队列技术是分布式应用间交换信息的一种技术。消息队列可驻留在内存或磁盘上,队列存储消息直到它们被应用程序读走。通过消息队列,应用程序可独立地执行--它们不需要知道彼此的位置、或在继续执行前不需要等待接收程序接收此消息。那我们又如何去监控应用程序给MQ发送的消息量了,又如何去实时掌握队列消息的处理能力和队列深度是否有积压情况,MQ队列消息监控一直是运维人员和开发人员头痛的一件事情,无法实时去了解MQ队列深度情况和消息处理的交易量。笔者针对MQ V7.0版本如何去监控某个队列的消息量,做了一些研究。
为了能监控MQ某个队列的消息量,翻阅了很多官方文档没明确的监控方案,官方文档只提供通过修改MQ管理器的qmgr值和本地队列的STATQ的属性启用能做到消息监控。然后可以对其某个本地队列消息进行跟踪监控。通过监测队列消息结果的Getout的值可以计算出每秒处理的消息量。
2. 开启qmgr和queue消息监控属性
监控消息队列时需要提前开启以下三个属性才能进实时监控消息。否则消息队列是无法进行实时监控。
ALTER QMGR STATQ(ON) ALTER QLOCAL(GD_JF_RT_01.LQ) STATQ(ON) ALTER QMGR STATINT(120) ==》设置消息生成的时间参数,此参数在监控的时候会有时延2分钟 |
3. MQ状态检查
检查消息队列参数是否正常开启监控
dis qmgr STATQ dis ql(GD_JF_RT_01.LQ) STATQ Dis QMGR STATINT |
4. 模拟收发消息指令
如把GD_JF_RT_01.LQ这个队列当作是应用程序的本地接收队列,现在我们用amqsput指令来模拟发送消息给应用程序。用amqsget指令模拟从应用程序本地队列提取消息。
/opt/mqm/bin/amqsput GD_JF_RT_01.LQ QM.TEST Hello mq! /opt/mqm/bin/amqsget GD_JF_RT_01.LQ QM.TEST Hello mq! |
5. 消息监控场景测试
接下来我们针对消息队列监控做以下4个场景测试,测试时间在11.19.33-11.25.33之间通过amqsmon命令输出这6分钟内,应用程序向本地队列GD_JF_RT_01.LQ发送消息,模拟应用程序正常从本地队列GD_JF_RT_01.LQ成功提取消息。
场景1:测试时间11:20:30 发送3条消息 2014年 07月 15日 星期二 11:20:30 CST mqm@weblogic232:~> /opt/mqm/samp/bin/amqsput GD_JF_RT_01.LQ QM.TEST Sample AMQSPUT0 start target queue is GD_JF_RT_01.LQ 1 1 Sample AMQSPUT0 end
mqm@weblogic232:~> /opt/mqm/samp/bin/amqsput GD_JF_RT_01.LQ QM.TEST Sample AMQSPUT0 start target queue is GD_JF_RT_01.LQ 1 Sample AMQSPUT0 end
dis QUEUE(GD_JF_RT_01.LQ) CURDEPTH 105 : dis QUEUE(GD_JF_RT_01.LQ) CURDEPTH AMQ8409: 显示队列细节。 QUEUE(GD_JF_RT_01.LQ) TYPE(QLOCAL) CURDEPTH(3) 《==== 看到当前深度为3,存在3条消息
------------------------------------------------------------------------------- 2014年 07月 15日 星期二 11:21:50 CST 场景2:测试时间:11:21:50 提取3消息 mqm@weblogic232:~> /opt/mqm/samp/bin/amqsget GD_JF_RT_01.LQ QM.TEST Sample AMQSGET0 start message <1> message <1> message <1> no more messages Sample AMQSGET0 end
dis QUEUE(GD_JF_RT_01.LQ) CURDEPTH 108 : dis QUEUE(GD_JF_RT_01.LQ) CURDEPTH AMQ8409: 显示队列细节。 QUEUE(GD_JF_RT_01.LQ) TYPE(QLOCAL) CURDEPTH(0) 《==== 看到当前深度为0,说明消息已经被取走
----------------------------------------------------------------------------- 场景3:测试时间:11:23:00 再次发送3条消息 2014年 07月 15日 星期二 11:23:00 CST mqm@weblogic232:~> /opt/mqm/samp/bin/amqsput GD_JF_RT_01.LQ QM.TEST Sample AMQSPUT0 start target queue is GD_JF_RT_01.LQ 1 Sample AMQSPUT0 end mqm@weblogic232:~> /opt/mqm/samp/bin/amqsput GD_JF_RT_01.LQ QM.TEST Sample AMQSPUT0 start target queue is GD_JF_RT_01.LQ 1 Sample AMQSPUT0 end mqm@weblogic232:~> /opt/mqm/samp/bin/amqsput GD_JF_RT_01.LQ QM.TEST Sample AMQSPUT0 start target queue is GD_JF_RT_01.LQ 1 Sample AMQSPUT0 end
dis QUEUE(GD_JF_RT_01.LQ) CURDEPTH 109 : dis QUEUE(GD_JF_RT_01.LQ) CURDEPTH AMQ8409: 显示队列细节。 QUEUE(GD_JF_RT_01.LQ) TYPE(QLOCAL) CURDEPTH(3) 《==== 看到当前深度为3,存在3条消息
------------------------------------------------------------------------------- 2014年 07月 15日 星期二 11:24:24 CST 场景4:测试时间:11:24:24 再次发送5条消息 mqm@weblogic232:~> /opt/mqm/samp/bin/amqsput GD_JF_RT_01.LQ QM.TEST Sample AMQSPUT0 start target queue is GD_JF_RT_01.LQ ` Sample AMQSPUT0 end mqm@weblogic232:~> /opt/mqm/samp/bin/amqsput GD_JF_RT_01.LQ QM.TEST Sample AMQSPUT0 start target queue is GD_JF_RT_01.LQ 1 Sample AMQSPUT0 end mqm@weblogic232:~> /opt/mqm/samp/bin/amqsput GD_JF_RT_01.LQ QM.TEST Sample AMQSPUT0 start target queue is GD_JF_RT_01.LQ 2 Sample AMQSPUT0 end mqm@weblogic232:~> /opt/mqm/samp/bin/amqsput GD_JF_RT_01.LQ QM.TEST Sample AMQSPUT0 start target queue is GD_JF_RT_01.LQ 3 Sample AMQSPUT0 end mqm@weblogic232:~> /opt/mqm/samp/bin/amqsput GD_JF_RT_01.LQ QM.TEST Sample AMQSPUT0 start target queue is GD_JF_RT_01.LQ 4 Sample AMQSPUT0 end dis QUEUE(GD_JF_RT_01.LQ) CURDEPTH 110 : dis QUEUE(GD_JF_RT_01.LQ) CURDEPTH AMQ8409: 显示队列细节。 QUEUE(GD_JF_RT_01.LQ) TYPE(QLOCAL) CURDEPTH(8) 《==== 此时看到当前深度为8,场景3发送了3条,场景4发了5条 |
总共4个场景发送了共11条消息,消息被取走了3条,接下来用监控脚本查看是否跟以上场景吻合。
1、总发送消息统计 mqm@weblogic232:~> /opt/mqm/samp/bin/amqsmon -m QM.TEST -t statistics -q GD_JF_RT_01.LQ -b -s "2014-07-15 11.19.00" -e "2014-07-15 11.26.00" |grep 'PutCount'|awk '{print $3}'|awk -F ']' '{print $1}'| xargs | tr ' ' '+' | bc 11
统计结果也是11条
2、取走队列消息统计 mqm@weblogic232:~> /opt/mqm/samp/bin/amqsmon -m QM.TEST -t statistics -q GD_JF_RT_01.LQ -b -s "2014-07-15 11.19.00" -e "2014-07-15 11.26.00" |grep 'GetCount'|awk '{print $3}'|awk -F ']' '{print $1}'| xargs | tr ' ' '+' | bc 3
统计结果也是3条 |
6. 结论
1、通过以上研究测试最终得出结论,通过开启MQ管理器的qmgr值属性和本地队列的STATQ属性,是可以实时监控mq本地队列消息的交易量,也能实时掌握消息处理情况。着重点关注这几个参数值PutCount、GetCount、QMaxDepth、QMinDepth。
2、咨询过IBM原厂关于消息量统计收集开启qmgr和queue的STATQ属性,会消耗一定的CPU和内存资源。具体消耗多少资源。需要根据业务量,MQ的队列数量以及机器的负载情况有关。要想监控MQ队列消息交易量还是需要发费一定的代价换取的。
3、以下是统计6分钟内的总消息量。
MSGCOUNT=
/opt/mqm/samp/bin/amqsmon -m QM.TEST -t statistics -q GD_JF_RT_01.LQ -b -s "2014-07-15 11.19.33"-e "2014-07-15 11.25.33" |grep 'GetCount'|awk '{print $3}'|awk -F ']''{print $1}'| xargs | tr ' ' '+' | bc
MQ交易量算法:
MQTPS(交易量)= MSGCOUNT(消息总量)
MQTIME(消息收集时间)*60秒
7. 参考资料
1、开启统计后的性能影响
www-01.ibm.com/support/docview.wss?uid=swg27022497&aid=1
2、MQ提供了一个statistics 统计的方法:http://www-01.ibm.com/support/knowledgecenter/api/content/SSFKSJ_7.0.1/com.ibm.mq.csqzax.doc/mo13410_.htm?locale=en&ro=kcUI
3、amqsmon examples:
http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_7.1.0/com.ibm.mq.doc/mo13500_.htm?lang=en