はじめに
IBM の公式チュートリアルにある、MQの練習用コンテナを建てる方法を実際にやってみる。
以下に触発されて実施。二番煎じですみません…。
公式手順はdockerではなくpodmanになっている。IBM(=MQの開発元)が、子会社RedHat(=podmanの開発元)に気を使っているのか。
※↓VM内に普通にインストールする方法もあるが、今回はお手軽な上記とする。
とりかかる前に
まずは以下で紹介されている「MQ超入門」と
「MQ虎の巻」を読む。
以下も重厚だが参考になる
VMを準備
以下と同様にOCI上にVMを建てる。自宅から任意ポートでアクセスできるようにセキュリティリストを適切に設定。
Firewalld, SELinuxは無効化しておく。
https://alphajinsei.hatenablog.com/entry/2024/10/14/022448?_gl=1*1s0rtv6*_gcl_au*MTgxNzgzOTExNy4xNzI4ODM4Nzg2
yum install docker
でdockerを入れておく。
MQのコンテナを起動
docker hubからイメージを取得してコンテナを起動。
※今回利用するdocker hub上のイメージはもうメンテナンスされておらず、今後の最新版はIBM Container Registry から提供されるとのこと
# 公式のdockerイメージを取得。バージョンは固定。
[root@my-instance ~]# docker pull icr.io/ibm-messaging/mq:9.2.4.0-r1
[root@my-instance ~]# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
icr.io/ibm-messaging/mq 9.2.4.0-r1 5211ea6323b7 3 years ago 928MB
# 永続化のためのボリュームを作成
[root@my-instance ~]# docker volume create qm1data
qm1data
[root@my-instance ~]# docker volume ls
DRIVER VOLUME NAME
local qm1data
# MQのdockerコンテナを起動
[root@my-instance ~]# docker run \
> --name QM1 \ # コンテナ名:QM1
> --detach \ # コンテナをバックグラウンドで起動。いつもの
> --rm \ # コンテナ終了時に勝手に消すオプション。毎回stop→rmしなくていいので便利
> --volume qm1data:/mnt/mqm \ #
> --publish 1414:1414 \ # デフォルトで作られるリスナのポート:1414をホストから転送
> --publish 9443:9443 \ # 管理コンソールのポート:9443をホストから転送
> --env LICENSE=accept \ # ライセンスに同意。VMにインストールすると試用期間があるが、このライセンスどうなっているんだろう・・
> --env MQ_QMGR_NAME=QM1 \ #デフォルトで作られるキューマネージャ名:QM1
> --env MQ_APP_USER=app \ # 一般ユーザー名:app
> --env MQ_APP_PASSWORD=passw0rd \
> --env MQ_ADMIN_USER=admin \ #adminユーザー名:admin
> --env MQ_ADMIN_PASSWORD=passw0rd \
> icr.io/ibm-messaging/mq:9.2.4.0-r1
cf0680b56bb7b031faa895a901aca56cf60c2a150897833bf2d07e49cb51a8ea
# コンテナが起動した。
[root@my-instance ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cf0680b56bb7 icr.io/ibm-messaging/mq:9.2.4.0-r1 "runmqdevserver" About a minute ago Up About a minute 0.0.0.0:1414->1414/tcp, 0.0.0.0:9443->9443/tcp, 9157/tcp QM1
公式ドキュメントによると、以下の状態になっているとのこと。(日本語訳を記載)
https://developer.ibm.com/tutorials/mq-connect-app-queue-manager-containers/#what-you-ve-done-so-far7
リスナを除いてDEV.*
の名前で作成されている模様。
Inside the container, the MQ installation on RHEL has the following objects:
- Queue manager QM1
- Queue DEV.QUEUE.1
- Channel: DEV.APP.SVRCONN
- Listener: SYSTEM.LISTENER.TCP.1 on port 1414
The queue that you will be using, DEV.QUEUE.1, "lives" on the queue manager QM1. The queue manager also has a listener that listens for incoming connections, for example, on port 1414. Client applications can connect to the queue manager and can open, put, and get messages, and close the queue.
Applications use an MQ channel to connect to the queue manager. Access to these three objects is restricted in different ways. For example, user "app", who is a member of the group "mqclient" is permitted to use the channel DEV.APP.SVRCONN to connect to the queue manager QM1 and is authorized to put and get messages to and from the queue DEV.QUEUE.1.
All the MQ objects and permissions that the client application needs are created and configured when you run the MQ server container.
以下の図も公式より。(おそらくリスナの記載は誤っていてSYSTEM.LISTER.TCPが正しい)
デフォルトで作成されるオブジェクトの全量は以下に記載されていた。--env MQ_DEV=false
を指定するとこれも作成されなくなるとのこと。
今回は学習用途で、デフォルトで作成されたキュー等を確認・利用する。
まずはそれぞれ確認していく。コマンドあれこれは以下を参照。
キューマネージャーの確認
まずはコンテナにログイン。
# コンテナにログイン
[root@my-instance ~]# docker exec -it QM1 bash
bash-4.4$
# MQのバージョンを表示
bash-4.4$ dspmqver
Name: IBM MQ
Version: 9.2.4.0
Level: p924-L211105.DE
BuildType: IKAP - (Production)
Platform: IBM MQ for Linux (x86-64 platform)
Mode: 64-bit
O/S: Linux 5.4.17-2136.335.4.el7uek.x86_64
O/S Details: Red Hat Enterprise Linux 8.5 (Ootpa)
InstName: Installation1
InstDesc: IBM MQ V9.2.4.0 (Unzipped)
Primary: N/A
InstPath: /opt/mqm
DataPath: /mnt/mqm/data
MaxCmdLevel: 924
LicenseType: Developer
# キューマネージャを表示
bash-4.4$ dspmq
QMNAME(QM1) STATUS(Running)
上記ではdspmq
でキューマネージャを表示したが、同様に、runmqscプロンプト上でもキューマネージャー状態を確認できる。
MQの操作を行う上ではむしろこのrunmqscプロンプトを経由するのが主流?
bash-4.4$ runmqsc QM1
5724-H72 (C) Copyright IBM Corp. 1994, 2021.
Starting MQSC for queue manager QM1.
DISPLAY QMSTATUS
1 : DISPLAY QMSTATUS
AMQ8705I: Display Queue Manager Status Details.
QMNAME(QM1) STATUS(RUNNING)
:
exit
2 : exit
One MQSC command read.
No commands have a syntax error.
All valid MQSC commands were processed.
ただ、プロンプト形式だと若干面倒で・・・以下のようにパイプで送り込むこともできる。運用スクリプトを考えるとこちらのほうが便利かも。ただ依然として不要な(とは言わないまでも興味のない)出力もセットで出てしまうのは変わらず。
bash-4.4$ echo "DISPLAY QMSTATUS" | runmqsc QM1
5724-H72 (C) Copyright IBM Corp. 1994, 2021.
Starting MQSC for queue manager QM1.
1 : DISPLAY QMSTATUS
AMQ8705I: Display Queue Manager Status Details.
QMNAME(QM1) STATUS(RUNNING)
One MQSC command read.
No commands have a syntax error.
All valid MQSC commands were processed.
キューの確認
キューには起動停止の概念はない模様。
# キューを表示。キュー名の表示箇所でgrepしている。普通のキューが3つ、デッドレターキューが1つ作成されていることがわかる
bash-4.4$ echo "DISPLAY QUEUE(DEV.*)" | runmqsc QM1 | grep QUEUE
1 : DISPLAY QUEUE(DEV.*)
QUEUE(DEV.DEAD.LETTER.QUEUE) TYPE(QLOCAL)
QUEUE(DEV.QUEUE.1) TYPE(QLOCAL)
QUEUE(DEV.QUEUE.2) TYPE(QLOCAL)
QUEUE(DEV.QUEUE.3) TYPE(QLOCAL)
# DEV.QUEUE.1のキューの定義を表示。 詳細表示のためALLを指定する。
bash-4.4$ echo "DISPLAY QUEUE(DEV.QUEUE.1) ALL" | runmqsc QM1
5724-H72 (C) Copyright IBM Corp. 1994, 2021.
Starting MQSC for queue manager QM1.
1 : DISPLAY QUEUE(DEV.QUEUE.1) ALL
AMQ8409I: Display Queue details.
QUEUE(DEV.QUEUE.1) TYPE(QLOCAL) # ローカルキューである
ACCTQ(QMGR) ALTDATE(2024-12-07)
ALTTIME(15.31.07) BOQNAME( )
BOTHRESH(0) CLUSNL( )
CLUSTER( ) CLCHNAME( )
CLWLPRTY(0) CLWLRANK(0)
CLWLUSEQ(QMGR) CRDATE(2024-12-07)
CRTIME(14.56.32) CURDEPTH(0) # これがキューの滞留数に相当。何もエンキューしていないので0件
CUSTOM( ) DEFBIND(OPEN)
DEFPRTY(0) DEFPSIST(NO)
DEFPRESP(SYNC) DEFREADA(NO)
DEFSOPT(SHARED) DEFTYPE(PREDEFINED)
DESCR( ) DISTL(NO)
GET(ENABLED) HARDENBO
IMGRCOVQ(QMGR) INITQ( )
IPPROCS(0) MAXDEPTH(5000)
MAXMSGL(4194304) MAXFSIZE(DEFAULT)
MONQ(QMGR) MSGDLVSQ(PRIORITY)
NOTRIGGER NPMCLASS(NORMAL)
OPPROCS(0) PROCESS( )
PUT(ENABLED) PROPCTL(COMPAT)
QDEPTHHI(80) QDEPTHLO(20)
QDPHIEV(DISABLED) QDPLOEV(DISABLED)
QDPMAXEV(ENABLED) QSVCIEV(NONE)
QSVCINT(999999999) RETINTVL(999999999)
SCOPE(QMGR) SHARE
STATQ(QMGR) STREAMQ( )
STRMQOS(BESTEF) TRIGDATA( )
TRIGDPTH(1) TRIGMPRI(0)
TRIGTYPE(FIRST) USAGE(NORMAL)
One MQSC command read.
No commands have a syntax error.
All valid MQSC commands were processed.
# キュー状態を表示。上記のキュー表示とも一部重複する。
bash-4.4$ echo "DISPLAY QSTATUS(DEV.QUEUE.1)" | runmqsc QM1
5724-H72 (C) Copyright IBM Corp. 1994, 2021.
Starting MQSC for queue manager QM1.
1 : DISPLAY QSTATUS(DEV.QUEUE.1)
AMQ8450I: Display queue status details.
QUEUE(DEV.QUEUE.1) TYPE(QUEUE)
CURDEPTH(0) CURFSIZE(1) #ここでもCURDEPTH:滞留数が確認できる。
CURMAXFS(2088960) IPPROCS(0)
LGETDATE( ) LGETTIME( )
LPUTDATE( ) LPUTTIME( )
MEDIALOG( ) MONQ(OFF)
MSGAGE( ) OPPROCS(0)
QTIME( , ) UNCOM(NO)
One MQSC command read.
No commands have a syntax error.
All valid MQSC commands were processed.
# ローカルキューなので、以下のローカルキューの検索にも引っかかる
bash-4.4$ echo "DISPLAY QLOCAL(DEV.QUEUE.1)" | runmqsc QM1 | grep "QUEUE("
QUEUE(DEV.QUEUE.1) TYPE(QLOCAL)
# リモートキューは存在しない
bash-4.4$ echo "DISPLAY QREMOTE(DEV.*)" | runmqsc QM1
5724-H72 (C) Copyright IBM Corp. 1994, 2021.
Starting MQSC for queue manager QM1.
1 : DISPLAY QREMOTE(DEV.*)
AMQ8147E: IBM MQ object DEV.* not found.
One MQSC command read.
No commands have a syntax error.
One valid MQSC command could not be processed.
チャネルの確認
MQのチャネルには、接続形態によって以下の3のチャネルが存在するが、コンテナ内にデフォルトで作成されているのはMQIチャネルである。
- メッセージ・チャネル
- 自分と対向にそれぞれMQサーバが存在して、お互いのキューマネージャを接続するチャネル。
- チャネルは単方向である。送受信したい場合2つチャネルが必要になる
-
START CHANNEL
でチャネル確立を行う。
- MQIチャネル
- 片方がMQのキューマネージャー、もう片方がアプリケーション(java等)のIMB MQ MQI clientの構成になっていて、それらをつなぐチャネル。
- チャネルは双方向である。1つのチャネルで送信も受信も可能。
- アプリケーションがMQI clientを使用して
MQCONN
関数を発行した時点でチャネル確立される。(=MQ側からチャネル確立することはできない?) - サーバ接続チャネル、クライアント接続チャネルの2種が存在する。前者がMQのキューマネージャーで定義するチャネルで利用、後者がアプリケーション上のMQI clientで定義するチャネルで利用されるものである。
- AMQPチャネル
- MQ系の拡張機能との連携用
# チャネルの確認。adminユーザとappユーザの2つ分作成されている
bash-4.4$ echo "DISPLAY CHANNEL(DEV.*)" | runmqsc QM1 | grep CHANNEL
1 : DISPLAY CHANNEL(DEV.*)
CHANNEL(DEV.ADMIN.SVRCONN) CHLTYPE(SVRCONN)
CHANNEL(DEV.APP.SVRCONN) CHLTYPE(SVRCONN)
# チャネルの詳細を表示。詳細表示のためALLをつける
# 対向の情報とかが記載されていないのは、不特定多数から接続を受け付ける想定のMQIチャネルだからか。
# 代わりに、外部からMQI clientで接続する際に指定すると思われるユーザー名(app)などが記載されている。
bash-4.4$ echo "DISPLAY CHANNEL(DEV.APP.SVRCONN) ALL" | runmqsc QM1
5724-H72 (C) Copyright IBM Corp. 1994, 2021.
Starting MQSC for queue manager QM1.
1 : DISPLAY CHANNEL(DEV.APP.SVRCONN) ALL
AMQ8414I: Display Channel details.
CHANNEL(DEV.APP.SVRCONN) CHLTYPE(SVRCONN) # MQIチャネルの一種である「サーバ接続」チャネルである
ALTDATE(2024-12-07) ALTTIME(15.31.07)
CERTLABL( ) COMPHDR(NONE)
COMPMSG(NONE) DESCR( )
DISCINT(0) HBINT(300)
KAINT(AUTO) MAXINST(999999999)
MAXINSTC(999999999) MAXMSGL(4194304)
MCAUSER(app) MONCHL(QMGR) # 外部から接続する際にappユーザーを指定するものと思われる
RCVDATA( ) RCVEXIT( )
SCYDATA( ) SCYEXIT( )
SENDDATA( ) SENDEXIT( )
SHARECNV(10) SSLCAUTH(REQUIRED)
SSLCIPH( ) SSLPEER( )
TRPTYPE(TCP)
One MQSC command read.
No commands have a syntax error.
All valid MQSC commands were processed.
# チャネル状態を表示・・・したが何も表示されない。起動していないから?
bash-4.4$ echo "DISPLAY CHSTATUS(DEV.APP.SERVCONN)" | runmqsc QM1
5724-H72 (C) Copyright IBM Corp. 1994, 2021.
Starting MQSC for queue manager QM1.
1 : DISPLAY CHSTATUS(DEV.APP.SERVCONN)
AMQ8420I: Channel Status not found.
One MQSC command read.
No commands have a syntax error.
One valid MQSC command could not be processed.
# 以下コマンドでチャネル起動してみたが状態変わらず。「チャネル起動のコマンドは通っているが、MQIチャネルをサーバ側からは起動できないので失敗している」のかもしれない
bash-4.4$ echo "START CHANNEL(DEV.APP.SVRCONN)" | runmqsc QM1
5724-H72 (C) Copyright IBM Corp. 1994, 2021.
Starting MQSC for queue manager QM1.
1 : START CHANNEL(DEV.APP.SVRCONN)
AMQ8018I: Start IBM MQ channel accepted.
One MQSC command read.
No commands have a syntax error.
All valid MQSC commands were processed.
リスナの確認
# リスナを確認。2つ作成されている。実利用は後者か。
bash-4.4$ echo "DISPLAY LISTENER(*)" | runmqsc QM1 | grep LISTENER
1 : DISPLAY LISTENER(*)
LISTENER(SYSTEM.DEFAULT.LISTENER.TCP)
LISTENER(SYSTEM.LISTENER.TCP.1)
# リスナの内容を確認。ALLを指定。1414ポートで受けていることがわかる
bash-4.4$ echo "DISPLAY LISTENER(SYSTEM.LISTENER.TCP.1) ALL" | runmqsc QM1
5724-H72 (C) Copyright IBM Corp. 1994, 2021.
Starting MQSC for queue manager QM1.
1 : DISPLAY LISTENER(SYSTEM.LISTENER.TCP.1) ALL
AMQ8630I: Display listener information details.
LISTENER(SYSTEM.LISTENER.TCP.1) CONTROL(QMGR)
TRPTYPE(TCP) PORT(1414) # 1414ポートをlistenしている
IPADDR( ) BACKLOG(0)
DESCR( ) ALTDATE(2024-12-07)
ALTTIME(14.56.27)
One MQSC command read.
No commands have a syntax error.
All valid MQSC commands were processed.
# リスナの状態を確認。1414ポートで稼働中(RUNNNIG)であることがわかる。
bash-4.4$ echo "DISPLAY LSSTATUS(SYSTEM.LISTENER.TCP.1)" | runmqsc QM1
5724-H72 (C) Copyright IBM Corp. 1994, 2021.
Starting MQSC for queue manager QM1.
1 : DISPLAY LSSTATUS(SYSTEM.LISTENER.TCP.1)
AMQ8631I: Display listener status details.
LISTENER(SYSTEM.LISTENER.TCP.1) STATUS(RUNNING)
PID(192) STARTDA(2024-12-07)
STARTTI(15.31.08) DESCR( )
TRPTYPE(TCP) CONTROL(QMGR)
IPADDR(*) PORT(1414)
BACKLOG(100)
One MQSC command read.
No commands have a syntax error.
All valid MQSC commands were processed.
他にもトピック等が作成されているようだが、いったん先に進む。
管理コンソールへログイン
# コンソールを受け付けるサービス?が起動しているかの確認。起動していて、以下で接続してねとのこと。
bash-4.4$ dspmqweb
MQWB1124I: Server 'mqweb' is running.
URLS:
https://cf0680b56bb7:9443/ibmmq/console/
https://cf0680b56bb7:9443/ibmmq/rest/
https://localhost:9443/ibmmq/console/
等でコンソールにログインできる。ID/PWはコンテナ起動時に指定したadmin/passw0rdで。
こっちを見たほうが早い。業務で使えないのが歯がゆいところ。
学習リソース
学習リソースに記載されていたサマリが勉強になったのでここにもメモ。
MQの基礎
メッセージング・スタイル
キュータイプについて理解する
REST APIによるエンキュー・デキュー
記事同様にREST APIを叩いてエンキューしてみる。元記事そのまんまですみません・・・。
以下のイメージ。
エンキュー
bash-4.4$ curl \
> -i \
> -k \
> https://localhost:9443/ibmmq/rest/v2/messaging/qmgr/QM1/queue/DEV.QUEUE.1/message \
> -X POST \
> -u app:passw0rd \
> -H 'ibm-mq-rest-csrf-token: blank' \
> -H 'Content-Type: text/plain;charset=utf-8' \
> -d 'Test MQ message'
HTTP/1.1 201 Created
Content-Language: en-US
Content-Length: 0
Content-Type: text/plain; charset=utf-8
ibm-mq-md-messageId: 414d5120514d312020202020202020203b6a546701f30140
Date: Sat, 07 Dec 2024 19:05:17 GMT
キューの滞留状況を確認
滞留状況はCURDEPTHの値から確認できる。
bash-4.4$ echo "DISPLAY QSTATUS(DEV.QUEUE.1) CURDEPTH" | runmqsc QM1
5724-H72 (C) Copyright IBM Corp. 1994, 2021.
Starting MQSC for queue manager QM1.
1 : DISPLAY QSTATUS(DEV.QUEUE.1) CURDEPTH
AMQ8450I: Display queue status details.
QUEUE(DEV.QUEUE.1) TYPE(QUEUE)
CURDEPTH(1) # 期待通り1件滞留している
One MQSC command read.
No commands have a syntax error.
All valid MQSC commands were processed.
肝心の滞留しているキュー内容だが、MQSCコマンドでの確認方法がわからず。
GETを発行して確認はできた。
bash-4.4$ curl \
> -i \
> -k \
> https://localhost:9443/ibmmq/rest/v2/messaging/qmgr/QM1/queue/DEV.QUEUE.1/message \
> -X GET \
> -u app:passw0rd \
> -H 'ibm-mq-rest-csrf-token: blank'
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Content-Language: en-US
ibm-mq-md-expiry: unlimited
ibm-mq-md-messageId: 414d5120514d312020202020202020203b6a5467013f0240
ibm-mq-md-persistence: nonPersistent
Content-Length: 15
Date: Sat, 07 Dec 2024 20:03:20 GMT
Test MQ message
他にも、以下のdmpmqmsg
で一応キューの中身を確認することはできた。(本来はキューそのものをダンプしてエクスポート・インポート・バックアップするためのツールと思われる)
# 情報表示。1件滞留している。
bash-4.4$ dmpmqmsg -mQM1 -iDEV.QUEUE.1
5724-H72 (C) Copyright IBM Corp. 1994, 2021.
IBM MQ Queue Load/Unload Utility
Read - Files: 0 Messages:1 Bytes:15
# キューの内容をダンプファイルに書き込み。 -d(isplay)のオプションにt(テキスト表示)を指定
bash-4.4$ dmpmqmsg -mQM1 -iDEV.QUEUE.1 -fmyfile -dt
5724-H72 (C) Copyright IBM Corp. 1994, 2021.
IBM MQ Queue Load/Unload Utility
Read - Files: 0 Messages:1 Bytes:15
Written - Files: 1 Messages:1 Bytes:15
# 一番最後にキューの内容が表示されている
bash-4.4$ cat myfile
* DMPMQMSG Version:9.2.4.0 Created:Sat Dec 7 19:15:22 2024
* Qmgr = QM1
* Queue = DEV.QUEUE.1
A VER 2
A RPT 0
A MST 8
A EXP -1
A FDB 0
A ENC 273
A CCS 1208
A FMT MQSTR
A PRI 4
A PER 0
A MSI 414D5120514D312020202020202020203B6A546701F30140
A COI 000000000000000000000000000000000000000000000000
A BOC 0
A RTQ
A RTM QM1
A USR app
A ACC 0000000000000000000000000000000000000000000000000000000000000000
A AIX 6170702020202020202020202020202020202020202020202020202020202020
A PAT 28
A PAN IBM MQ REST API
A PTD 20241207
A PTT 19051725
A AOX 52455354
A GRP 000000000000000000000000000000000000000000000000
A MSQ 1
A OFF 0
A MSF 0
A ORL -1
T Test MQ message
デキュー
bash-4.4$ curl \
> -i \
> -k \
> https://localhost:9443/ibmmq/rest/v2/messaging/qmgr/QM1/queue/DEV.QUEUE.1/message \
> -X DELETE \
> -u app:passw0rd \
> -H 'ibm-mq-rest-csrf-token: blank'
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Content-Language: en-US
ibm-mq-md-expiry: unlimited
ibm-mq-md-messageId: 414d5120514d312020202020202020203b6a546701b50140
ibm-mq-md-persistence: nonPersistent
Content-Length: 15
Date: Sat, 07 Dec 2024 19:00:02 GMT
Test MQ message # デキューしたメッセージが表示される
滞留も0件になった。
bash-4.4$ echo "DISPLAY QSTATUS(DEV.QUEUE.1) CURDEPTH" | runmqsc QM1 | grep CURDEPTH
1 : DISPLAY QSTATUS(DEV.QUEUE.1) CURDEPTH
CURDEPTH(0)
bash-4.4$ dmpmqmsg -mQM1 -iDEV.QUEUE.1
5724-H72 (C) Copyright IBM Corp. 1994, 2021.
IBM MQ Queue Load/Unload Utility
Read - Files: 0 Messages:0 Bytes:0
MQコマンドによるエンキュー・デキュー
以下のコマンドでput, getできるという記載を見かけたが、起動しているコンテナ上の/opt/mqm/bin
には見つからず断念。
# PUT
amqsput キュー名 キューマネージャ名
# 内容確認
amqsbcg キュー名 キューマネージャ名
# GET
amqsget キュー名 キューマネージャ名
おわりに
引き続きチュートリアルを進める。