この章では、次の問題を把握して解決する方法について説明します。
問題が発生したら、インストールしている Message QueueTM ソフトウェアのバージョン番号を調べてください。そのバージョン番号により、ソフトウェアバージョンと一致するバージョンのマニュアルを使用していることを確認します。Sun に問題を報告するときにも、そのバージョン番号が必要になります。バージョン番号を調べるには、次のコマンドを実行します。
imqcmd -v
症状:
クライアントが新しい接続を確立できない。
クライアントが障害の生じた接続を自動的に再接続できない。
考えられる原因:
考えられる原因: クライアントアプリケーションが接続を閉じていないため、接続数がリソース制限を超えてしまった。
この問題の原因を確認するには:ブローカへの接続をすべて一覧表示します。
imqcmd list cxn
出力にはすべての接続と各接続の確立元のホストが一覧表示されます。異常な数の接続が開かれている特定のクライアントがわかります。
問題を解決するには: 原因となっているクライアントが未使用の接続を閉じるようにプログラムし直します。
考えられる原因: ブローカが実行されていないか、ネットワーク接続の問題が存在している。
この問題の原因を確認するには:
ブローカのプライマリポートへ telnet で接続し、ブローカがポートマッパー出力を返すか確認します。プライマリポートのデフォルトは 7676 です。
ブローカプロセスがホスト上で実行されていることを確認します。
問題を解決するには:
ブローカを起動します。
ネットワーク接続の問題を修復します。
考えられる原因: 接続サービスが非アクティブであるか停止している。
この問題の原因を確認するには: すべての接続サービスのステータスを確認します。
imqcmd list svc
接続サービスのステータスが unknown または paused と表示された場合、クライアントはそのサービスを使用する接続を確立できません。
問題を解決するには:
接続サービスのステータスが unknown と表示された場合、そのサービスはアクティブサービスリスト (imq.service.active ) に含まれていません。SSL ベースのサービスの場合は、サービスが不適切に設定されているため、ブローカがブローカログに次のエントリを作成する可能性があります。
ERROR [B3009]: Unable to start service ssljms: [B4001]: Unable to open protocol tls for ssljms service...
例外の根本的な原因の説明が続きます。
SSL サービスを適切に設定する方法については、「メッセージの暗号化」を参照してください。
接続サービスのステータスが paused と表示された場合は、サービスを再開します (「接続サービスの停止および再開」を参照)。
考えられる原因: 必要な接続数に対して使用可能なスレッドが少なすぎる。
この問題の原因を確認するには: ブローカログの次のエントリを確認します。
WARNING [B3004]: No threads are available to process a new connection on service ... Closing the new connection.
また、次の形式のうちいずれかを使用し、接続サービスの接続数と現在使用中のスレッド数を確認します。
imqcmd query svc -n serviceName imqcmd metrics svc -n serviceName -m cxn
接続ごとに 2 つのスレッドが必要です。1 つは受信メッセージ用、もう 1 つは出力メッセージ用です (「スレッドプール管理」を参照)。
問題を解決するには:
専用スレッドプールモデル (imq. serviceName.threadpool_model= dedicated) を使用している場合、接続の最大数は、スレッドプールにあるスレッドの最大数の半分です。そのため、接続数を増やすには、スレッドプール (imq. serviceName.max_threads) のサイズを拡大するか、共有スレッドプールモデルに切り換えます。
共有スレッドプールモデル (imq. serviceName.threadpool_model=shared) を使用している場合、接続の最大数は、接続監視制限 (imq.serviceName.connectionMonitor_limit ) とスレッドの最大数 (imq. serviceName.max_threads) の 2 つのプロパティーの結果の半分です。そのため、接続数を増やすには、スレッドプールのサイズを拡大するか、接続監視制限の値を大きくします。
最終的に、サポート可能な接続の数または接続のスループットが入力/出力制限に達してしまいます。このような場合は、マルチブローカクラスタを使用して、クラスタ内のブローカインスタンス間で接続を分散します。
考えられる原因: Solaris または Linux プラットフォーム上で必要な接続数に対してファイル記述子が少なすぎる。
この問題については、「ファイル記述子制限の設定」を参照してください。
この問題の原因を確認するには:次のようなブローカログのエントリを確認します。
Too many open files
問題を解決するには: ulimit のマニュアルで説明しているとおり、ファイル記述子の制限を増やします。
考えられる原因: TCP バックログにより、確立可能な新しい同時接続要求の数が制限される。
TCP バックログにより、ポートマッパーが追加の要求を拒否するまでにシステムバックログ (imq.portmapper.backlog)) に格納可能な同時接続要求の数が制限されます。Windows プラットフォームでは、Windows デスクトップで 5、Windows サーバーで 200 というバックログ制限がハードコードされています。
通常、バックログ制限が原因の要求拒否は過渡的な現象であり、非常に多数の同時接続要求があると発生します。
この問題の原因を確認するには: ブローカログを調べます。最初に、ブローカが、その他の接続を拒否している期間に接続を受け入れているかどうかを確認します。次に、拒否された接続について説明するメッセージを確認します。このようなメッセージがある場合、TCP バックログが問題ではないと思われます。ブローカは、TCP バックログによる接続拒否をログしないからです。正常接続がログされ、接続拒否がログされない場合は、TCP バックログが問題と思われます。
問題を解決するには:
クライアントが確立しようとする接続の再試行を短い間隔で行うようにプログラミングします。この問題の過渡的な性質上、このようにプログラミングしても正常に動作します。
imq.portmapper.backlog の値を大きくします。
クライアントが接続を閉じずに、多くの接続を開いていないか確認します。
考えられる原因: オペレーティングシステムによって同時接続の数が制限される。
Windows オペレーティングシステムのライセンスは、サポートされる同時リモート接続の数を制限します。
この問題の原因を確認するには: imqcmd query svc を使用して、接続用のスレッドが十分にあることを調べ、さらに Windows ライセンス契約書の条項を確認します。ローカルクライアントからは接続を確立できるが、リモートクライアントからは確立できない場合は、オペレーティングシステムの制限が問題の原因と考えられます。
問題を解決するには:
より多くの接続が許可されるように 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 より低速です (「トランスポートプロトコル」を参照)。
この問題の原因を確認するには: SSL ベースのプロトコルまたは HTTP ベースのプロトコルを使用している場合は、TCP を使用して配信時間を比較してみます。
問題を解決するには: 通常、アプリケーション要件によって使用するプロトコルが決定されます。そのため、「トランスポートプロトコルの調整」の説明に従いプロトコルを調整する以外に、対処方法はほとんどありません。
考えられる原因: 接続サービスプロトコルが最適に調整されていない。
この問題の原因を確認するには: プロトコルを調整し、違いが生じるかどうかを確認します。
問題を解決するには: 「トランスポートプロトコルの調整」の説明にしたがいプロトコルを調整します。
考えられる原因: メッセージのサイズが大きく、多くの帯域幅を占有してしまう。
この問題の原因を確認するには: 小さいサイズのメッセージでベンチマークを実行します。
問題を解決するには:
メッセージ圧縮機能を使用するように、アプリケーション開発者にアプリケーションを修正してもらいます。『Message Queue Developer's Guide for Java Clients』を参照してください。
データを送信することの通知としてメッセージを使用し、データの送信には別のプロトコルを使用します。
考えられる原因: 接続スループットが低速であるように見えるが、実際は、メッセージ配信プロセスのほかの手順にボトルネックがある。
この問題の原因を確認するには: 接続スループットが低速であるように見えるが、上記のどの原因では説明できない場合は、「パフォーマンスに影響する要因」を参照して、そのほかの考えられるボトルネックを特定し、次の問題に関連する現象が出ていないかどうかを確認します。
問題を解決するには: 前に示されているトラブルシューティングの節に記載された問題の解決方法に従います。
症状:
メッセージプロデューサが物理的送信先に対して作成できず、クライアントは例外を受け取る。
考えられる原因:
考えられる原因: 限定された数のプロデューサだけを許可するように物理的送信先が設定されている。
物理的送信先でのメッセージの蓄積を回避する 1 つの方法は、サポートされるプロデューサの数 (maxNumProducers) を限定することです。
この問題の原因を確認するには: 物理的送信先を確認します。
imqcmd query dst
「物理的送信先の情報の表示」を参照してください。出力に現在のプロデューサ数と maxNumProducers の値が表示されます。2 つの値が同じ場合、プロデューサ数は設定済みの制限に達しています。ブローカは、新しいプロデューサを拒否したとき、次の例外を返します。
ResourceAllocationException [C4088]: A JMS destination limit was reached
また、ブローカログに次のエントリを作成します。
[B4183]: Producer can not be added to destination
問題を解決するには: maxNumProducers 属性の値を大きくします (「物理的送信先のプロパティーの更新」を参照)。
考えられる原因: アクセス制御プロパティーファイル内の設定により、ユーザーがメッセージプロデューサの作成を承認されていない。
この問題の原因を確認するには: ブローカは、新しいプロデューサを拒否したとき、次の例外を返します。
JMSSecurityException [C4076]: Client does not have permission to create producer on destination
また、ブローカログに次のエントリを作成します。
[B2041]: Producer on destination denied[B4051]: Forbidden guest.
問題を解決するには: ユーザーがメッセージを生成できるようにアクセス制御プロパティーを変更します (「物理的な送信先のアクセス制御」を参照)。
症状は次のとおりです。
持続メッセージを送信したときに、send メソッドが戻らずクライアントがブロックする。
持続メッセージを送信したときに、クライアントが例外を受け取る。
プロデューシングクライアントの処理速度が低下する。
考えられる原因:
考えられる原因: ブローカがバックログされ、メッセージプロデューサの処理速度を低下させることによって対処される。
バックログされたブローカでは、ブローカメモリーにメッセージが蓄積します。物理的送信先メモリー内のメッセージ数またはメッセージのバイト数が設定された制限に達すると、ブローカは指定された制限の動作に従いメモリーリソースを節約しようとします。次の制限の動作により、メッセージプロデューサの処理速度が低下します。
FLOW_CONTROL: ブローカが持続メッセージの受信を即時に通知せず、プロデューシングクライアントがブロックされる。
REJECT_NEWEST: ブローカが新しい持続メッセージを拒否する。
同様に、ブローカ全体のメモリー内 (すべての物理的送信先に対応) のメッセージ数またはメッセージのバイト数が設定済みの制限に達すると、ブローカは最新のメッセージを拒否してメモリーリソースを節約しようとします。また、物理的送信先またはブローカ全体の制限が適切に設定されていないために、システムメモリーの制限に達すると、ブローカはさらに大規模なアクションを実行してメモリーの過負荷を防ぎます。このアクションには、メッセージプロデューサを徐々に減らすことなどがあります。
この問題の原因を確認するには: 設定済みのメッセージ制限が原因でブローカによってメッセージが拒否された場合は、ブローカが次の例外を返します。
JMSException [C4036]: A server error occurred
また、ブローカログに次のエントリを作成します。
[B2011]: Storing of JMS message from IMQconn failed
このメッセージには、到達した制限を示す別のメッセージが続きます。
[B4120]: Cannot store message on destination destName because capacity of maxNumMsgs would be exceeded.
これは、物理的送信先上でメッセージが制限されている場合です。
[B4024]: The maximum number of messages currrently in the system has been exceeded, rejecting message.
これは、ブローカ全体でメッセージが制限されている場合です。
より一般的には、拒否が発生する前に、次のようにメッセージ制限条件を確認します。
物理的送信先とブローカを照会し、設定されているメッセージ制限の設定を調べます。
適切な imqcmd コマンドを使用し、物理的送信先かブローカ全体に現在あるメッセージの数かバイト数を監視します。監視できるメトリックス、およびメトリックスの取得に使用するコマンドについては、第 18 章「メトリックスのリファレンス」を参照してください。
問題を解決するには:
物理的送信先またはブローカ全体のメッセージ制限を、メモリーリソースを超えないように注意しながら変更します。
一般に、ブローカ全体のメッセージ制限に達しないように、送信先単位でメモリーを管理する必要があります。詳細については、「ブローカの調整」を参照してください。
メッセージ制限に達したときに、メッセージの生成が低速化しないようにする代わりに、メモリー内のメッセージを廃棄するよう、送信先の制限の動作を変更します。
たとえば、メモリーに累積されたメッセージを削除する REMOVE_OLDEST および REMOVE_LOW_PRIORITY といった制限の動作を指定できます (表 15–1 を参照)。
考えられる原因: ブローカが持続メッセージをデータストアに保存できない。
ブローカがデータストアにアクセスできないか、または持続メッセージを書き込めない場合は、プロデューシングクライアントがブロックされます。前に述べたとおり、この状態は、送信先またはブローカ全体のメッセージ制限に達したときにも発生します。
この問題の原因を確認するには: ブローカは、データストアに書き込めない場合には、ブローカログに次のエントリのいずれかを作成します。
[B2011]: Storing of JMS message from connectionID failed [B4004]: Failed to persist message messageID
問題を解決するには:
ファイルベースの持続の場合は、ファイルベースのデータストアのディスク容量を増やしてみます。
JDBC 互換のデータストアの場合は、JDBC ベースの持続が正しく設定されていることを確認します (「持続データストアの設定」を参照)。正しく設定されている場合は、データベース管理者にほかのデータベース問題の解決を依頼します。
考えられる原因: ブローカによる通知のタイムアウトが短すぎる。
低速な接続または、CPU 使用率が高いかメモリーリソースが不十分なためにブローカの能力が低下したことが原因で、ブローカが持続メッセージの受信を通知するまでに、接続ファクトリの imqAckTimeout 属性値で許容されている以上の時間を必要としている可能性があります。
この問題の原因を確認するには: imqAckTimeout 値を超えると、ブローカは次の例外を返します。
JMSException [C4000]: Packet acknowledge failed
問題を解決するには: imqAckTimeout 接続ファクトリ属性の値を変更します (「信頼性およびフロー制御」を参照)。
考えられる原因: プロデューシングクライアントが JVM 制限に達している。
この問題の原因を確認するには:
クライアントアプリケーションがメモリー不足エラーを受け取ったかどうかを確認します。
freeMemory、MaxMemory、totalMemory などのランタイムメソッドを使用して JVM ヒープの使用可能な空きメモリーを確認します。
問題を解決するには: JVM を調整します (「Java 仮想マシン (JVM) の調整」を参照)。
症状:
メッセージの生成が遅い、または生成されたメッセージがブローカによって拒否される。
メッセージがコンシューマに到達するまでに異常に長い時間がかかる。
ブローカまたは特定の送信先のメッセージ数またはメッセージのバイト数が時間の経過とともに徐々に増えていく。
メッセージが蓄積されているかどうかを確認するため、ブローカ内のメッセージ数またはメッセージのバイト数が時間の経過とともにどのように変化するかを確認し、設定済みの制限と比較します。最初に、設定済みの制限を確認します。
imqcmd query bkr
imqcmd metrics bkr サブコマンドは、この情報を表示しません。
その後、各送信先でのメッセージの蓄積を確認します。
imqcmd list dst
メッセージが設定済みの送信先またはブローカ全体の制限を超えているかどうかを判断するため、ブローカログで次のエントリを確認します。
[B2011]: Storing of JMS message from … failed.
このエントリには、超過した制限について示す別のエントリが続きます。
考えられる原因:
考えられる原因: トピック送信先に非アクティブな永続サブスクリプションがある。
永続サブスクリプションが非アクティブな場合は、該当するコンシューマがアクティブになりメッセージを消費できるようになるまで、メッセージは送信先に格納されます。
この問題の原因を確認するには: 各トピック送信先の永続サブスクリプションの状態を確認します。
imqcmd list dur -d destName
問題を解決するには:
原因となっている永続サブスクリプションのすべてのメッセージを消去します (「永続サブスクリプションの管理」を参照)。
トピックのメッセージの制限と制限の動作属性を指定します (表 15–1 を参照)。たとえば、メモリーに累積されたメッセージを削除する REMOVE_OLDEST および REMOVE_LOW_PRIORITY といった制限の動作を指定できます。
該当する送信先からすべてのメッセージを消去します (「物理的送信先の消去」を参照)。
プロデューシングクライアントをプログラムし直し、メッセージごとに生存時間の値を設定して、メッセージをメモリー内で存続できる時間を制限します。imqOverrideJMSExpiration および imqJMSExpiration 接続ファクトリ属性を設定することで、接続を共有するすべてのプロデューサのこれらの設定値を上書きできます (「メッセージヘッダーの上書き」を参照)。
考えられる原因: キュー内のメッセージを消費するための使用可能なコンシューマが少なすぎる。
メッセージを配信可能なアクティブなコンシューマが少なすぎる場合は、メッセージが蓄積するにつれ、キュー送信先がバックログされる恐れがあります。この状態は、次の理由のどれかが原因で発生することがあります。
送信先に対応するアクティブなコンシューマが少なすぎる。
コンシューミングクライアントが接続の確立に失敗した。
アクティブなコンシューマがキュー内のメッセージに一致するセレクタを使用していない。
この問題の原因を確認するには: コンシューマが使用できない理由を判断するために、送信先のアクティブなコンシューマの数を確認します。
imqcmd metrics dst - n destName -t q -m con
問題を解決するには: コンシューマが使用できない理由に応じて、次のいずれかを実行します。
追加のコンシューミングクライアントを起動して、キューに対応するアクティブなコンシューマを増やします。
imq.consumerFlowLimit ブローカプロパティーを調整して、複数のコンシューマへのキュー配信を最適化します (「複数のコンシューマキューのパフォーマンス」を参照)。
キューのメッセージの制限と制限の動作属性を指定します (表 15–1 を参照)。たとえば、メモリーに累積されたメッセージを削除する REMOVE_OLDEST および REMOVE_LOW_PRIOROTY といった制限の動作を指定できます。
該当する送信先からすべてのメッセージを消去します (「物理的送信先の消去」を参照)。
プロデューシングクライアントをプログラムし直し、メッセージごとに生存時間の値を設定して、メッセージをメモリー内で存続できる時間を制限します。imqOverrideJMSExpiration および imqJMSExpiration 接続ファクトリ属性を設定することで、接続を共有するすべてのプロデューサのこれらの設定値を上書きできます (「メッセージヘッダーの上書き」を参照)。
考えられる原因: メッセージプロデューサの処理速度についていくには、メッセージコンシューマの処理速度が遅すぎる。
この場合、トピックのサブスクライバまたはキューの受信側は、プロデューサがメッセージを送信する速度より遅い速度でメッセージを消費しています。この不均衡が原因で、複数の送信先にメッセージがバックログされています。
この問題の原因を確認するには: ブローカとの間のメッセージのフローレートを確認します。
imqcmd metrics bkr -m rts
その後、個々の送信先についてそれぞれのフローレートを確認します。
imqcmd metrics bkr -t destType -n destName - m rts
問題を解決するには:
コンシューミングクライアントコードを最適化します。
キュー送信先の場合は、アクティブなコンシューマの数を増やします (「複数のコンシューマキューのパフォーマンス」を参照)。
考えられる原因: クライアントの通知処理が、メッセージの消費を遅くする。
クライアントの通知処理には 2 つの要因が影響しています。
クライアント通知の処理時に、大量のブローカリソースが使用されることがあります。その結果、このような通知モードでは、ブローカがクライアント通知を確認するまでコンシューミングクライアントがブロックされるので、メッセージの消費が遅くなることがあります。
JMS ペイロードメッセージと、クライアント通知などの Message Queue 制御メッセージは同じ接続を共有します。その結果、制御メッセージが JMS ペイロードメッセージによって保留され、メッセージの消費を低速化させることがあります。
この問題の原因を確認するには:
メッセージのフローをパケットのフローと比較して確認します。1 秒当たりのパケット数がメッセージの数と比例していない場合は、クライアントの通知が問題と考えられます。
クライアントが次の例外を受信したかどうかを確認します。
JMSException [C4000]: Packet acknowledge failed
問題を解決するには:
クライアントの通知モードを変更します。たとえば、DUPS_OK_ACKNOWLEDGE または CLIENT_ACKNOWLEDGE に切り換えます。
CLIENT_ACKNOWLEDGE または処理済みのセッションを使用している場合は、より多数のメッセージを単一の通知にグループ化します。
コンシューマと接続のフロー制御パラメータを調整します (「クライアントランタイムのメッセージフローの調整」を参照)。
考えられる原因: 生成されたメッセージの処理にブローカが追いつけない。
この場合、ブローカがメッセージをコンシューマにルーティングおよび配信可能な速度より速く、ブローカにメッセージが流入しています。ブローカの遅滞は、次のどれかまたはすべてにおける制限が原因と考えられます。
CPU
ネットワークソケットの読み取り/ 書き込み操作
ディスク読み取り/ 書き込み操作
メモリーのページング
持続ストア
JVM メモリー制限
この問題の原因を確認するには: この問題にそれ以外の考えられる原因が関与していないことを確認します。
問題を解決するには:
コンピュータまたはデータストアの速度をアップグレードします。
ブローカクラスタを使用して、複数のブローカインスタンスに負荷を分散します。
考えられる原因: クライアントコードの欠陥: コンシューマがメッセージを通知していない。
メッセージは、すべてのコンシューマによってメッセージの送信先へ通知されるまで、送信先で保持されます。クライアントが消費したメッセージを通知しない場合、メッセージは削除されずに送信先で蓄積されます。
たとえば、クライアントコードは次の欠陥を持っている可能性があります。
CLIENT_ACKNOWLEDGE 通知モードまたは処理済みセッションを使用しているコンシューマが、定期的に Session.acknowledge または Session.commit を呼び出していない。
AUTO_ACKNOWLEDGE 通知モードを使用しているコンシューマが何らかの理由で停止している。
この問題の原因を確認するには: この節で挙げられている、その他すべての考えられる原因を確認します。次に、以下のコマンドを使用し、送信先を一覧表示します。
imqcmd list dst
ヘッダー「UnAcked」の下に一覧表示されるメッセージの数が、送信先のメッセージの数と同じであるかどうか確認してください。このヘッダーの下のメッセージはコンシューマに送信されますが、通知されません。この数がメッセージの総数と同じである場合、ブローカはすべてのメッセージを送信し、通知を待機しています。
問題を解決するには: アプリケーション開発者にこの問題をデバッグしてもらうように依頼します。
症状:
メッセージのスループットがときどき低下し、その後通常のパフォーマンスに戻る。
考えられる原因:
考えられる原因: ブローカのメモリーリソースがかなり不足している。
送信先とブローカに制限が適切に設定されなかったため、ブローカはメモリーが過負荷になるのを防ぐためにさらに大規模なアクションを実行します。このため、メッセージのバックログがクリアされるまでは、ブローカの処理がかなり遅くなります。
この問題の原因を確認するには: ブローカのログで、メモリー不足の状態になっていないかどうかを確認します。
[B1089]: In low memory condition, broker is attempting to free up resources
に続き、メモリーの最新の状態と、使用中のメモリーの合計を示すエントリが表示されます。また、JVM ヒープ内の使用可能な空きメモリーも確認します。
imqcmd metrics bkr -m cxn
JVM メモリーの合計値が JVM メモリーの最大値に近くなると、空きメモリーは不足がちになります。
問題を解決するには:
JVM を調整します (「Java 仮想マシン (JVM) の調整」を参照)。
システムスワップスペースを増やします。
考えられる原因: JVM メモリーの再利用 (ガベージコレクション) を実行する。
定期的なメモリー再利用によりシステム全体を一掃し、メモリーを解放します。これが実行されると、すべてのスレッドがブロックされます。より多くのメモリーが解放され、JVM ヒープサイズがより大きくなるほど、メモリー再利用に起因する遅延も長くなります。
この問題の原因を確認するには: コンピュータ上の CPU 使用率を監視します。メモリーが再利用されるとき、CPU 使用率は下がります。
また、次のコマンド行オプションを使用してブローカを起動します。
- vmargs -verbose:gc
標準出力では、メモリー再利用が実行される時間が示されます。
問題を解決するには: 複数の CPU を持つコンピュータでは、メモリー再利用を並行して実行するように設定します。
-XX:+UseParallelGC=true
考えられる原因: JVM は JIT コンパイラを使用してパフォーマンスを高速化させる。
この問題の原因を確認するには: この問題にそれ以外の考えられる原因が関与していないことを確認します。
問題を解決するには: しばらくの間システムを稼働させておくと、パフォーマンスは改善するはずです。
症状:
プロデューサによって送信されたメッセージをコンシューマが受信しない
考えられる原因:
考えられる原因: 制限の動作が、ブローカでのメッセージの削除を引き起こしている。
送信先メモリー内のメッセージ数またはメッセージのバイト数が設定済みの制限に達すると、ブローカはメモリーリソースを節約しようとします。これらの制限に達したときにブローカが選択する 3 つの設定可能な動作によって、メッセージが失われることがあります。
REMOVE_OLDEST: もっとも古いメッセージを削除する。
REMOVE_LOW_PRIORITY: 有効期間に従いもっとも優先度の低いメッセージを削除する。
REJECT_NEWEST: 新しい持続メッセージを拒否する。
この問題の原因を確認するには: 「デッドメッセージキューにメッセージが含まれる」の説明に従い、デッドメッセージキューを確認します。特に「メッセージ数かメッセージサイズが送信先の制限を超える」の指示に従ってください。REMOVE_OLDEST か REMOVE_LOW_PRIORITY の理由を探します。
問題を解決するには: 送信先の制限を上げます。たとえば、次のように指定します。
imqcmd update dst -n MyDest - o maxNumMsgs=1000
考えられる原因: メッセージタイムアウト値が期限切れになる。
ブローカは、タイムアウトして期限切れになったメッセージを削除します。送信先がメッセージで過分にバックログされている場合、生存期間の値が短すぎるメッセージは削除されます。
この問題の原因を確認するには: QBrowser デモアプリケーションを使用し、デッドメッセージキューの内容を調べ、メッセージがタイムアウトになっているかどうかを確認します。QBrowser デモのプラットフォームごとの場所については、付録 A 「プラットフォームごとの Message QueueTM データの場所」を参照し、アプリケーション例と場所の表を調べてください。
以下は、Windows プラットフォームにおける呼び出し例です。
cd \MessageQueue3\demo\applications\qbrowser java QBrowser
QBrowser のメインウィンドウが表示されたら、キュー名 mq.sys.dmq を選択してから「Browse」をクリックします。次のようなリストが表示されます。
メッセージをダブルクリックすると、そのメッセージの詳細が表示されます。
メッセージの JMS_SUN_DMQ_UNDELIVERED_REASON プロパティー値が EXPIRED に設定されているかどうか確認してください。
問題を解決するには: アプリケーション開発者と相談し、生存時間の値を上げます。
考えられる原因: クロックが同期化しない。
クロックが同期化されていない場合、ブローカによるメッセージの生存期間の計算が誤りとなり、メッセージが有効期限より早く削除される場合があります。
この問題の原因を確認するには: ブローカのログファイルで、B2102、B2103、B2104 のメッセージを探します。このメッセージはすべて、クロックスキューが検出されたことを報告します。
問題を解決するには: 「システムリソースの準備」の説明に従い、時刻同期プログラムが動作していることを確認します。
考えられる原因: コンシューミングクライアントが接続でのメッセージ配信の開始に失敗した。
クライアントコードが接続を確立し、その接続上でメッセージ配信を開始するまで、メッセージは配信できません。
この問題の原因を確認するには: クライアントコードが接続を確立しメッセージ配信を開始したことを確認します。
問題を解決するには: 接続を確立しメッセージ配信を開始するように、クライアントコードをプログラミングし直します。
症状:
送信先を一覧表示したとき、デッドメッセージキューにメッセージが含まれていることが表示されます。たとえば次のようなコマンドを実行します。
imqcmd list dst
ユーザー名とパスワードを入力したあとで、次のような出力が表示されます。
Listing all the destinations 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 0 1177.0 mq.sys.dmq Queue RUNNING 0 0 35 0 1422.0 Successfully listed destinations. |
この例では、デッドメッセージキュー mq.sys.dmq に 35 個のメッセージが含まれています。
考えられる原因:
考えられる原因: メッセージ数かメッセージサイズが送信先の制限を超える。
この問題の原因を確認するには: QBrowser デモアプリケーションを使用し、デッドメッセージキューの内容を調べます。QBrowser デモのプラットフォームごとの場所については、付録 A 「プラットフォームごとの Message QueueTM データの場所」を参照し、アプリケーション例と場所の表を調べてください。
次に示すのは、Windows プラットフォームにおける呼び出し例です。
cd \MessageQueue3\demo\applications\qbrowser java QBrowser
QBrowser のメインウィンドウが表示されたら、キュー名 mq.sys.dmq を選択してから「Browse」をクリックします。前に「メッセージタイムアウト値が期限切れになる」に示したようなリストが表示されます。メッセージをダブルクリックすると、そのメッセージの詳細が表示されます。「メッセージタイムアウト値が期限切れになる」で示したウィンドウが表示されます。
次のメッセージプロパティーの値を確認してください。
JMS_SUN_DMQ_UNDELIVERED_REASON
JMS_SUN_DMQ_UNDELIVERED_COMMENT
JMS_SUN_DMQ_UNDELIVERED_TIMESTAMP
「JMS Headers」の下で JMSDestination の値を調べ、メッセージが終了している送信先を判断します。
問題を解決するには: 送信先の制限を上げます。たとえば、次のように指定します。
imqcmd update dst - n MyDest -o maxNumMsgs=1000
考えられる原因: ブローカのクロックとプロデューサのクロックが同期化しない。
この問題の原因を確認するには: QBrowser アプリケーションを使用し、デッドメッセージキューのメッセージのメッセージ詳細を表示します。JMS_SUN_DMQ_UNDELIVERED_REASON の値を確認し、理由が EXPIRED になっているメッセージを探します。
ブローカのログファイルで、B2102、B2103、B2104 のメッセージを探します。このメッセージはすべて、クロックスキューが検出されたことを報告します。
問題を解決するには: 「システムリソースの準備」の説明に従い、時刻同期プログラムが動作していることを確認します。
考えられる原因: コンシューマがメッセージを受信せずにメッセージがタイムアウトになる。
この問題の原因を確認するには: QBrowser アプリケーションを使用し、デッドメッセージキューのメッセージのメッセージ詳細を表示します。JMS_SUN_DMQ_UNDELIVERED_REASON の値を確認し、理由が EXPIRED になっているメッセージを探します。
送信先にコンシューマがあるかどうかを確認します。たとえば、次のように指定します。
imqcmd query dst -t q -n MyDest
Current Number of Active Consumers に一覧表示される値を確認します。アクティブなコンシューマがある場合は、次のうちいずれかに該当します。
コンシューマの接続が一時停止している。
コンシューマの実行速度を考慮すると、メッセージのタイムアウトが短すぎる。
問題を解決するには: アプリケーション開発者に、メッセージの生存時間の値を上げてもらいます。
考えられる原因: コンシューマの数に対してプロデューサが多すぎる。
この問題の原因を確認するには: QBrowser アプリケーションを使用し、デッドメッセージキューのメッセージのメッセージ詳細を表示します。JMS_SUN_DMQ_UNDELIVERED_REASON の値を確認します。この値が REMOVE_OLDEST か REMOVE_LOW_PRIORITY である場合は、imqcmd query dst コマンドを使用し、送信先のプロデューサ数とコンシューマ数を確認します。プロデューサ数がコンシューマ数より多い場合は、生成レートが消費レートを超えている可能性があります。
問題を解決するには: コンシューマクライアントを追加するか、または、次のようなコマンドを使用して、送信先の制限動作を FLOW_CONTROL (消費レートを使用して生成レートを制御する) に設定します。
imqcmd update dst -n myDst -t q -o consumerFlowLimit=FLOW_CONTROL
考えられる原因: プロデューサがコンシューマより速い。
この問題の原因を確認するには: 低速コンシューマがプロデューサの減速の原因になっているかどうかを判断するには、次のようなコマンドを使用して、送信先の制限動作を FLOW_CONTROL (消費レートを使用して生成レートを制御する) に設定します。
imqcmd update dst -n myDst -t q -o consumerFlowLimit=FLOW_CONTROL
次のようなコマンドを使用し、メトリックスを使用して、送信先の入力と出力を調べます。
imqcmd metrics dst - n myDst -t q -m rts
メトリックスの出力で、次の値を調べます。
Msgs/sec Out: ブローカが 1 秒あたりに削除したメッセージ数を示します。すべてのコンシューマがメッセージの受信を通知したとき、ブローカはメッセージを削除するので、このメトリックスには消費レートが反映されます。
Msgs/sec In: ブローカが 1 秒あたりにプロデューサから受信したメッセージ数を示します。このメトリックスには生成レートが反映されます。
フロー制御では生成が消費に調整されるので、生成が低速になるか停止しているか確認します。生成が低速になるか停止している場合は、プロデューサとコンシューマの処理速度に相違があります。imqcmd list dst コマンドを使用し、未通知 (UnAcked) 送信メッセージの数を確認することもできます。未通知メッセージ数が送信先のサイズより小さい場合、送信先では容量に余裕がありますが、送信先はクライアントフロー制御によって抑制されています。
問題を解決するには: 生成レートが消費レートより常に速い場合は、フロー制御を定期的に使用することを考慮し、システムを調整します。また、後続の節を参照し、次の考えられる要因の解決を考慮するか試してください。
考えられる原因: コンシューマが遅すぎる。
この問題の原因を確認するには: 「プロデューサがコンシューマより速い」の説明に従い、メトリックスを使用して、生成と消費のレートを判断します。
問題を解決するには:
次のようなコマンドを使用して、送信先の制限動作を FLOW_CONTROL に設定します。
imqcmd update dst -n myDst -t q -o consumerFlowLimit=FLOW_CONTROL
フロー制御を使用すると、消費のレートまで生成が減速し、ブローカにおけるメッセージの蓄積が防止されます。送信先がメッセージを処理できるようになるまで、プロデューサアプリケーションはメッセージを抑制するので、期限切れになる可能性が低くなります。
プロデューサが安定したレートでメッセージを送信しているか、定期的に大量のメッセージを送信しているかをアプリケーション開発者に尋ねます。アプリケーションが大量のメッセージを送信している場合は、次の項目の説明に従い、送信先の制限を上げます。
メッセージ数かバイト数、またはその両方に基づいて、送信先の制限を上げます。送信先のメッセージ数を変更するには、次の形式のコマンドを入力します。
imqcmd update dst - n destName -t {q|t} -o maxNumMsgs=number
送信先のサイズを変更するには、次の形式のコマンドを入力します。
imqcmd update dst -n destName -t {q|t} -o maxTotalMsgBytes=number
制限を上げると、ブローカが使用するメモリー量が増えることに注意してください。制限が高すぎる場合は、ブローカでメモリーが不足し、メッセージを処理できなくなることがあります。
生成負荷のレベルが高い間、メッセージの喪失を受け入れることができるかどうかを考慮します。
考えられる原因: クライアントがメッセージをコミットしない。
この問題の原因を確認するには: アプリケーション開発者と協力し、アプリケーションでトランザクションが使用されているかどうかを調べます。使用されている場合は、次のようにアクティブなトランザクションを一覧表示します。
imqcmd list txn
以下は、コマンド出力の例です。
---------------------------------------------------------------------- Transaction ID State User name # Msgs/# Acks Creation time ---------------------------------------------------------------------- 6800151593984248832 STARTED guest 3/2 7/19/04 11:03:08 AM |
メッセージ数と通知数に注意してください。メッセージ数が多い場合は、プロデューサがそれぞれのメッセージを送信しているが、トランザクションのコミットには失敗している可能性があります。ブローカは、コミットを受信するまで、そのトランザクションのメッセージをルーティングしたり配信したりすることができません。通知数が多い場合は、コンシューマがメッセージごとに通知を送信しているが、トランザクションのコミットには失敗している可能性があります。ブローカは、コミットを受信するまで、そのトランザクションの通知を削除できません。
問題を解決するには: アプリケーション開発者に連絡し、コーディングエラーを修正します。
考えられる原因: コンシューマがメッセージを通知しない。
この問題の原因を確認するには: アプリケーション開発者に連絡し、アプリケーションでシステムベースの通知が使用されているか、クライアントベースの通知が使用されているかを判断します。アプリケーションでシステムベースの通知が使用されている場合は、この節を省略してください。アプリケーションでクライアントベースの通知 (CLIENT_ACKNOWLEDGE) が使用されている場合は、まず、次のようなコマンドを使用して、クライアントで保存されるメッセージの数を減らします。
imqcmd update dst -n myDst -t q -o consumerFlowLimit=1
次に、コンシューマが遅いためにブローカがメッセージをバッファリングしている状態か、コンシューマがメッセージを高速に処理しているがメッセージを通知していない状態かを判断します。次のコマンドを使用し、送信先を一覧表示します。
imqcmd list dst
ユーザー名とパスワードを入力したあとで、次のような出力が表示されます。
Listing all the destinations 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 の数値は、ブローカが送信して通知を待機しているメッセージ数を表します。この数値が高いか上昇し続けている場合、ブローカはメッセージを送信しているので、遅いコンシューマを待機していません。コンシューマはメッセージを通知していないことになります。
問題を解決するには: アプリケーション開発者に連絡し、コーディングエラーを修正します。
考えられる原因: 永続コンシューマがアクティブにならない。
この問題の原因を確認するには: 次のコマンド形式を使用し、トピックの永続サブスクライバを調べます。
imqcmd list dur -d topicName
問題を解決するには:
imqcmd purge dur コマンドを使用し、永続コンシューマを消去します。
コンシューマアプリケーションを再起動します。
考えられる原因: 予期しないブローカエラーが発生する。
この問題の原因を確認するには: 「プロデューサがコンシューマより速い」の説明に従い、QBrowser を使用してメッセージを調べます。 JMS_SUN_DMQ_UNDELIVERED_REASON の値が ERROR である場合は、ブローカエラーが発生しています。
問題を解決するには:
ブローカのログファイルを調べ、関連エラーを探します。
Sun テクニカルサポートに連絡し、ブローカの問題について報告します。