WAS V7 - WMQ V7.0.1 for z/OSでありがちな失敗
少しまとめた気になってみました。
JMSプロバイダーのネイティブ・ライブラリ設定
WAS for z/OS V7からは、WebSphere変数MQ_INSTALL_ROOTからは、
ネイティブ・ライブラリのみを読み込むことのみになりますが、
JMSプロバイダーでのネイティブ・ライブラリの設定が有効になります。
これはきっと上書きというよりも、
先に読み込まれるという意味のが正しいのではないかと思います。
Installing WebSphere MQ to interoperate with WebSphere Application Server
MQ_INSTALL_ROOTはデフォルトの場所(実際にはライブラリが無い場所)を
指定したままでも問題はおきないでしょう。
どうしても変更したい方は、JMS プロバイダのネイティブ・ライブラリで設定するのと同じ場所を指定することになります。
もしも、「こんな不要なWebSphere変数は消そう」とするならば、
それはそれでWebSphere変数が見つからない警告が出たりすることが考えられるのでお勧めしません。
また、JMSプロバイダーのネイティブ・ライブラリを設定するスコープを間違えることがあります。
私が間違いだと思ってるだけで確証はないのですが、
JMSリソース(コネクションファクトリー、キュー、トピック)を作るスコープに応じて、ネイティブ・ライブラリの設定が必要なスコープが変わります。
WebSphere変数のようなものは、ノードに設定しておくと、ノード配下の全サーバーで見れるでしょう。また、JNDI名なども同じです。その際に、例えばセルに同じWebSphere変数だったり同じJNDI名などがあると、ノードに設定した値が先に発見されて使われます。
しかし、JMSプロバイダーはその理屈は通じないはずです。なぜなら、MQのJMSプロバイダーは全てのスコープに存在します。サーバー・スコープのものしか使われないんでしたっけ?いいえ、そんなことはないでしょう。分けてる意味がないじゃないか。
MQのライブラリ群はOSGiで読み込まれてることは明白です。そのため、各スコープのJMSプロバイダーは、それぞれ別のクラスローダーで読まれている可能性が高いため、上位のスコープのクラスパスやネイティブ・ライブラリパスを混ぜるようなことは考えにくい。そうなると、どのJMSリソースがそのJMSプロバイダーを使うかによって、JMSプロバイダーのネイティブ・ライブラリが必要かが分かるのです。
MQのJarとネイティブ・ライブラリのバージョン差異
通常、JMSプロバイダーが読み込むMQのクラスは、WASが提供しているものを読み込む設定になっています。それはresources.xmlでいうところのclasspathの部分にあたります。WASが提供しているRARは、ネイティブ・ライブラリを含んでいません。そのためMQのJarはWASのPTFから、ネイティブ・ライブラリはMQJMSのPTFからという構成になってます。そこでバージョン差異が生まれることは必然です。それで問題が起きたという話はまだ聞かないのですが、そんなバージョン差異は誰が保証しているんだというのを昔から心配しています。実際にRSUなどで提供されているPTF群では、必ずと言って良いほどMQJMSのPTFはWASが使っているものより新しいのです。完璧に一致させたい場合はリソースアダプターの更新が必要になります。これはノード・スコープからのみ可能です。結果としては、関係するスコープに伝搬します。セル、クラスター、ノード、サーバーです。ただし、別ノードのノード、サーバーは含まれてないはずですから、全てのノードで実行します。律儀にデプロイメント・マネージャのノードもやってしまうと経験しなくてもいい苦労をするので、そこはやらないでおきましょう。リソースアダプターの更新をすると、WASのメンテナンスの度にそれをやらないといけないという話を聞いたことがあります。本当にそうなんでしょうか?それはWASのメンテナンスをすると、resources.xmlが書き換わると言っているようなものです。リスース・アダプターがバージョンアップすると稀にカスタム・プロパティが増えます。そういうのはrar.xmlに含まれており、それを展開することでresources.xmlに書きこまれるため、考えられなくもない話です。WASに含まれているrarでupdateRARすることで、きっとarchivepathとclasspathが書きかわるのだろう。
ネイティブ・ライブラリを設定したのにMDBが動かない
ネイティブ・ライブラリの設定をすると通常サーバーを2回再起動する必要があります。そういうメッセージが出るのです。それが終わっていない状況では、JMSプロバイダーがdisabledの状態になり動きません。そういう状況でコネクション・ファクトリーが動くと、ライブラリが見つからないようなエラーになることもあります。分散系の場合32bit/64bitのライブラリが分かれていますが、z/OSの場合はMQのライブラリは分かれておらず自動で31bit/64bitを判別します。また、ネイティブ・ライブラリを設定していることから、BINDINGS MODEで繋ぐのでしょうが、REUSASID=YESにしているとダメです。WASのJCLや管理コンソールからの起動パラメータからこのパラメータを取り除くためにupdateZOSStartArgsというスクリプトがあるので-removeオプションなどを付けて動かします。これを使わなくても各JVMのページ(コントローラーやサーバント)で変更していくのでも大丈夫だと思います。しかし、正しくはスクリプトで。
メンテナンスの度に2回再起動?
MQ_CLEAR_MQ_FROM_OSGI_CACHE_ON_SHUTDOWNというWebSphere変数を使うことでそれは回避可能です。サーバー停止の度にOSGiのキャッシュをクリアするわけですから、毎回のサーバー起動時間が少々増加することになりますが、メンテンナンス時の時間は減ることになります。
MQのクラスが見つからない
JMSプロバイダーのクラスパス以外でMQのJarにクラスパスを通してる箇所はないので比較的簡単な話です。しかし、WASの利用者にはそのクラスパスは目のつくところに出ていないでしょう。resources.xmlにしっかりと書いてあります。ただし、どのJMSリソースを使う時に見つからないかが分からないと、どのスコープのresouces.xmlでclasspathが通ってないのかが分からない。リスナーポート名やJNDI名だったりが拾えれば、resources.xmlからスコープを見つけて、どのスコープのJMSプロバイダーに問題があるかを調べることが出来ます。
OSGiのキャッシュやsharedclassesのあたりも気になるので、
それらのキャッシュを消してから試すというのも考えられます。
クラスローダー・ビューワではMQのクラスは確認することが出来ないため、
通常の冗長クラスロード等のやり方で調べていくのも良いでしょう。
ごく稀にアプリケーション内にMQのJarを持っていて問題になることもあるでしょう。
それはWAS V6.1では考えられる使い方ですが、WAS V7からはやらないほうがいい。
STEPLIBにMQのロードモジュールが入ってない
必ずしもSTEPLIBである必要はないのですがこういうケースも考えられます。
LNKLSTとかでもいいはずです。
MDBがメッセージをコンシュームしない
非常にさまざま理由があるのでMustGatherに従って情報を集めないといけません。
リスナーポートの停止/起動、アプリケーションの停止/起動というのはわりと鬼門です。
-キューなのかトピックなのか?
-BINDINGS MODEか?
-キューマネージャ名かキュー共用グループ名か?
-共用キューか?
-MDBスロットルの設定はどうなってるか?
-キューやトピック、キューマネージャ、チャネルの設定はどうか?
-プロバイダー・バージョンは?
-SHARECONVは?
-ejb-jar.xmlやejb-jar-bnd.xmlの設定はあっているか?
他にも考えることはたくさんあります。
wlm classification fileが正しく読み込めずTRANSACTION CLASSが割り当てれない
ファイルパスを間違えていたり、
ごく単純にXMLのエレメントの閉じ忘れなどもあります。
DTDファイルを作ってなくてエラーメッセージが出ることもあります。
まずはJOBLOGで確認してから、次にMODIFYコマンドで確認したほうがいいです。
F <server>,DISPLAY,WORK,CLINFO
リスナーポートやアクティベーションスペックやSIBでは
wlm classification fileの書き方が異なるために失敗してることもあります。
MDB PLAN B(トピック)はInternalになるので、
それをうまいこと分類するやり方は知らない。
MDBリクエストがタイムアウトする
コネクション・プール、セッション・プール、リスナーポート、ワーカースレッドの設定問題である場合があります。
MDB throttle settings for message-driven beans on z/OS
ワーカースレッドよりも大きな値を受け付けてしまうと、セッションやコネクションが足らないということが起きます。もしくはWLMキューで待機しすぎるというシナリオもあります。
リスナーポートが停止する
ある種のポイズンメッセージが起因して止まることはあります。
MQのバックアウト閾値よりも大きな値をリスナーポートの最大リトライ回数に設定しておかないと簡単にリスナーポートは停止します。
OOMになる
マイグレーションなどで、古くからのアプリケーションで独自にコネクションを管理していた場合、そのコネクション管理の裏側でスレッドが作られるため、BPXPRMxxもしくはRACFユーザーのOMVSセグメントで定義する最大スレッド数に達したり、ネイティブ・メモリが枯渇したりするということがあります。ただ、この話はプログラムや環境設定に問題がある話です。WAS V7以降であればコネクション・ファクトリーを使うようにしたほうがいい。WAS V7以降であっても、リソースのリミットに達するような無茶な設定になっていると同じことは起こるはずです。
けっこう書いてみたけど、本当に難しい問題はいろいろ資料収集しないね。