DIS QSTATUS 与 DIS CHSTATUS 上总 CONNAME 值之间的差异
Discrepancy between total CONNAME values on DIS QSTATUS Vs DIS CHSTATUS
我在 IBM MQ v8 上执行了两个 mqsc 命令以查明 App1 在队列管理器 QMGR 上建立的连接数,并发现名为 CONNAME
的属性之一的输出值之间存在差异
echo 'dis chs('APP1.SVRCONN.CHL')'| runmqsc QMGR | grep CONNAME
这次我得到了14个IP作为CONNAME
echo 'dis qs(APP1.QUEUE) type(handle) All where(CHANNEL eq 'APP1.SVRCONN.CHL')'| runmqsc QMGR | grep CONNAME
当我检查由 App1 通道连接的唯一 App1 队列上的句柄数时,我只得到 7 个 IP 作为 CONNAME
所以 App1 队列上有 7 个句柄,但队列管理器上的 App1 通道有 14 个连接。我如何关联这两个值?这是每个队列句柄上的多线程连接吗?如果是,我如何找到它们之间的关系?
DIS CHS
命令将显示有多少通道实例 运行,这实际上是在您的客户端和队列管理器之间建立了多少 TCP 会话。
MQ v7.0.1 及更高版本支持每个频道内的共享对话。每次应用程序与队列管理器建立连接时,这可能是同一通道实例中的另一个对话。客户端和服务器可以设置最大共享连接数。在队列管理器的 SVRCONN
上,属性是 SHARECNV
,在客户端上,它可以在 CCDT 中或以编程方式。当通道启动时,客户端和服务器将协商它们之间的最低值。在 DIS CHS
上,您可以添加 MAXSHCNV
以查看 运行 频道实例协商的最大值和 CURSHCNV
以查看每个频道中有多少对话 运行实例.
带有 TYPE(HANDLE)
的 DIS QS
命令只会显示在您 运行 命令的时间点应用程序打开该队列的句柄的连接。
应用程序可以在没有打开队列的情况下连接到队列管理器,或者它可以打开和关闭队列,如果您没有在队列打开时捕获它,您将看不到句柄。
显示频道正在做什么的更准确的命令是 DIS CONN
,它将显示所有连接,每个连接代表一个对话,因此连接数应与 CURSHCNV
的总数相匹配来自所有频道实例。
以下命令将通过具有指定名称的通道向您显示所有连接运行。
echo "DIS CONN(*) TYPE(ALL) WHERE(CHANNEL EQ APP1.SVRCONN.CHL)"|runmqsc QMGR
输出可能如下所示:
AMQ8276: Display Connection details.
CONN(ABABABABABABABAB)
EXTCONN(ABABABABABABABABABABABABABABABAB)
TYPE(*)
PID(99998) TID(998)
APPLDESC(WebSphere MQ Channel) APPLTAG(App1)
APPLTYPE(USER) ASTATE(NONE)
CHANNEL(APP1.SVRCONN.CHL) CLIENTID( )
CONNAME(10.10.10.10)
CONNOPTS(MQCNO_HANDLE_SHARE_BLOCK,MQCNO_SHARED_BINDING)
USERID(appuser) UOWLOG( )
UOWSTDA( ) UOWSTTI( )
UOWLOGDA( ) UOWLOGTI( )
URTYPE(QMGR)
EXTURID(XA_FORMATID[] XA_GTRID[] XA_BQUAL[])
QMURID(0.0) UOWSTATE(NONE)
AMQ8276: Display Connection details.
CONN(BABABABABABABABA)
EXTCONN(BABABABABABABABABABABABABABABABA)
TYPE(*)
PID(99999) TID(999)
APPLDESC(WebSphere MQ Channel) APPLTAG(App1)
APPLTYPE(USER) ASTATE(STARTED)
CHANNEL(APP1.SVRCONN.CHL) CLIENTID( )
CONNAME(10.10.10.10)
CONNOPTS(MQCNO_HANDLE_SHARE_BLOCK,MQCNO_SHARED_BINDING)
USERID(appuser) UOWLOG( )
UOWSTDA(2018-05-21) UOWSTTI(10.11.27)
UOWLOGDA( ) UOWLOGTI( )
URTYPE(QMGR)
EXTURID(XA_FORMATID[] XA_GTRID[] XA_BQUAL[])
QMURID(0.99999) UOWSTATE(ACTIVE)
OBJNAME(APP1.QUEUE) OBJTYPE(QUEUE)
ASTATE(ACTIVE) HSTATE(INACTIVE)
OPENOPTS(MQOO_INPUT_SHARED,MQOO_BROWSE,MQOO_INQUIRE,MQOO_SAVE_ALL_CONTEXT,MQOO_FAIL_IF_QUIESCING)
READA(NO)
在上面的输出中,CONN(ABABABABABABABAB)
仅连接到队列管理器并且没有对象打开,而 CONN(BABABABABABABABA)
连接到队列管理器并打开了队列 APP1.QUEUE
。
如果要添加到上述命令 |grep 'APP1.QUEUE'
,计数应与 DIS QS
命令中的句柄数相匹配。
您可能有一个应用程序在一个连接上浏览队列以查找消息,然后分派到其他线程以实际处理消息。在您的情况下,7 个通道实例可能为 BROWSE 打开队列,而其他 7 个通道实例将等待打开队列以供 INPUT 读取消息。
下面是我在 Linux 上使用的命令,它将输出 DIS CONN
命令的 CSV 格式以及每个打开的对象。
echo "DIS CONN(*) TYPE(ALL) WHERE(CHANNEL EQ CHL_NAME)"|runmqsc QMGR|grep -o '^\w\+:\|\w\+[(][^)]\+[)]' | awk -F '[()]' -v OFS='","' 'function printValues() { if ("CONN" in p) { print p["CONN"], p["CHANNEL"], p["APPLTAG"], p["USERID"], p["CONNAME"], p["OBJNAME"], p["OBJTYPE"], p["OPENOPTS"] } } /^\w+:/ { if (x !~ /YES/) {printValues()}; x = "NO"; delete p; next } { p[] = } { if ("OPENOPTS" in p) { printValues() ; delete p["OPENOPTS"]; x = "YES"} } END { if (x !~ /YES/) {printValues()} }'|sed -e 's/^/"/g' -e 's/$/"/g'
CSV 输出中的字段是:
"CONN","CHANNEL","APPLTAG","USERID","CONNAME","OBJNAME","OBJTYPE","OPENOPTS"
对象可以是 QMGR 本身、QUEUE、TOPIC 等。如果同一个 CONN 打开了多个对象,则 CONN id 将在输出的行中重复。如果 CONN 没有打开的对象,您将在该行的末尾看到一个没有列出任何对象的条目,如果至少有一个对象打开,则不会有一行表示没有对象:
我在 IBM MQ v8 上执行了两个 mqsc 命令以查明 App1 在队列管理器 QMGR 上建立的连接数,并发现名为 CONNAME
的属性之一的输出值之间存在差异echo 'dis chs('APP1.SVRCONN.CHL')'| runmqsc QMGR | grep CONNAME
这次我得到了14个IP作为CONNAME
echo 'dis qs(APP1.QUEUE) type(handle) All where(CHANNEL eq 'APP1.SVRCONN.CHL')'| runmqsc QMGR | grep CONNAME
当我检查由 App1 通道连接的唯一 App1 队列上的句柄数时,我只得到 7 个 IP 作为 CONNAME
所以 App1 队列上有 7 个句柄,但队列管理器上的 App1 通道有 14 个连接。我如何关联这两个值?这是每个队列句柄上的多线程连接吗?如果是,我如何找到它们之间的关系?
DIS CHS
命令将显示有多少通道实例 运行,这实际上是在您的客户端和队列管理器之间建立了多少 TCP 会话。
MQ v7.0.1 及更高版本支持每个频道内的共享对话。每次应用程序与队列管理器建立连接时,这可能是同一通道实例中的另一个对话。客户端和服务器可以设置最大共享连接数。在队列管理器的 SVRCONN
上,属性是 SHARECNV
,在客户端上,它可以在 CCDT 中或以编程方式。当通道启动时,客户端和服务器将协商它们之间的最低值。在 DIS CHS
上,您可以添加 MAXSHCNV
以查看 运行 频道实例协商的最大值和 CURSHCNV
以查看每个频道中有多少对话 运行实例.
带有 TYPE(HANDLE)
的 DIS QS
命令只会显示在您 运行 命令的时间点应用程序打开该队列的句柄的连接。
应用程序可以在没有打开队列的情况下连接到队列管理器,或者它可以打开和关闭队列,如果您没有在队列打开时捕获它,您将看不到句柄。
显示频道正在做什么的更准确的命令是 DIS CONN
,它将显示所有连接,每个连接代表一个对话,因此连接数应与 CURSHCNV
的总数相匹配来自所有频道实例。
以下命令将通过具有指定名称的通道向您显示所有连接运行。
echo "DIS CONN(*) TYPE(ALL) WHERE(CHANNEL EQ APP1.SVRCONN.CHL)"|runmqsc QMGR
输出可能如下所示:
AMQ8276: Display Connection details.
CONN(ABABABABABABABAB)
EXTCONN(ABABABABABABABABABABABABABABABAB)
TYPE(*)
PID(99998) TID(998)
APPLDESC(WebSphere MQ Channel) APPLTAG(App1)
APPLTYPE(USER) ASTATE(NONE)
CHANNEL(APP1.SVRCONN.CHL) CLIENTID( )
CONNAME(10.10.10.10)
CONNOPTS(MQCNO_HANDLE_SHARE_BLOCK,MQCNO_SHARED_BINDING)
USERID(appuser) UOWLOG( )
UOWSTDA( ) UOWSTTI( )
UOWLOGDA( ) UOWLOGTI( )
URTYPE(QMGR)
EXTURID(XA_FORMATID[] XA_GTRID[] XA_BQUAL[])
QMURID(0.0) UOWSTATE(NONE)
AMQ8276: Display Connection details.
CONN(BABABABABABABABA)
EXTCONN(BABABABABABABABABABABABABABABABA)
TYPE(*)
PID(99999) TID(999)
APPLDESC(WebSphere MQ Channel) APPLTAG(App1)
APPLTYPE(USER) ASTATE(STARTED)
CHANNEL(APP1.SVRCONN.CHL) CLIENTID( )
CONNAME(10.10.10.10)
CONNOPTS(MQCNO_HANDLE_SHARE_BLOCK,MQCNO_SHARED_BINDING)
USERID(appuser) UOWLOG( )
UOWSTDA(2018-05-21) UOWSTTI(10.11.27)
UOWLOGDA( ) UOWLOGTI( )
URTYPE(QMGR)
EXTURID(XA_FORMATID[] XA_GTRID[] XA_BQUAL[])
QMURID(0.99999) UOWSTATE(ACTIVE)
OBJNAME(APP1.QUEUE) OBJTYPE(QUEUE)
ASTATE(ACTIVE) HSTATE(INACTIVE)
OPENOPTS(MQOO_INPUT_SHARED,MQOO_BROWSE,MQOO_INQUIRE,MQOO_SAVE_ALL_CONTEXT,MQOO_FAIL_IF_QUIESCING)
READA(NO)
在上面的输出中,CONN(ABABABABABABABAB)
仅连接到队列管理器并且没有对象打开,而 CONN(BABABABABABABABA)
连接到队列管理器并打开了队列 APP1.QUEUE
。
如果要添加到上述命令 |grep 'APP1.QUEUE'
,计数应与 DIS QS
命令中的句柄数相匹配。
您可能有一个应用程序在一个连接上浏览队列以查找消息,然后分派到其他线程以实际处理消息。在您的情况下,7 个通道实例可能为 BROWSE 打开队列,而其他 7 个通道实例将等待打开队列以供 INPUT 读取消息。
下面是我在 Linux 上使用的命令,它将输出 DIS CONN
命令的 CSV 格式以及每个打开的对象。
echo "DIS CONN(*) TYPE(ALL) WHERE(CHANNEL EQ CHL_NAME)"|runmqsc QMGR|grep -o '^\w\+:\|\w\+[(][^)]\+[)]' | awk -F '[()]' -v OFS='","' 'function printValues() { if ("CONN" in p) { print p["CONN"], p["CHANNEL"], p["APPLTAG"], p["USERID"], p["CONNAME"], p["OBJNAME"], p["OBJTYPE"], p["OPENOPTS"] } } /^\w+:/ { if (x !~ /YES/) {printValues()}; x = "NO"; delete p; next } { p[] = } { if ("OPENOPTS" in p) { printValues() ; delete p["OPENOPTS"]; x = "YES"} } END { if (x !~ /YES/) {printValues()} }'|sed -e 's/^/"/g' -e 's/$/"/g'
CSV 输出中的字段是:
"CONN","CHANNEL","APPLTAG","USERID","CONNAME","OBJNAME","OBJTYPE","OPENOPTS"
对象可以是 QMGR 本身、QUEUE、TOPIC 等。如果同一个 CONN 打开了多个对象,则 CONN id 将在输出的行中重复。如果 CONN 没有打开的对象,您将在该行的末尾看到一个没有列出任何对象的条目,如果至少有一个对象打开,则不会有一行表示没有对象: