理系学生日記

おまえはいつまで学生気分なのか

15分でWebSphere MQの環境を構築しメッセージの読み書きを行う

WebSphere MQ の実験するんだったら Docker 使うのが一番楽だと思います。 調べてたら、IBM が公式に WebSphere MQ v8.0 の Docker Image を作ってくれてて、これあったら 15 分くらいで WebSphere MQ が使える環境が整います。便利な世の中ですね。

ただし、上記イメージには、いわゆる WebSphere MQ のサンプルアプリが入っていないので、すぐ QUEUE にメッセージを PUT してみたい、みたいなことができない。 そういうわけで、fork してサンプルアプリもインストールするように Dockerfile を書き換えた。

それでは、これを使って 15 分くらいで WebSphere MQ が使える環境を整えましょう。

file-max を増やす

WebSphere MQ は、インストール時に fs.file-max を 524288 以上かどうかのチェックが入っており、デフォルト設定だと docker container の起動でコケる。 これは docker host 側の設定になるので、ここでは以下のコマンドで当該の制限値を変更しておく。

$ docker-machine ssh default sudo 'sysctl -w fs.file-max=524288'

Docker Container を立ち上げる

まずはリポジトリを clone して、Dockerfile から Docker Container を作成。

$ git clone https://github.com/kiririmode/mq-docker
$ cd mq-docker
$ docker build --tag mq ./8.0.0/

その後は、Container を立ち上げるだけです。

$ mkdir ~/work && cd ~/work
$ docker run --env LICENSE=accept --env MQ_QMGR_NAME=QM1 --publish 1414:1414 --detach mq
$ docker start <Container ID>
$ docker exec -it <Container ID> /bin/bash
$ docker exec -it <Container ID> /bin/bash
(mq:8.0)root@1a980fdb7590:/# su - mqm
$

コンテナを立ち上げた段階でキューマネージャ QM1 が作成されていますが、これは docker run 実行時の MQ_QMGR_NAME 指定によるものです。 dspmq コマンドで確認できます。

$ dspmq
QMNAME(QM1)                                               STATUS(Running)

キューマネージャを作成する

新しくキューマネージャを作成するのは crtmqm コマンド。-q オプションは、作成したキューマネージャをデフォルトキューマネージャに指定するものです。

$ crtmqm -q host1/qm1
WebSphere MQ queue manager created.
Directory '/var/mqm/qmgrs/host1&qm1' created.
The queue manager is associated with installation 'Installation1'.
Creating or replacing default objects for queue manager 'host1/qm1'.
Default objects statistics : 79 created. 0 replaced. 0 failed.
Completing setup.
Setup completed.

デフォルトキューマネージャの情報は、/var/mqm/mqs.ini に格納されています。

$ grep -A1 DefaultQueueManager /var/mqm/mqs.ini
DefaultQueueManager:
   Name=host1/qm1

キューマネージャを起動する

キューマネージャの起動は strmqm コマンドで実行します。引数にはキューマネージャ名を取るけど、デフォルトキューマネージャに対する操作の場合は省略可能です。

$ strmqm host1/qm1
WebSphere MQ queue manager 'host1/qm1' starting.
The queue manager is associated with installation 'Installation1'.
5 log records accessed on queue manager 'host1/qm1' during the log replay phase.
Log replay for queue manager 'host1/qm1' complete.
Transaction manager state recovered for queue manager 'host1/qm1'.
WebSphere MQ queue manager 'host1/qm1' started using V8.0.0.4.

ローカルキューを作成する

ローカルキューの作成は runmqsc コマンド経由でプロンプトを取って行います。実際にローカルキューを作成するのは DEFINE QLOCAL

$ runmqsc host1/qm1
(snip)
DEFINE QLOCAL('queue1') DESCR('newly defined')
     1 : DEFINE QLOCAL('queue1') DESCR('newly defined')
AMQ8006: WebSphere MQ queue created.

この確認には、DISPLAY QLOCAL を使用します。DISPLAY QLOCAL(<QNAME>) ALL を使用すると情報が多すぎるので、特定の情報だけ見たい場合は見たい属性の名前を明示的に指定してやる方が良いでしょう。

# 情報量が多い
DISPLAY QLOCAL('queue1')
     1 : DISPLAY QLOCAL('queue1')
