Linux实用脚本5:一键式IBM MQ队列深度获取与消息预览V2

需求

         有IBM MQ服务器,在做异地灾备切换时,为保证消息不丢失,需要在切换前检查QM中是否有消息。由于单台服务器上QM比较多,里面的QUEUE更多,若需要肉眼登录查看,甚是低效。因而有此需求。

解决方案

#!/bin/bash

 

#param1: mq_name

#param2: qlocal

GetQueueDepth()

{

    if [ $# != 2 ]

    then

        echo "Usage : FUNCTION QMNAME QLOCAL"

        return 1

    fi

    QMNAME="$1"

    QLOCAL="$2"

    AAA=`runmqsc $QMNAME <<!

       display qlocal($QLOCAL)

       end

!`

    echo ${AAA#*CURDEPTH} | awk '{print $1}' | cut -d '(' -f2|cut -d ')' -f1

}

 

GetQueueContent()

{

    if [ $# != 2 ]

    then

        echo "Usage : FUNCTION QMNAME QLOCAL"

        return 1

    fi

    MSG_DETAIL_PATH=./MSG_DETAIL

    QMNAME="$1"

    QLOCAL="$2"

    if [ ! -d $MSG_DETAIL_PATH ]

    then

        mkdir $MSG_DETAIL_PATH

    fi

    MSG_FILE=$MSG_DETAIL_PATH/$QMNAME-$QLOCAL

    > $MSG_FILE

    amqsbcg $QLOCAL $QMNAME  > $MSG_FILE

}

 

GetAllQM()

{

    AAA=`dspmq`

    for item in $AAA

    do 

        PREFIX=${item:0:6}

        if [ "$PREFIX" = "QMNAME" ]

        then

            echo ${item#*QMNAME} | cut -d '(' -f2|cut -d ')' -f1

        fi

    done

}

 

GetAllQueue()

{

    if [ $# != 1 ]

    then

        echo "Usage : FUNCTION QMNAME"

        return 1

    fi

    QMNAME="$1"

    AAA=`runmqsc $QMNAME <<!

       display qlocal(*)

       end

!`

    for item in $AAA

    do

        PREFIX=${item:0:5}

        if [ "$PREFIX" = "QUEUE" ]

        then

             QUEUENAME=`echo ${item#*QUEUE} | cut -d '(' -f2|cut -d ')' -f1`

             QUEUE_PREFIX=${QUEUENAME:0:6}

             if [ "$QUEUE_PREFIX" != "SYSTEM" ]

             then

                echo "$QUEUENAME"

             fi

        fi

    done

}

 

setupenv()

{

    IFS_old=$IFS

    IFS=$':'

   

    BIN1=0

    BIN2=0

    PATH1="/opt/mqm/bin"

    PATH2="/opt/mqm/samp/bin"

    CUR_PATH_ENV=`echo $PATH`

    for item in $CUR_PATH_ENV

    do

        #echo -e "$item \n"

        if [ "$item" = $PATH1 ]

        then

            BIN1=1

        fi

        if [ "$item" = $PATH2 ]

        then

            BIN2=1

        fi 

    done

   

    [ $BIN1 -ne 1 ] && [ -d $PATH1 ] && export PATH=$PATH1:$PATH

    [ $BIN2 -ne 1 ] && [ -d $PATH2 ] && export PATH=$PATH2:$PATH

   

    IFS=$IFS_old

}

 

###############main function####################

#QMNAME="QM_T24HK_EXT"

#QLOCAL="Q.DTS.REQU"

 

LOGFILE=./CHECK_QM.log

> $LOGFILE

 

setupenv

#echo $PATH

 

ALLQM=$(GetAllQM)

for QMNAME in $ALLQM

do

    echo -e "------------------------------" |  tee -a $LOGFILE

    echo -e "Current QM : $QMNAME   \n"      |  tee -a $LOGFILE

    ALLQUEUE=$(GetAllQueue $QMNAME)

    for queuename in $ALLQUEUE

    do

        $(GetQueueContent $QMNAME $queuename)

        DEPTH=$(GetQueueDepth $QMNAME $queuename)

        if [ "X$DEPTH" != "X0" ]

        then

            echo -e "\t!!![ATTENTION] The ($QMNAME:$queuename) depth is : $DEPTH" |  tee -a $LOGFILE

        else

            echo -e "\t The ($QMNAME:$queuename) depth is : $DEPTH" |  tee -a $LOGFILE

        fi

    done

    echo -e "------------------------------\n"  |  tee -a $LOGFILE

done

 

echo "Successfully............"

解决方案详解

  • 设置环境变量setupenv

为实用IBM MQ的相关命令,需配置PATH环境变量,以便让脚本能直接引用相关命令。具体请参阅函数。

  • 获取当前服务器上的所有QM(队列管理器)

采用函数GetAllQM()获取当前服务器上的所有QM。主要使用了dspmq命令,并对命令的输出进行了截取操作。这里讲述cat命令:

-b :以字节为单位进行分割。这些字节位置将忽略多字节字符边界,除非也指定了 -n 标志。  byte

-c :以字符为单位进行分割。  char

-d 自定义分隔符,默认为制表符。  define

-f :与-d一起使用,指定显示哪个区域。   fields   一般用以指定分隔符后的第几列

-n :取消分割多字节字符。仅和 -b 标志一起使用。如果字符的最后一个字节落在由 -b 标志的 List 参数指示的
范围之内,该字符将被写出;否则,该字符将被排除

笔者使用的cut -d '(' -f2 | cut -d ')' -f1 在网上搜寻得知。具体需求就是需要提取括号中的内容。

-d 指定了分隔符,-f 指定取哪个field。

此处先按照左括号分割,先取第二域,再按右括号分割,取第一个域。刚好提取了括号里面的内容。可能有更好的正则表达式方案可以实现此效果。但笔者正则表达式学艺不深,未能实现。

  • 获取QM的所有队列GetAllQueue

根据1中的结果,调用函数获取了特定队列的所有queue。主要使用了两个命令:

  1. runmqsc XXX
  2. display qlocal(*)

与1同样,对display qlocal的返回进行了截取处理,并过滤掉了以”SYSTEM”开头的对接(属于系统预置队列)

  • 获取队列深度GetQueueDepth

函数根据入参1(QM名)、入参2(QLOCAL名),使用display qlocal(XXX)获取队列的具体信息。同样,对返回值进行了截取处理,获得了具体的队列深度。

  • 预览队列内容GetQueueContent

函数使用命令amqsbcg根据入参(QM名+QLOCAL名)预览队列消息,并写入到./MSG_DETAIL目录下,每个应用队列的预览消息形成一个文件,命令为:$QMNAME-$QLOCAL。

  • 结果输出

除了将结果输出到终端外,笔者还通过tee将结果重定向了相关文件,便于永久保存。

运行结果

队列深度

 

如上,QM_SDR和QM_RCV未获取到队列信息是因为QM状态不正常。另外一个QM获取到正确的结果。

Linux实用脚本5:一键式IBM MQ队列深度获取与消息预览V2

Linux实用脚本5:一键式IBM MQ队列深度获取与消息预览V2

 

消息内容

Linux实用脚本5:一键式IBM MQ队列深度获取与消息预览V2

 

扩展与总结

  1. 为实现类似此IBM MQ管理的脚本化,需要对IBM MQ的命令比较熟悉;
  2. 采用函数化的设计,读者可以轻易扩展出更多的功能,比如笔者的遗漏功能:获取QM的状态;
上一篇:开工:创建虚拟机,xshell连接虚拟机,复制虚拟机,docker安装,添加加速器


下一篇:ADO连接数据库