![]() |
Sun ONE Message Queue 開発者ガイド |
第 4 章 クライアントの最適化
JMS クライアントのパフォーマンスは、クライアントアプリケーション固有の設計と MQ クライアントランタイムの機能と能力に依存します。この章では、MQ クライアントランタイムが JMS クライアントのメッセージング機能をサポートする仕組み、特にパフォーマンスとメッセージスループットの改善に役立つプロパティおよび動作の設定について説明します。
メッセージのプロデュースとコンシューム
MQ クライアントランタイムは、JMS クライアントに MQ メッセージサーバへのインタフェースを提供します。つまり、クライアントランタイムによって、「JMS プログラミングモデル」に記載されるすべての JMS プログラミングオブジェクトがクライアントに提供されます。クライアントランタイムでは、送信先にメッセージを送信し、送信先からメッセージを受信する場合に、クライアントに必要なすべての処理がサポートされます。この節では、MQ クライアントランタイムがどのようにメッセージをプロデュースしコンシュームするかについて詳しく説明します。図 4-1 は、クライアントと MQ クライアントランタイム間の対話におけるメッセージのプロデュースとコンシュームの様子と、MQ クライアントランタイムと MQ メッセージサーバ間の対話におけるメッセージの配信の様子について示しています。
図 4-1    メッセージングの処理
![]()
クライアントによってブローカへのコネクションが作成されると、メッセージ配信用のシングルスレッドコンテキストとしてセッションが作成されます。さらに、メッセージサーバ内の特定の送信先にアクセスするために必要な MessageProducer と MessageConsumer オブジェクトが作成され、メッセージのプロデュース (送信) およびコンシューム (受信) が行われます。
メッセージのプロデュース
メッセージのプロデュースでは、クライアントによってメッセージが作成され、ブローカ上の送信先へのコネクションを介して送信されます。MessageProducer オブジェクトのメッセージ配信モードが、持続的 (配信を 1 回だけ保証する) に設定されている場合、メッセージが送信先に配信されて、ブローカの持続データストアに保存されたことをブローカが通知するまで、クライアントスレッドがブロックされます。メッセージが持続的でない場合、ブローカの通知メッセージ (「Ack」というプロパティ名で呼ばれる) は返されず、クライアントスレッドはブロックされません。持続メッセージの場合、スループットを改善するため、ブローカの通知を必要としないコネクションを設定できます (表 4-7 の imqAckOnProduce プロパティを参照)。ただし、この設定では、持続的メッセージの確実な配信を保証できません。
メッセージのコンシューム
メッセージのコンシュームは、プロデュースより複雑です。ブローカの送信先に到着したメッセージは、次の条件に基づいて MQ クライアントランタイムへのコネクションで配信されます。図 4-2 に示されるように、コネクションで配信されるメッセージは、適切な MQ セッションに分散されます。ここで、メッセージは適切な MessageConsumer オブジェクトによってコンシュームされるために、キューに入れられます。メッセージは、1 つずつ各セッションキューからフェッチされ (セッションはシングルスレッドになる)、receive メソッドを呼び出すクライアントスレッドによって同期的、または MessageListener オブジェクトの onMessage メソッドを呼び出すセッションスレッドによって非同期的にコンシュームされます。
図 4-2    MQ クライアントランタイムへのメッセージの配信
![]()
ブローカがクライアントランタイムにメッセージを配信する場合、ブローカはそれに応じてメッセージをマークしますが、メッセージが受信、またはコンシュームされたかどうかは、実際には把握していません。このため、ブローカは、ブローカの送信先からメッセージを削除する前に、クライアントがメッセージの受信を通知するのを待ちます。
JMS 仕様に基づいて、クライアント開発者は、クライアントセッションに次の 3 つの通知オプションを設定できます。
AUTO_ACKNOWLEDGE: クライアントがコンシュームした個々のメッセージが、セッションによって自動的に通知されます。
これら 3 つの通知オプションでは、それぞれ異なった処理レベルと帯域幅オーバーヘッドが必要になります。最もオーバーヘッドの高い自動通知では、メッセージごとにその信頼性が保証されます。これに対して、最もオーバーヘッドの低い DUPS_OK_ACKNOWLEDGE では、メッセージの重複配信が可能です。CLIENT_ACKNOWLEDGE: 1 つまたは複数のメッセージがコンシュームされたあと、クライアントによって明示的に通知が行われます。このオプションを指定すると、ほとんどの制御をクライアントで行うことができます。この通知は、メッセージオブジェクトの acknowledge() メソッドを呼び出すことによって行われます。セッションは、現時点までにコンシュームされたすべてのメッセージを通知します。これには、セッション内の複数のメッセージリスナーによって非同期方式でコンシュームされたメッセージも含まれます。なお、メッセージがコンシュームされた順番は考慮されません。
DUPS_OK_ACKNOWLEDGE: 設定可能な複数のメッセージがコンシュームされたあと、セッションによって通知されます。これらのメッセージが必ず 1 回配信され確実にコンシュームされることを保証しません。クライアントは、メッセージが複数回処理されるかどうかを考慮する必要がない場合に、このモードを使用します。
AUTO_ACKNOWLEDGE オプションまたは CLIENT_ACKNOWLEDGE オプションを指定した場合、通知を行うか、またはトランザクションをコミットするスレッドはブロックされ、クライアントの通知の受信を知らせる制御メッセージがブローカから返されるまで待機します。このブローカの通知 (プロパティ名は「Ack」) により、対応するコネクションメッセージがブローカによって削除され、二度と送信されないことが保証されます。ただし、クライアントやブローカに障害が発生したりコネクションに障害が発生したような故障時を除きます。
スループットを改善するため、クライアントの通知の受信を知らせるブローカの通知を必要としないコネクションを設定できます (表 4-5 の imqAckOnAcknowledge プロパティを参照)。ただし、この設定では、コネクションメッセージの確実な配信を保証できません。
MQ クライアントランタイムの設定可能なプロパティ
MQ クライアントランタイムは、「メッセージのプロデュースとコンシューム」で説明されるすべての操作をサポートします。また、リソース、パフォーマンス、メッセージスループットの最適化に役立つ多くの設定可能なプロパティも提供します。これらのプロパティは、JMS クライアントと MQ メッセージサーバ間の物理コネクションを作成するために使用する ConnectionFactory オブジェクトの属性に対応しています。ConnectionFactory オブジェクトは、クライアントからブローカへのコネクションを確立するために使用されるだけであり、実際にブローカ内に存在するわけではありません。また、ConnectionFactory オブジェクトは、コネクションの動作や、ブローカにアクセスするためにコネクションを使用するクライアントランタイムの動作を指定する場合にも使用します。ConnectionFactory は、クライアントが設定するメッセージヘッダーの値をオーバーライドする機能により、MQ メッセージサーバの管理にも使用されます。
分散トランザクション (「ローカルトランザクション」を参照) をサポートする場合は、分散トランザクションをサポートする特殊な XAConnectionFactory オブジェクトを使用する必要があります。
第 3 章「管理対象オブジェクトの使用」で示されるように、ConnectionFactory 管理対象オブジェクトは、管理者が作成するか、クライアントコード内でインスタンス化します。
ConnectionFactory 管理対象オブジェクトを構成することによって、オブジェクトがプロデュースするすべてのコネクションに共通する属性値 (プロパティ) を指定します。ConnectionFactory オブジェクトと XAConnectionFactory オブジェクトは、一連の同じ属性値を共有します。これらの属性値は、影響を及ぼす動作に基づいて、いくつかのカテゴリに分類されます。
各カテゴリについては、それぞれの ConnectionFactory (または XAConnectionFactory) 属性とともに、次の節で説明します。『MQ 管理者ガイド』で示されているように、属性値の設定には MQ 管理ツールを使用します。
コネクションの指定
コネクションは、ブローカのホスト名、ポートマッパー (または特定のコネクションサービス) があるポートの番号、サポートしているコネクションサービスの種類によって指定されます。コネクションタイプ (コネクションサービスが使用するプロトコル) によっては、追加の属性値を設定しないとコネクションが動作しない場合もあります。表 4-1 に、コネクションの動作に影響を及ぼす属性を示します。
自動再コネクションの動作
MQ には自動再コネクション機能があります。コネクションに障害が発生した場合、MQ は、クライアントランタイムが提供するオブジェクト (セッション、メッセージコンシューマ、メッセージプロデューサなど) を維持したまま、再コネクションを試みます。処理済みセッションの場合、再コネクションによる影響は不明であり、その際の動作は予測できません。一方、処理済みセッションでない場合、再コネクションによる影響はメッセージのプロデュースとメッセージのコンシュームで異なります。
メッセージのプロデュース
再コネクションの間、プロデューサはメッセージを送信できません。この場合、例外がスローされます。プロデューサは、再度コネクションが確立されるまでコネクションを再試行する必要があります。一時的な送信先は、コネクションが確立されている間だけ存在します。これらは、再度コネクションが確立されたときには失われます。
メッセージのコンシューム
コンシューマは、自動再コネクションの試行中も、クライアントランタイムに配信されたメッセージをコンシュームできます。ただし、再コネクションの動作は次のいくつかの要因によって異なります。
CLIENT_ACKNOWLEDGE を使ったセッションの場合、持続的サブスクライバまたはキューの受信側に通知されていないメッセージが再配信される
表 4-2 に、自動接続機能の動作に影響を及ぼす属性を示します。AUTO_ACKNOWLEDGE を使ったセッションの場合、持続的サブスクライバまたはキューの受信側に最後に配信されたメッセージが再配信される (まだ通知されていない可能性があるため)
持続的サブスクライバではない場合、コネクションの修復処理の間、次のようなメッセージは配信されない
クライアントの識別
クライアントは、認証と持続的サブスクリプションの追跡のためにブローカに識別される必要があります (「クライアント識別子」を参照)。認証のため、MQ はデフォルトのユーザ名とパスワードを提供します。ユーザリポジトリを明示的に設定する必要がない場合、開発者はこれらを便利に使用できます (『MQ 管理者ガイド』を参照)。
MQ は、永続的サブスクリプションを追跡するため、一意のクライアント ID (ClientID) を使用します。トピック送信先にメッセージが配信されたとき、永続的サブスクライバが非アクティブになっていると、ブローカはそのサブスクライバ宛てのメッセージを保存し、サブスクライバがアクティブになったときに配信します。ブローカがサブスクライバを識別する唯一の方法は ClientID を使用する方法です。
コネクションのために ClientID を設定する方法には、さまざまな方法があります。たとえば、クライアントコードでは、Connection オブジェクトの setClientID() メソッドを使用できます。どのような方法を使用する場合でも、ClientID は、コネクションを使用する前に設定しなければなりません。コネクションの使用後は ClientID の設定または再設定はできません。
クライアントコード内に ClientID を設定する方法が最適というわけではありません。各ユーザには一意の ID が必要です。つまり、調整が一元的に行われることを意味します。このため、MQ は ConnectionFactory オブジェクトに imqConfiguredClientID 属性を提供します。この属性を使用して、各ユーザに一意の ClientID を提供できます。この機能を使用するには、次のように imqConfiguredClientID の値を設定します。
特殊な予約文字 ${u} により、コネクションを確立するためのユーザ認証時に一意のユーザ識別子が提供されます。string は ConnectionFactory オブジェクト固有のテキスト値です。適切に使用した場合、MQ メッセージサーバは u を u:username に置き換え、ユーザ固有の ClientID を生成します。
${u} は、必ず属性値の最初の 4 文字から始める必要があります。「u」以外の文字が検出された場合、コネクションの作成時に JMS 例外がスローされます。属性値の先頭以外の文字で ${} を使用した場合、この文字列はプレーンテキストと見なされ、変数置換は行われません。
追加属性 imqDisableSetClientID を true に設定して、コネクションファクトリを使用するクライアントが Connection オブジェクトの setClientID() メソッドを使用して構成可能な ClientID を変更できないようにすることができます。
配置済みアプリケーション内で永続的サブスクリプションを使用する場合は、プログラム内で setClientID() メソッドを使用するか、ConnectionFactory オブジェクトの imqConfiguredClientID 属性を使用する方法でクライアント識別子を設定する必要があります。
表 4-3 に、クライアント ID に影響を及ぼす属性を示します。
メッセージヘッダーのオーバーライド
MQ 管理者は、メッセージの持続性、有効期間、優先度を指定する JMS メッセージヘッダーフィールドをオーバーライドできます。特に、次のフィールドの値をオーバーライドできます (「Java XML Messaging (JAXM) 仕様書」を参照)。MQ 管理者は、メッセージヘッダーの値をオーバーライドすることにより、MQ メッセージサーバのリソースをより厳密に管理できます。ただし、オーバーライドする内容とアプリケーション固有の要件 (メッセージの持続性など) が衝突する可能性もあります。したがって、この機能は、必ず適切なアプリケーションユーザか設計者と相談して使用してください。
MQ では、コネクションレベルでメッセージヘッダーをオーバーライドできます。オーバーライドは、指定されたコネクションのコンテキストで作成されたすべてのメッセージに適用され、対応するコネクションファクトリ管理対象オブジェクトの属性を設定することにより構成されます。これらの属性は、表 4-4 に示されています。
信頼性およびフローの制御
クライアントランタイムによる MQ 制御メッセージ、特にブローカの通知 (属性名内の「Ack」で表される) の使用方法とフローは、さまざまな属性によって決定されます。表 4-5 に、信頼性とフローの制御に影響を及ぼす属性を示します。
キューブラウザの動作
表 4-6 に、クライアントランタイムのキューブラウザの動作に影響を及ぼす属性を示します。
アプリケーションサーバのサポート
アプリケーションサーバ環境のセッションの動作は、表 4-7 に示す属性による影響を受けます。基本的な情報は、JMS 仕様書を参照してください。
JMS 定義のプロパティのサポート
JMS 定義のプロパティの名前は、JMS によって予約されています。JMS プロバイダは、これらのプロパティをサポートするかどうかを選択できます (「Java XML Messaging (JAXM) 仕様書」を参照)。これらのプロパティは、クライアントのプログラミング機能を拡張します。表 4-8 に MQ がサポートする JMS 定義のプロパティを示します。
パフォーマンス要因
ブローカとのメッセージのやりとりのメカニズムと、信頼性の高い配信を確保するために使用されるさまざまな MQ 制御メッセージにより、いくつかの要因がメッセージのフローとコンシュームに影響します。メッセージのスループットとパフォーマンスに影響を与える要因には、配信モード、メッセージフローの測定、メッセージフローの制限、通知モード、およびセッション数があります。これらの要因はまったく別個のものですが、相互作用があるため、特定のクライアントのパフォーマンスにどの要因が影響を与えているかを判別するのは困難です。
配信モード メッセージは、配信モードによって、1 回だけ配信される場合と (非持続)、必ず 1 回は確実に配信される場合 (持続) があります。配信モードにより信頼性の要件も異なるため、オーバーヘッドの大きさが変わります。特に、ブローカ、クライアントに障害が発生したり、コネクションが失われたときなどに、持続メッセージが失われないようにしたり、2 回配信したりして配信を保証する場合にオーバーヘッドは大きくなります。たとえば、クライアントとブローカの制御メッセージがコネクション全体にフローする数、およびクライアントとブローカの通知の処理が、メッセージのスループットとパフォーマンスに大きな影響を与えます。
メッセージフロー測定 JMS クライアントによって送受信されるメッセージ (JMS メッセージ) と MQ 制御メッセージは、同じクライアントとブローカのコネクションを使って伝送されます。これが、制御メッセージのフローのボトルネックになる可能性があります。たとえば、ブローカのコネクションがクライアントに配信される JMS メッセージでいっぱいになっているとします。この場合には、ブローカの通知など制御メッセージの配信遅延が発生する可能性があります。このように、遅延が発生する場合は、大量の JMS メッセージ配信によって制御メッセージの配信が停滞している可能性があります。このようなネットワークの混雑を防止するため、MQ はコネクション全体の JMS メッセージのフローを測定します。JMS メッセージはバッチ処理されるので、一定数の JMS メッセージが配信されると配信処理が一時的に停止します。JMS メッセージの配信処理が再開される前に、それまで待ち状態だった制御メッセージがクライアントに配信されます。JMS メッセージのこのような測定バッチ内のメッセージ数を指定できます (表 4-5 の imqFlowControlCount プロパティを参照)。大量の JMS メッセージが配信される場合は、この数を小さくすると、制御メッセージがコネクション全体にフローされる遅延時間が短縮できます。
メッセージフロー制限 MQ クライアントランタイムコードは、メモリーなどのローカルリソースが限界に達するまでに、処理できる JMS メッセージの配信数を制限できます。この数に達すると、パフォーマンスに悪影響が出ます。このため、MQ では、クライアントへの JMS メッセージのフローを制御することで、セッション内のコンシューム待ちメッセージ数を制限できるようになっています。具体的には、しきい値を指定します (表 4-5 の FlowControlLimit を参照)。バッチ処理で配信される JMS メッセージ (「メッセージフロー測定」を参照) の数がこのしきい値を超過すると、クライアントランタイムは待機し、コンシュームされないメッセージ数がしきい値を下回ったときに JMS メッセージの配信要求を再開します。その後、再度しきい値に達するまで配信処理が続行されます。
クライアント通知モード コネクション上で送受信されるクライアントおよびブローカ通知メッセージの数は、クライアント通知モードによって異なります。
AUTO_ACKNOWLEDGE モードでは、コンシュームされるメッセージごとにクライアントとブローカの通知が要求される。セッションスレッドはブロックされ、ブローカの通知が得られるまで待機する
CLIENT_ACKNOWLEDGE モードでは、クライアントとブローカの通知がバッチ処理される (通知はメッセージごとに送信されない)。このモードでは、コネクション帯域幅を節約できる。また、通常ブローカ通知の待ち時間も短縮される
DUPS_OK_ACKNOWLEDGE モードでは、クライアントの通知がバッチ処理で行われ、クライアントスレッドがブロックされない (ブローカの通知が要求されない) ため、スループットが一層改善される。ただし、同じメッセージを 1 回以上配信し、コンシュームすることはできない
セッション数とコネクション数 セッション内で待ち状態になっているメッセージの数と、これらの処理にかかる時間によって、セッション内のメッセージコンシューマの数と、各コンシューマに読み込めるメッセージの数が決まります。クライアント側のメッセージのプロデュースまたはメッセージのコンシュームに遅延が発生する場合は、アプリケーションを再設計し、より多くのセッションにメッセージプロデューサとメッセージコンシューマを分散し、またはより多くのコネクションにセッションを分散してパフォーマンスを改善できます。
前へ 目次 索引 次へ
Copyright © 2002 Sun Microsystems, Inc. All rights reserved.
最終更新日 2002 年 6 月 19 日