AMQ8409: Display Queue details.
   QUEUE(queue1)                           TYPE(QLOCAL)
   ACCTQ(QMGR)                             ALTDATE(2016-05-04)
   ALTTIME(09.34.30)                       BOQNAME( )
(snip)

# 情報量を絞る
DISPLAY QLOCAL('queue1') CURDEPTH DESCR
     3 : DISPLAY QLOCAL('queue1') CURDEPTH DESCR
AMQ8409: Display Queue details.
   QUEUE(queue1)                           TYPE(QLOCAL)
   CURDEPTH(0)                             DESCR(newly defined)

ローカルキューの属性を変更する

ローカルキューの属性を変更するのは ALTER QLOCAL コマンド。

# 変更
ALTER QLOCAL('queue1') DESCR('kiririmode')
     4 : ALTER QLOCAL('queue1') DESCR('kiririmode')
AMQ8008: WebSphere MQ queue changed.

# 確認
DISPLAY QLOCAL('queue1') DESCR
     5 : DISPLAY QLOCAL('queue1') DESCR
AMQ8409: Display Queue details.
   QUEUE(queue1)                           TYPE(QLOCAL)
   DESCR(kiririmode)

メッセージを PUT してみる

WebSphere MQ にはデフォルトでサンプルプログラム群が含まれており、メッセージを PUT するサンプルとして amqsput が提供されている。 コマンドの引数にローカルキュー名を渡して起動すると、標準入力でメッセージ入力を行えるようになる。ここでは hello world! と入力してみた。入力の終了は空行で判断されるらしい。

$ amqsput queue1
Sample AMQSPUT0 start
target queue is queue1
hello world!

Sample AMQSPUT0 end

この後で、queue1 の中に入っているメッセージ長(CURDEPTH) を表示すると、1 に増えていることが確認できる。

DISPLAY QLOCAL('queue1') CURDEPTH
     2 : DISPLAY QLOCAL('queue1') CURDEPTH
AMQ8409: Display Queue details.
   QUEUE(queue1)                           TYPE(QLOCAL)
   CURDEPTH(1)

キューの中のメッセージを表示してみる

キューの中を覗くサンプルプログラムは amqsbcg です。

詳細は、GitHub - IBM/japan-technology: IBM Related Japanese technical documents - Code Patterns, Learning Path, Tutorials, etc. に記載があります。

amqsbcgは、指定されたキューからメッセージを読み込み、そのヘッダ情報とデータ本体を標準出力へ表示するプログラムです。ただし、amqsgetとは異なりbrowseするだけですので、メッセージ自体はキューに残ります。

amqsbcg では、メッセージの MQMD まで見ることができるのがメリットです。

$ amqsbcg queue1

AMQSBCG0 - starts here
**********************

 MQOPEN - 'queue1'


 MQGET of message number 1, CompCode:0 Reason:0
****Message descriptor****

  StrucId  : 'MD  '  Version : 2
  Report   : 0  MsgType : 8
  Expiry   : -1  Feedback : 0
  Encoding : 546  CodedCharSetId : 819
  Format : 'MQSTR   '
  Priority : 0  Persistence : 0
  MsgId : X'414D5120686F7374312F716D31202020D7E3295704220020'
  CorrelId : X'000000000000000000000000000000000000000000000000'
  BackoutCount : 0
  ReplyToQ       : '                                                '
  ReplyToQMgr    : 'host1/qm1                                       '
  ** Identity Context
  UserIdentifier : 'mqm         '
  AccountingToken :
   X'0431303030000000000000000000000000000000000000000000000000000006'
  ApplIdentityData : '                                '
  ** Origin Context
  PutApplType    : '6'
  PutApplName    : 'amqsput                     '
  PutDate  : '20160504'    PutTime  : '11590590'
  ApplOriginData : '    '

  GroupId : X'000000000000000000000000000000000000000000000000'
  MsgSeqNumber   : '1'
  Offset         : '0'
  MsgFlags       : '0'
  OriginalLength : '-1'

****   Message      ****

 length - 12 of 12 bytes

00000000:  6865 6C6C 6F20 776F 726C 6421           'hello world!    '



 No more messages
 MQCLOSE
 MQDISC

というわけで、基本的なキューへの読み書きが実現できました。