Sun Java System Message Queue 3 2005Q1 管理ガイド |
第 12 章
問題のトラブルシューティングこの章では、次の問題を把握して解決する方法について説明します。
問題が発生したら、インストールしている Message Queue ソフトウェアのバージョン番号を調べてください。そのバージョン番号により、ソフトウェアバージョンと一致するバージョンのマニュアルを使用していることを確認します。Sun に問題を報告するときにも、そのバージョン番号が必要になります。バージョン番号を調べるには、次のコマンドを実行します。
クライアントがコネクションを確立できないこの問題では、次の症状がみられます。
この節では、次の原因について説明します。
クライアントアプリケーションがコネクションを閉じていないため、コネクション数がリソース制限を超えてしまった
この問題の原因を確認するには
ブローカへのコネクションをすべて一覧表示します。
出力にはすべてのコネクションと各コネクションの確立元のホストが一覧表示されます。異常な数のコネクションが開かれている特定のクライアントがわかります。
問題を解決するには
原因となっているクライアントが未使用のコネクションを閉じるようにプログラムし直します。
ブローカが実行されていないか、ネットワーク接続の問題が存在している
この問題の原因を確認するには
問題を解決するには
コネクションサービスが非アクティブであるか停止される
この問題の原因を確認するには
すべてのコネクションサービスのステータスを確認します。
コネクションサービスのステータスが unknown または paused と表示された場合、クライアントはそのサービスを使用するコネクションを確立できません。
問題を解決するには
SSL サービスを適切に設定する方法については、「SSL ベースのサービスの操作」を参照してください。
- コネクションサービスのステータスが paused と表示された場合は、サービスを再開します (「コネクションサービスの停止および再開」を参照)。
必要なコネクション数に対して使用可能なスレッドが少なすぎる
この問題の原因を確認するには
ブローカログの次のエントリを確認します。
また、次の形式のうちいずれかを使用し、コネクションサービスのコネクション数と現在使用中のスレッド数を確認します。
コネクションごとに 2 つのスレッドが必要です。1 つは受信メッセージ用、もう 1 つは出力メッセージ用です (「スレッドプールマネージャ」を参照)。
問題を解決するには
- 専用のスレッドプールモデル (imq.service_name. threadpool_model=dedicated) を使用している場合は、コネクションの最大数はスレッドプールにあるスレッドの最大数の半分です。そのため、コネクション数を増やすには、スレッドプール (imq.service_name.max_threads) のサイズを拡大するか、共有スレッドプールモデルに切り換えます。
- 共有スレッドプールモデル (imq.service_name. threadpool_model=shared) を使用している場合は、コネクションの最大数は次の 2 つのプロパティの結果の半分です。それは、コネクション監視制限 (imq.service_name.connectionMonitor_limit) とスレッドの最大数 (imq.service_name.max_threads) です。そのため、コネクション数を増やすには、スレッドプールのサイズを拡大するか、コネクション監視制限の値を大きくします。
- 最終的に、サポート可能なコネクションの数またはコネクションのスループットが入力/出力制限に達してしまいます。このような場合は、マルチブローカクラスタを使用して、クラスタ内のブローカインスタンス間でコネクションを分散します。
Solaris または Linux オペレーティングシステム上で必要なコネクション数に対してファイル記述子が少なすぎる
この問題については、「ファイル記述子制限を設定する (Solaris または Linux)」を参照してください。
この問題の原因を確認するには
次のようなブローカログのエントリを確認します。Too many open files.
問題を解決するには
マニュアルの ulimit で説明しているとおり、ファイル記述子の制限を増やします。
TCP バックログにより、確立可能な新しい同時コネクション要求の数が制限される
TCP バックログが、同時コネクション要求の数を制限します。ポートマッパーが追加要求を拒否しなければ、同時コネクション要求はシステムバックログ (imq.portmapper.backlog) に格納されます。Windows オペレーティングシステムでは、 Windows デスクトップで 5、Windows サーバーで 200 というバックログ制限がハードコードされています。
通常、バックログ制限が原因の要求拒否は過渡的な現象であり、非常に多数の同時コネクション要求があると発生します。
この問題の原因を確認するには
ブローカログを調べます。最初に、ブローカが、その他のコネクションを拒否している期間にコネクションを受け入れているかどうかを確認します。次に、拒否されたコネクションについて説明するメッセージを確認します。このようなメッセージがある場合、TCP バックログが問題ではないと思われます。ブローカは、TCP バックログによるコネクション拒否をログしないからです。
正常コネクションがログされ、コネクション拒否がログされない場合は、TCP バックログが問題と思われます。
問題を解決するには
次の手順で、TCP バックログ制限を解消できます。
オペレーティングシステムによって同時コネクションの数が制限される
Windows オペレーティングシステムのライセンスは、サポートされる同時リモートコネクションの数を制限します。
この問題の原因を確認するには
imqcmd query svc を使用して、コネクション用のスレッドが十分にあることを調べ、さらに Windows ライセンス契約書の条項を確認します。ローカルクライアントからはコネクションを確立できるが、リモートクライアントからは確立できない場合は、オペレーティングシステムの制限が問題の原因と考えられます。
問題を解決するには
ユーザーの認証に失敗するか権限が与えられない
不正なパスワード、ユーザーリポジトリにユーザーのエントリがない、またはユーザーがコネクションサービスへのアクセス許可を持っていないといった原因で、認証は失敗することがあります。
この問題の原因を確認するには
ブローカログのエントリで Forbidden エラーメッセージを確認します。このメッセージは、認証エラーを示しているだけで、その理由は示していません。
- ファイルベースのユーザーリポジトリを使用している場合は、次のコマンドを入力します。
imqusermgr list -i instanceName -u userName
- 出力にユーザーが表示された場合は、不正なパスワードの入力が原因と考えられます。出力に次のエラーが表示された場合は、ユーザーリポジトリにエントリがありません。
Error [B3048]: User does not exist in the password file,
- LDAP サーバーのユーザーリポジトリを使用している場合は、適切なツールを使用して、ユーザーのエントリがあるかどうかを確認します。
- アクセス制御プロパティファイルで、コネクションサービスへのアクセスが制限されていないかどうかを確認します。
問題を解決するには
- ユーザーリポジトリにユーザーのエントリがない場合は、ユーザーリポジトリにユーザーを追加します (「ユーザーリポジトリの設定と管理」を参照)。
- 不正なパスワードが使用された場合は、正しいパスワードを入力し直します。
- アクセス制御プロパティが不正に設定されていた場合は、アクセス制御プロパティファイルを編集し、コネクションサービスへのアクセス許可を与えます (「コネクションサービスのアクセス制御」を参照)。
コネクションスループットが遅すぎるこの問題では、次の症状がみられます。
- メッセージスループットが期待どおりでない。
- サポートされるブローカへのコネクション数は、「クライアントがコネクションを確立できない」で説明したように制限されているわけではなく、メッセージの入力/出力レートによって制限されている。
この節では、次の原因について説明します。
ネットワークコネクションまたは WAN が遅すぎる
この問題の原因を確認するには
ネットワークへ ping し、ping が戻るまでに要する時間を確認し、ネットワーク管理者に相談します。また、ローカルクライアントを使用してメッセージを送受信し、ネットワークリンク経由でリモートクライアントを使用した場合と配信時間を比較することもできます。
問題を解決するには
コネクションが遅すぎる場合は、ネットワークリンクをアップグレードします。
コネクションサービスプロトコルが、TCP に比べて本質的に低速
たとえば、SSL ベースプロトコルや HTTP ベースプロトコルは、TCP より低速です (図 11-5 を参照)。
この問題の原因を確認するには
SSL ベースのプロトコルまたは HTTP ベースのプロトコルを使用している場合は、TCP を使用して配信時間を比較してみます。
問題を解決するには
通常、アプリケーション要件によって使用するプロトコルが決定されます。そのため、「トランスポートプロトコルの調整」の説明に従いプロトコルを調整する以外に、対処方法はほとんどありません。
コネクションサービスプロトコルが最適に調整されていない
この問題の原因を確認するには
プロトコルを調整し、違いが生じるかどうかを確認します。
問題を解決するには
「トランスポートプロトコルの調整」の説明にしたがいプロトコルを調整します。
メッセージのサイズが大きく、多くの帯域幅を占有してしまう
この問題の原因を確認するには
小さいサイズのメッセージでベンチマークを実行します。
問題を解決するには
コネクションスループットが低速であるように見えるが、実際は、メッセージ配信プロセスのほかの手順にボトルネックがある
この問題の原因を確認するには
コネクションスループットが低速であるように見えるが、前に述べたような原因が見当たらない場合は、図 11-1 を参照して、そのほかの考えられるボトルネックを特定し、次の問題に関連する現象が出ていないかどうかを確認します。
問題を解決するには
前に述べた問題のトラブルシューティングの節に記載された問題の解決方法に従います。
クライアントがメッセージプロデューサを作成できないこの問題では、次の症状がみられます。
この節では、次の原因について説明します。
限定された数のプロデューサだけを許可するように物理的送信先が設定されている
物理的送信先でのメッセージの蓄積を回避する 1 つの方法は、サポートされるプロデューサの数 (maxNumProducers) を限定することです。
この問題の原因を確認するには
物理的送信先を確認します (「物理的送信先の情報の表示」を参照)。
出力に現在のプロデューサ数と maxNumProducers の値が表示されます。2 つの値が同じ場合、プロデューサ数は設定済みの制限に達しています。ブローカは新しいプロデューサを拒否したときには、ResourceAllocationException [C4088]:A JMS destination limit was reached を返し、ブローカログに次のエントリを作成します。[B4183]:Producer can not be added to destination.
問題を解決するには
maxNumProducers 属性の値を大きくします (「物理的送信先のプロパティの更新」を参照)。
アクセス制御プロパティファイル内の設定により、ユーザーがメッセージプロデューサの作成を承認されていない
この問題の原因を確認するには
ブローカは、新しいプロデューサを拒否したとき、次のメッセージを返します。
ブローカは、ブローカログに次のエントリも作成します。
問題を解決するには
ユーザーがメッセージを生成できるようにアクセス制御プロパティを変更します (「物理的な送信先のアクセス制御」を参照)。
メッセージの生成が遅れるまたは低速であるこの問題では、次の症状がみられます。
この節では、次の原因について説明します。
メッセージサーバーがバックログされ、処理速度が低下したメッセージプロデューサが応答する
バックログされたサーバーでは、ブローカメモリーにメッセージが蓄積します。
物理的送信先メモリー内のメッセージ数またはメッセージのバイト数が設定された制限に達すると、ブローカは指定された制限の動作に従いメモリーリソースを節約しようとします。次の制限の動作により、メッセージプロデューサの処理速度が低下します。
同様に、ブローカ全体のメモリー内 (すべての物理的送信先に対応) のメッセージ数またはメッセージのバイト数が設定済みの制限に達すると、ブローカは最新のメッセージを拒否してメモリーリソースを節約しようとします。
また、物理的送信先またはブローカ全体の制限が適切に設定されていないために、システムメモリーの制限に達すると、ブローカはさらに大規模なアクションを実行してメモリーの過負荷を防ぎます。このアクションには、メッセージプロデューサを徐々に減らすことなどがあります。
この問題の原因を確認するには
設定済みのメッセージの制限が原因でブローカによってメッセージが拒否された場合は、ブローカが次のメッセージを返します。
ブローカは、ブローカログに次のエントリも作成します。
このメッセージには、到達した制限を示すメッセージが続きます。物理的送信先上でメッセージが制限されている場合、ブローカは次のようなエントリを作成します。
ブローカ全体でメッセージが制限されている場合、ブローカは次のようなエントリを作成します。
より一般的には、拒否が発生する前に、次のようにメッセージ制限条件を確認します。
- 物理的送信先とブローカを照会し、設定されているメッセージ制限の設定を調べます。
- 適切な imqcmd コマンドを使用し、物理的送信先かブローカ全体に現在あるメッセージの数かバイト数を監視します。監視できるメトリックス、およびメトリックスの取得に使用するコマンドについては、第 18 章「メトリックスのリファレンス」を参照してください。
問題を解決するには
メッセージがバックログされたことでプロデューサの処理が低下する問題を解消するためのアプローチは多数あります。
一般に、ブローカ全体のメッセージ制限に達しないように、送信先単位でメモリーを管理する必要があります。詳細は、「ブローカの調整」を参照してください。
たとえば、メモリーに累積されたメッセージを削除する REMOVE_OLDEST および REMOVE_LOW_PRIORITY といった制限の動作を指定できます (表 15-1 を参照)。
ブローカが持続性メッセージをデータストアに保存できない
ブローカがデータストアにアクセスできないか、または持続性メッセージをデータストアに書き込めない場合は、プロデューシングクライアントがブロックされます。前に述べたとおり、この状態は、送信先またはブローカ全体のメッセージ制限に達したときにも発生します。
この問題の原因を確認するには
ブローカは、データストアに書き込めない場合には、ブローカログに次のエントリのどれかを作成します。[B2011]: Storing of JMS message from connectionID failed... または [B4004]: Failed to persist message messageID...
問題を解決するには
- 組み込み持続の場合は、ファイルベースのデータストアのディスクスペースを増やしてみます。
- JDBC 互換のデータストアの場合は、プラグイン持続が正しく設定されていることを確認します (第 4 章「ブローカの設定」を参照)。正しく設定されている場合は、データベース管理者にほかのデータベース問題の解決を依頼します。
ブローカによる通知のタイムアウトが短すぎる
低速なコネクションまたは、CPU 使用率が高いかメモリーリソースが不十分なためにメッセージサーバーの能力が低下したことが原因で、ブローカが持続性メッセージの受信を通知するまでに、コネクションファクトリの imqAckTimeout 属性値で許容されている以上の時間を必要としています。
この問題の原因を確認するには
imqAckTimeout 値を超えると、ブローカは次のメッセージを返します。
問題を解決するには
imqAckTimeout コネクションファクトリ属性値を変更します (「コネクションファクトリの属性」を参照)。
プロデューシングクライアントが JVM 制限に達している
この問題の原因を確認するには
問題を解決するには
JVM を調整します (「Java 仮想マシン (JVM) の調整」を参照)。
メッセージがバックログされるこの問題では、次の症状がみられます。
この節では、次の原因について説明します。
トピック送信先に非アクティブな永続サブスクリプションがある
永続サブスクリプションが非アクティブな場合は、該当するコンシューマがアクティブになりメッセージを消費できるようになるまで、メッセージは送信先に格納されます。
この問題の原因を確認するには
各トピック送信先の永続サブスクリプションの状態を確認します。
問題を解決するには
次のアクションのどれかを実行できます。
- 原因となっている永続サブスクリプションのすべてのメッセージをパージします (「永続サブスクリプションの管理」を参照)。
- トピックのメッセージの制限と制限の動作属性を指定します (表 15-1 を参照)。たとえば、メモリーに累積されたメッセージを削除する REMOVE_OLDEST および REMOVE_LOW_PRIORITY といった制限の動作を指定できます。
- 該当する送信先からすべてのメッセージをパージします (「物理的送信先のパージ」を参照)。
- メッセージをメモリー内で存続できる時間を制限します。プロデューシングクライアントをプログラムし直し、メッセージごとに生存時間の値を設定できます。imqOverrideJMSExpiration および imqJMSExpiration コネクションファクトリ属性を設定することで、コネクションを共有するすべてのプロデューサのこれらの設定値をオーバーライドできます (「メッセージヘッダーのオーバーライド」を参照)。
キュー内のメッセージを消費するための使用可能なコンシューマが少なすぎる
メッセージを配信可能なアクティブなコンシューマが少なすぎる場合は、メッセージが蓄積するにつれ、キュー送信先がバックログされる恐れがあります。この状態は、次の理由のどれかが原因で発生することがあります。
この問題の原因を確認するには
コンシューマが使用できない理由を判断するために、送信先のアクティブなコンシューマの数を確認します。
問題を解決するには
コンシューマが使用できない理由に応じて、次のアクションのどれかを実行できます。
- 追加のコンシューミングクライアントを起動して、キューに対応するアクティブなコンシューマを増やします。
- imq.consumerFlowLimit ブローカプロパティを調整して、複数のコンシューマへのキュー配信を最適化します (「複数のコンシューマキューのパフォーマンス」を参照)。
- キューのメッセージの制限と制限の動作属性を指定します (表 15-1 を参照)。たとえば、メモリーに累積されたメッセージを削除する REMOVE_OLDEST および REMOVE_LOW_PRIORITY といった制限の動作を指定できます。
- 該当する送信先からすべてのメッセージをパージします (「物理的送信先のパージ」を参照)。
- メッセージをメモリー内で存続できる時間を制限します。プロデューシングクライアントをプログラミングし直し、メッセージごとに生存期間の値を設定できます。imqOverrideJMSExpiration および imqJMSExpiration コネクションファクトリ属性を設定することで、コネクションを共有するすべてのプロデューサのこれらの設定値をオーバーライドできます (「メッセージヘッダーのオーバーライド」を参照)。
メッセージプロデューサの処理速度についていくには、メッセージコンシューマの処理速度が遅すぎる
この場合、トピックのサブスクライバまたはキューの受信側は、プロデューサがメッセージを送信する速度より遅い速度でメッセージを消費しています。この不均衡が原因で、複数の送信先にメッセージがバックログされています。
この問題の原因を確認するには
ブローカとの間のメッセージのフローレートを確認します。
その後、個々の送信先についてそれぞれのフローレートを確認します。
問題を解決するには
- コンシューミングクライアントコードを最適化します。
- キュー送信先の場合は、アクティブなコンシューマの数を増やします (「複数のコンシューマキューのパフォーマンス」を参照)。
クライアントの通知処理が、メッセージの消費を遅くする
クライアントの通知処理には 2 つの要因が影響しています。
この問題の原因を確認するには
問題を解決するには
- クライアントの通知モードを変更します。たとえば、DUPS_OK_ACKNOWLEDGE または CLIENT_ACKNOWLEDGE に切り換えます。
- CLIENT_ACKNOWLEDGE または処理済みのセッションを使用している場合は、より多数のメッセージを単一の通知にグループ化します。
- コンシューマとコネクションのフロー制御パラメータを調整します (「クライアントランタイムのメッセージフローの調整」を参照)。
生成されたメッセージの処理にブローカが追いつけない
この場合、ブローカがメッセージをコンシューマにルーティングおよび配信可能な速度より速く、ブローカにメッセージが流入しています。ブローカの遅滞は、次のどれかまたはすべてにおける制限が原因と考えられます。それは、CPU、ネットワークソケットの読み取り/書き込み操作、ディスク読み取り/書き込み操作、メモリーのページング、持続ストア、または JVM メモリー制限です。
この問題の原因を確認するには
この問題にそれ以外の原因が関与していないことを確認します。
問題を解決するには
クライアントコードの欠陥: コンシューマがメッセージを通知していない
メッセージは、すべてのコンシューマによってメッセージの送信先へ通知されるまで、送信先で保持されます。クライアントが消費したメッセージを通知しない場合、メッセージは削除されずに送信先で蓄積されます。
たとえば、クライアントコードは次の欠陥を持っている可能性があります。
この問題の原因を確認するには
この節で挙げられている、その他すべての考えられる原因を確認します。次に、以下のコマンドを使用し、送信先を一覧表示します。
ヘッダー「UnAcked」の下に一覧表示されるメッセージの数が、送信先のメッセージの数と同じであるかどうか確認してください。ヘッダー「UnAcked」の下のメッセージはコンシューマに送信されますが、通知されません。この数がメッセージの総数と同じである場合、ブローカはすべてのメッセージを送信し、通知を待機しています。
問題を解決するには
アプリケーション開発者にこの問題をデバッグしてもらうように依頼します。
メッセージサーバーのスループットが散発的であるこの問題では、次の症状がみられます。
この節では、次の原因について説明します。
ブローカのメモリーリソースがかなり不足している
送信先とブローカに制限が適切に設定されなかったため、ブローカはメモリーが過負荷になるのを防ぐためにさらに大規模なアクションを実行します。このため、メッセージのバックログがクリアされるまでは、ブローカの処理がかなり遅くなります。
この問題の原因を確認するには
ブローカのログで、メモリー不足の状態になっていないかどうかを確認します。[B1089]:In low memory condition, broker is attempting to free up resources に続き、メモリーの最新の状態と、使用中のメモリーの合計を示すエントリが表示されます。
また、JVM ヒープ内の使用可能な空きメモリーも確認します。
JVM メモリーの合計値が JVM メモリーの最大値に近くなると、空きメモリーは不足がちになります。
問題を解決するには
- JVM を調整します (「Java 仮想マシン (JVM) の調整」を参照)。
- システムスワップスペースを増やします。
JVM メモリーの再利用 (ガベージコレクション) を実行する
定期的なメモリー再利用によりシステム全体を一掃し、メモリーを解放します。これが実行されると、すべてのスレッドがブロックされます。より多くのメモリーが解放され、JVM ヒープサイズがより大きくなるほど、メモリー再利用に起因する遅延も長くなります。
この問題の原因を確認するには
コンピュータ上の CPU 使用率を監視します。メモリーが再利用されるとき、CPU 使用率は下がります。
また、次のコマンド行オプションを使用してブローカを起動します。
標準出力では、メモリー再利用に要した時間が示されます。
問題を解決するには
複数の CPU を持つコンピュータでは、メモリー再利用を並行して実行するように設定します。
JVM は JIT コンパイラを使用してパフォーマンスを高速化させる
この問題の原因を確認するには
この問題にそれ以外の原因が関与していないことを確認します。
問題を解決するには
しばらくの間システムを稼働させておくと、パフォーマンスは改善するはずです。
メッセージがコンシューマに到達しないこの問題では、次の症状がみられます。
この節では、次の原因について説明します。
制限の動作が、ブローカでのメッセージの削除を引き起こしている
送信先メモリー内のメッセージ数またはメッセージのバイト数が設定済みの制限に達すると、ブローカはメモリーリソースを節約しようとします。これらの制限に達したときにブローカが実行する 3 つの設定可能な動作によって、メッセージが失われることがあります。
ブローカのメモリー内のメッセージ数またはメッセージのバイト数が設定済みの制限に達すると、ブローカは最新のメッセージを拒否してメモリーリソースを節約しようとします。
この問題の原因を確認するには
「デッドメッセージキューにメッセージが含まれる」の説明に従い、デッドメッセージキューを確認します。特に「メッセージ数かメッセージサイズが送信先の制限を超える」の指示に従ってください。REMOVE_OLDEST か REMOVE_LOW_PRIORITY の理由を探します。
問題を解決するには
送信先の制限を上げます。たとえば、次のように指定します。
メッセージタイムアウト値が期限切れになる
ブローカは、タイムアウトして期限切れになったメッセージを削除します。送信先がメッセージで過分にバックログされている場合、生存期間の値が短すぎるメッセージは削除されます。
この問題の原因を確認するには
デッドメッセージキューを確認し、メッセージがタイムアウトになったかどうかを確認します。
QBrowser デモアプリケーションを使用し、DMQ の内容を調べます。QBrowser デモアプリケーションの場所は、オペレーティングシステムによって異なります。場所については、付録 A 「オペレーティングシステムごとの Message Queue データの場所」を参照し、アプリケーション例と場所の表を調べてください。
以下は、Windows における呼び出し例です。
QBrowser のメインウィンドウが表示されたら、キュー名 mq.sys.dmq を選択してから「Browse」をクリックします。次のようなリストが表示されます。
図 12-1 QBrowser のウィンドウ
メッセージをダブルクリックすると、そのメッセージの詳細が表示されます。
図 12-2 QBrowser のメッセージ詳細
メッセージの JMS_SUN_DMQ_UNDELIVERED_REASON プロパティ値が EXPIRED に設定されているかどうか確認してください。
問題を解決するには
アプリケーション開発者と相談し、生存時間の値を上げます。
クロックが同期化しない
クロックが同期化されていない場合、ブローカによるメッセージの生存期間の計算が誤りとなり、メッセージが有効期限より早く削除される場合があります。
この問題の原因を確認するには
ブローカのログファイルで、 B2102、B2103、B2104 のメッセージを探します。このメッセージはすべて、クロックスキューが検出されたことを報告します。
問題を解決するには
「システムリソースの準備」の説明に従い、時刻同期プログラムが動作していることを確認します。
コンシューミングクライアントがコネクションでのメッセージ配信の起動に失敗した
クライアントコードがコネクションを確立し、そのコネクション上でメッセージ配信を開始するまで、メッセージは配信できません。
この問題の原因を確認するには
クライアントコードがコネクションを確立しメッセージ配信を開始したことを確認します。
問題を解決するには
コネクションを確立しメッセージ配信を開始するように、クライアントコードをプログラミングし直します。
デッドメッセージキューにメッセージが含まれるこの問題では、次の症状がみられます。
ユーザー名とパスワードを入力した後で、次のような出力が表示されます。
この例では、デッドメッセージキュー mq.sys.dmq に 35 個のメッセージが含まれています。
この節では、次の原因について説明します。
メッセージ数かメッセージサイズが送信先の制限を超える
この問題の原因を確認するには
QBrowser デモアプリケーションを使用し、デッドメッセージキューの内容を調べます。QBrowser デモアプリケーションの場所は、オペレーティングシステムによって異なります。場所については、付録 A 「オペレーティングシステムごとの Message Queue データの場所」を参照し、アプリケーション例と場所の表を調べてください。
以下は、Windows における呼び出し例です。
QBrowser のメインウィンドウが表示されたら、キュー名 mq.sys.dmq を選択してから「Browse」をクリックします。図 12-1 に示したようなリストが表示されます。
メッセージをダブルクリックすると、そのメッセージの詳細が表示されます。図 12-2 で示したウィンドウが表示されます。
次のメッセージプロパティの値を確認してください。
「JMS Headers」の下で JMSDestination の値を調べ、メッセージが終了している送信先を判断します。
問題を解決するには
送信先の制限を上げます。たとえば、次のように指定します。
ブローカのクロックとプロデューサのクロックが同期化しない
この問題の原因を確認するには
QBrowser アプリケーションを使用し、デッドメッセージキューのメッセージのメッセージ詳細を表示します。JMS_SUN_DMQ_UNDELIVERED_REASON の値を確認し、理由が EXPIRED になっているメッセージを探します。
ブローカのログファイルで、 B2102、B2103、B2104 のメッセージを探します。このメッセージはすべて、クロックスキューが検出されたことを報告します。
問題を解決するには
「システムリソースの準備」の説明に従い、時刻同期プログラムが動作していることを確認します。
コンシューマがメッセージを受信せずにメッセージがタイムアウトになる
この問題の原因を確認するには
QBrowser アプリケーションを使用し、デッドメッセージキューのメッセージのメッセージ詳細を表示します。JMS_SUN_DMQ_UNDELIVERED_REASON の値を確認し、理由が EXPIRED になっているメッセージを探します。
送信先にコンシューマがあるかどうかを確認します。たとえば、次のように操作します。
Active Consumers の Current Number に一覧表示される値を確認します。アクティブなコンシューマがある場合は、次のうちいずれかが true になります。
問題を解決するには
アプリケーション開発者に、メッセージの生存時間の値を上げてもらいます。
コンシューマの数に対してプロデューサが多すぎる
この問題の原因を確認するには
QBrowser アプリケーションを使用し、デッドメッセージキューのメッセージのメッセージ詳細を表示します。JMS_SUN_DMQ_UNDELIVERED_REASON の値を確認します。
JMS_SUN_DMQ_UNDELIVERED_REASON の値が REMOVE_OLDEST か REMOVE_LOW_PRIORITY である場合は、imqcmd query dst コマンドを使用し、送信先のプロデューサ数とコンシューマ数を確認します。プロデューサ数がコンシューマ数より多い場合は、生成レートが消費レートを超えている可能性があります。
問題を解決するには
コンシューマクライアントを追加するか、FLOW_CONTROL 制限動作を使用するように送信先を設定します。FLOW_CONTROL 制限動作では、消費レートが使用されて生成レートが制御されます。
次の例のようなコマンドを使用し、フロー制御動作を起動します。
プロデューサがコンシューマより速い
この問題の原因を確認するには
低速コンシューマがプロデューサの減速の原因になっているかどうか判断するには、送信先制限動作を FLOW_CONTROL に設定します。FLOW_CONTROL 制限動作では、消費レートが使用されて生成レートが制御されます。
次の例のようなコマンドを使用し、フロー制御動作を起動します。
次の例のようなコマンドを実行し、メトリックスを使用して、送信先の入力と出力を調べます。
メトリックスの出力で、次の値を調べます。
フロー制御では生成が消費に調整されるので、生成が低速になるか停止しているか確認します。レートが低速になるか停止している場合は、プロデューサとコンシューマの処理速度に相違があります。
imqcmd list dst コマンドを使用し、未通知 (UnAcked) 送信メッセージの数を確認することもできます。未通知メッセージ数が送信先のサイズより小さい場合、送信先では容量に余裕がありますが、送信先はクライアントフロー制御によって抑制されています。
問題を解決するには
生成レートが消費レートより常に速い場合は、フロー制御を定期的に使用することを考慮し、システムを調整します。
また、後続の節を参照し、次の考えられる要因の解決を考慮するか試してください。
コンシューマが遅すぎる
この問題の原因を確認するには
「プロデューサがコンシューマより速い」の説明に従い、メトリックスを使用して、生成と消費のレートを判断します。
問題を解決するには
次のうち 1 つ以上を試します。
- FLOW_CONTROL 制限動作を使用するように送信先を設定します。次のようなコマンドを使用します。
imqcmd update dst -n myDst -t q -o consumerFlowLimit=FLOW_CONTROL
フロー制御を使用すると、消費のレートまで生成が減速し、ブローカにおけるメッセージの蓄積が防止されます。送信先が適時にメッセージを処理できるようになり、期限切れになる可能性が低くなるまで、プロデューサアプリケーションはメッセージを抑制します。
- プロデューサが安定したレートでメッセージを送信しているか、定期的に大量のメッセージを送信しているかをアプリケーション開発者に尋ねます。
アプリケーションが大量のメッセージを送信している場合は、次の項目の指示に従い、送信先の制限を上げます。
- メッセージ数かバイト数、またはその両方に基づいて、送信先の制限を上げます。
送信先のメッセージ数を変更するには、次の形式のコマンドを入力します。
imqcmd update dst -n destName -t {q/t} -o maxNumMsgs=number
クライアントがメッセージをコミットしない
この問題の原因を確認するには
アプリケーション開発者と協力し、アプリケーションでトランザクションが使用されているかどうかを調べます。アプリケーションでトランザクションが使用されている場合は、次のようにアクティブなトランザクションを一覧表示します。
以下は、コマンド出力の例です。
----------------------------------------------------------------------
Transaction ID State User name # Msgs/# Acks Creation time
----------------------------------------------------------------------
6800151593984248832 STARTED guest 3/2 7/19/04 11:03:08 AM
メッセージ数と通知数に注意してください。
メッセージ数が多い場合は、プロデューサがそれぞれのメッセージを送信しているが、トランザクションのコミットには失敗している可能性があります。ブローカは、コミットを受信するまで、そのトランザクションのメッセージをルーティングしたり配信したりすることができません。
通知数が多い場合は、コンシューマがメッセージごとに通知を送信しているが、トランザクションのコミットには失敗している可能性があります。ブローカは、コミットを受信するまで、そのトランザクションの通知を削除できません。
問題を解決するには
アプリケーション開発者に連絡し、コーディングエラーを修正します。
コンシューマがメッセージを通知しない
この問題の原因を確認するには
アプリケーション開発者に連絡し、アプリケーションでシステムベースの通知が使用されているか、クライアントベースの通知が使用されているかを判断します。アプリケーションでシステムベースの通知が使用されている場合は、この節を省略してください。
アプリケーションでクライアントベースの通知 (CLIENT_ACKNOWLEDGE type) が使用されている場合は、まず、クライアントで保存されるメッセージの数を減らします。次のようなコマンドを使用します。
次に、コンシューマが遅いためにブローカがメッセージをバッファリングしている状態か、コンシューマがメッセージを高速に処理しているがメッセージを通知していない状態かを判断します。
次のコマンドを使用し、送信先を一覧表示します。
ユーザー名とパスワードを入力した後で、次のような出力が表示されます。
Listing all the services on the broker specified by:
---------------------------------
Host Primary Port
---------------------------------
localhost 7676
----------------------------------------------------------------------
Name Type State Producers Consumers Msgs
Total Count UnAck Avg Size
-----------------------------------------------------------------------
MyDest Queue RUNNING 0 0 5 200 1177.0
mq.sys.dmq Queue RUNNING 0 0 35 0 1422.0
Successfully listed destinations.
UnAck の数値は、ブローカが送信して通知を待機しているメッセージ数を表します。UnAck の数値が高いか上昇し続けている場合、ブローカはメッセージを送信しているので、遅いコンシューマを待機していません。コンシューマはメッセージを通知していないことになります。
問題を解決するには
アプリケーション開発者に連絡し、コーディングエラーを修正します。
永続コンシューマがアクティブにならない
この問題の原因を確認するには
次のコマンド形式を使用し、トピックの永続サブスクリプションを調べます。
問題を解決するには
予期しないブローカエラーが発生する
この問題の原因を確認するには
「プロデューサがコンシューマより速い」の説明に従い、QBrowser を使用してメッセージを調べます。
JMS_SUN_DMQ_UNDELIVERED_REASON の値が ERROR である場合は、ブローカエラーが発生しています。
問題を解決するには