クライアントアプリケーションは、接続ファクトリ管理対象オブジェクトを使用して、ブローカとメッセージを交換するための接続を作成します。接続ファクトリの属性は、その接続ファクトリが作成するすべての接続のプロパティーを定義します。接続が作成されたあとは、そのプロパティーを変更できません。つまり、接続のプロパティーを設定するには、その作成に使用される接続ファクトリの属性を設定する必要があります。
Message Queue では、2 つのクラスの接続ファクトリオブジェクトが定義されています。
どちらのクラスも同じ設定属性を持ち、それらを使用して、リソース、パフォーマンス、およびメッセージスループットを最適化できます。これらの属性のリストと詳細な説明については、第 16 章「管理対象オブジェクト属性のリファレンス」を参照してください。次の節では、これらの属性について取り上げます。
接続処理の属性では、接続先のブローカのアドレス、および必要に応じて、接続障害の検出方法と再接続の試行方法を指定します。これらの要約については、表 16–1を参照してください。
もっとも重要な接続処理の属性は、接続の確立先となる 1 つ以上のブローカを指定する imqAddressList です。この属性の値は、ブローカのアドレスを 1 つ含む文字列、またはブローカクラスタの場合はコンマ区切りで複数含む文字列です。ブローカのアドレスには、使用する接続サービス (「接続サービス」を参照) と接続の確立方法に応じて、さまざまなアドレススキーマを使用できます。
mq。jms または ssljms 接続サービスで、ブローカのポートマッパーを使用してポートを動的に割り当てます。
mqtcp。jms 接続サービスを使用し、ポートマッパーをバイパスして、指定されたポートに直接接続します。
mqssl。ssljms 接続サービスを使用し、指定されたポートへの SSL (Secure Socket Layer) 接続を作成します。
http。httpjms 接続サービスを使用し、指定された URL の Message Queue トンネルサーブレットへの HTTP (Hypertext Transport Protocol) 接続を作成します。
https。httpsjms 接続サービスを使用し、指定された URL の Message Queue トンネルサーブレットへの HTTPS (Secure Hypertext Transport Protocol) 接続を作成します。
これらのアドレススキーマの要約については、表 16–2を参照してください。
各ブローカアドレスの一般的な形式は、次のようになります。
scheme://address
scheme は、前述のアドレススキーマのいずれかで、address は、ブローカのアドレス自体を示します。アドレスを指定するための正確な構文は、表 16–2の最後の列に示すように、アドレススキーマによって異なります。表 16–3 に、さまざまなアドレス形式の例を示します。
複数のブローカによるクラスタ環境では、アドレスリストに複数のブローカアドレスを含めることができます。最初の接続試行に失敗すると、Message Queue クライアントランタイムは、リスト内の別のアドレスに接続を試行し、成功するまでリスト内のすべてのアドレスに順に接続を試みます。2 つの追加の接続ファクトリ属性によって、この方法を制御します。
imqAddressListBehavior。指定したアドレスへの試行順序を指定します。この属性を文字列 PRIORITY に設定すると、アドレスリストに表示されている順序でアドレスが試行されます。属性値を RANDOM にすると、ランダムな順序でアドレスが試行されます。これは、たとえば、多数の Message Queue クライアントが同じ接続ファクトリオブジェクトを共有しているときに、すべてのクライアントが同じブローカアドレスに接続を試行するのを避けるためなどに便利です。
imqAddressListIterations。試行を中止して失敗を報告するまでの、リストの繰り返し回数を指定します。値 -1 は、繰り返し回数が無制限であることを示します。つまり、クライアントランタイムは、接続の確立に成功するか時間切れになるまで試行を続けます。
接続ファクトリの imqReconnectEnabled 属性を true に設定すると、接続に障害が発生した場合にクライアントがブローカに自動的に再接続するように設定できます。imqReconnectAttempts 属性では、特定のブローカアドレスに再接続を試行する回数を制御します。imqReconnectInterval 属性では、試行の間隔をミリ秒単位で指定します。
ブローカのアドレスリスト (imqAddressList) で複数のアドレスを指定するブローカクラスタでは、障害の発生した接続を、元のブローカだけでなく、クラスタ内の別のブローカでも復元できます。元のブローカへの再接続に失敗すると、クライアントランタイムは、リスト内のほかのアドレスを試行します。前述のとおり、imqAddressListBehavior および imqAddressListIterations 属性で、アドレスの試行順序とリストの繰り返し回数を制御します。各アドレスは、imqReconnectInterval ミリ秒の間隔で、imqReconnectAttempts を最大回数として、繰り返し試行されます。
自動再接続では、メッセージの消費に関するすべてのクライアント通知モードがサポートされます。接続が再確立されると、ブローカは、以前に配信した未通知メッセージをすべて再配信し、それらに Redeliver フラグを付けます。アプリケーションコードでは、このフラグを使用して、特定のメッセージが消費されたが未通知であるかどうかを判断できます。ただし、永続的でないサブスクライバの場合、ブローカは、接続が閉じられたあとはメッセージを保持しません。そのため、接続がダウンしている間にそれらのサブスクライバに対して生成されたメッセージは、再接続後に配信できず、失われることになります。自動再接続中は、メッセージ生成がブロックされます。メッセージプロデューサは、接続の再確立が完了するまで、ブローカにメッセージを送信できません。
自動再接続は、接続のフェイルオーバーを提供しますが、データのフェイルオーバーは実行しません。障害の発生したブローカまたは切断されたブローカが保持する持続メッセージ、その他の状態情報は、クライアントが別のブローカインスタンスに再接続すると失われることがあります。接続の再確立の試行中、Message Queue によって、クライアントランタイムが提供したオブジェクト (セッション、メッセージコンシューマ、メッセージプロデューサなど) は維持されます。一時的送信先も、接続に障害が発生したときは、クライアントがそれらの送信先に再接続して再度アクセスする可能性があるため、当面は維持されます。再接続してそれらの送信先を使用するための時間をクライアントに与えたあとで、ブローカはそれらを削除します。再接続時にブローカでクライアント側の状態を完全に復元できない場合 (たとえば、接続の間のみ存在する処理済セッションを使用している場合など) は、自動再接続は行われず、代わりに接続の例外ハンドラが呼び出されます。その後の例外のキャッチ、再接続、および状態の復元は、アプリケーションコードに任されます。
Message Queue クライアントランタイムは、接続を定期的にテストする、つまり「ping」を実行するように設定できます。これにより、メッセージ転送に失敗する前に、予防的に接続の障害を検出できます。メッセージを消費するだけで生成しないクライアントアプリケーションでは、接続の障害を検出する手段がほかにないため、このようなテストが特に重要です。メッセージをたまに生成するだけのクライアントでも、この機能が役立ちます。
接続ファクトリ属性 imqPingInterval では、接続で ping を実行する頻度を秒単位で指定します。デフォルトでは、この間隔は 30 秒に設定されます。値 -1 を指定すると、ping の実行が無効になります。
失敗した ping への対応は、オペレーションシステムのプラットフォームによって異なります。一部のオペレーティングシステムでは、ただちに、クライアントアプリケーションの例外リスナーに例外がスローされます。クライアントに例外リスナーがない場合は、その接続を使用するための次回の試行に失敗します。また、オペレーティングシステムによっては、ブローカへの接続の確立を試行し続け、ping が成功するかバッファーがオーバーフローするまで、一連の ping をバッファリングするものもあります。
表 16–4 に示されている接続ファクトリ属性は、クライアント認証と、永続サブスクライバのクライアント識別子の設定をサポートしています。
ブローカへのすべての接続試行は、ユーザー名とパスワードによって、メッセージサービスが管理するユーザーリポジトリに対して認証される必要があります。接続ファクトリ属性 imqDefaultUsername および imqDefaultPassword では、クライアントが接続の作成時にユーザー名とパスワードを明示的に提供しなかった場合に使用するデフォルトのユーザー名とパスワードを指定します。
開発者がアプリケーションの開発およびテストの際にユーザーリポジトリを設定する手間を省くことができるように、Message Queue には、ユーザー名とパスワードがどちらも guest に設定されたゲストユーザーアカウントが用意されています。これは、imqDefaultUsername および imqDefaultPassword 属性のデフォルト値でもあるため、これらが明示的に指定されていない場合、クライアントは常にゲストアカウントで接続を取得できます。本稼動環境では、ブローカ接続へのアクセスは、ユーザーリポジトリに明示的に登録されているユーザーのみに制限するべきです。
『Java Message Service 仕様書』では、ブローカがクライアントに代わって持続状態を維持する必要があるときは常に、接続で一意のクライアント識別子を提供することが要求されています。Message Queue は、このクライアント識別子を使用して、トピック送信先への永続サブスクライバを追跡します。永続サブスクライバが非アクティブになると、ブローカは、そのトピックのすべての受信メッセージを保持し、サブスクライバが再度アクティブになったときにそれらを配信します。ブローカは、クライアント識別子によってサブスクライバを識別します。
クライアントアプリケーションが接続オブジェクトの setClientID メソッドを使用してプログラムによって独自のクライアント識別子を設定することは可能ですが、この場合、クライアント識別子が互いに一意になるように調整するのが難しくなります。一般的には、Message Queue が、クライアントに代わって接続を作成するときに一意の識別子を自動的に割り当てるようにすることをお勧めします。このためには、接続ファクトリの imqConfiguredClientID 属性を、次の形式の値に設定します。
${u}factoryID
この属性値の先頭の 4 文字は必ず、${u} になります。括弧内に u 以外の文字があると、接続の作成時に例外がスローされます。先頭以外の位置では、これらの文字は特別な意味を持たず、プレーンテキストとして扱われます。factoryID の値は、この接続ファクトリオブジェクトに一意に関連付ける文字列です。
特定のクライアントの接続を作成するときに、Message Queue は、文字列 $\ を u:userName に置き換えることによってクライアント識別子を生成します。userName は、接続で認証されたユーザー名です。これにより、特定の接続ファクトリによって作成された接続がそれぞれ、ほかのすべての面で同一であっても、一意のクライアント識別子を持つことが保証されます。たとえば、ユーザー名が Calvin で、接続ファクトリの imqConfiguredClientID 属性に指定された文字列が ${u}Hobbes である場合、割り当てられるクライアント識別子は u:CalvinHobbes になります。
2 つのクライアントがデフォルトユーザー名 guest を使用して接続を取得しようとした場合、それぞれが同じ ${u} 要素を含むクライアント識別子を持つことになるため、このスキーマは動作しません。この場合は、先に接続を要求したクライアントだけが接続を取得します。Message Queue は同じクライアント識別子を持つ 2 つの接続を作成できないため、あとのクライアントの接続試行は失敗します。
imqConfiguredClientID を使用してクライアント識別子を指定する場合でも、クライアントアプリケーションは、接続メソッド setClientID を使用してこの設定を上書きできます。接続ファクトリの imqDisableSetClientID 属性を true に設定することで、これを避けることができます。永続サブスクライバを使用するアプリケーションでは、クライアント識別子を必ず設定する必要があります。その方法は、管理のために imqConfiguredClientID を使用するか、プログラムによって setClientID を使用するかのいずれかです。
クライアントが送受信する「ペイロード」メッセージと Message Queue 自体が使用する制御メッセージ (ブローカ通知など) は、クライアントとブローカ間の同じ接続でやり取りされるため、ペイロードのトラフィックが過剰になると、制御メッセージの配信が妨げられる可能性があります。この問題を軽減するために、表 16–5 に示されている接続ファクトリ属性を使用して、2 種類のメッセージの相対的なフローを管理できます。これらの属性は、4 つのカテゴリに分類されます。
通知タイムアウト: 例外をスローするまでのブローカ通知の最大待ち時間 (imqAckTimeout) を指定します。
接続フロー測定: ペイロードメッセージの転送を、指定したサイズ (imqConnectionFlowCount) のバッチに制限します。これにより、累積された制御メッセージを配信する機会が定期的に得られます。
接続フロー制御: 特定の接続で、消費を待って保留状態になるペイロードメッセージの数 (imqConnectionFlowLimit) を制限します。制限に達すると、消費待ちのメッセージの数が制限を下回るまで、その接続へのペイロードメッセージの配信が一時停止されます。この機能の使用は、ブール型のフラグ (imqConnectionFlowLimitEnabled) によって制御します。
コンシューマフロー制御: 単一のコンシューマに対して、消費を待って保留状態になるペイロードメッセージの数 (imqConsumerFlowLimit) を制限します。この制限は、特定のキュー送信先のプロパティー (consumerFlowLimit) として指定することもできます。制限に達すると、消費待ちのメッセージの数が、imqConsumerFlowLimit に対する割合として imqConsumerFlowThreshold 属性で指定した制限を下回るまで、そのコンシューマへのペイロードメッセージの配信が一時停止されます。同じ接続上で 1 つのコンシューマがほかのコンシューマの通信を妨げるのを回避することによって、複数のコンシューマ間のロードバランスを向上させるのに役立ちます。
これらのフロー制御技術のいずれを使用する場合でも、信頼性とスループットの兼ね合いを考慮する必要があります。詳細は、「クライアントランタイムのメッセージフローの調整」を参照してください。
表 16–6に、クライアントのキュー検索とサーバーセッションに関する接続ファクトリ属性が示されています。imqQueueBrowserMaxMessagesPerRetrieve 属性では、キュー送信先の内容の検索時に一度に取得するメッセージの最大数を指定します。imqQueueBrowserRetrieveTimeout 属性では、メッセージ取得の最大待ち時間を指定します。imqQueueBrowserMaxMessagesPerRetrieve は、検索されるメッセージの総数には影響せず、クライアントランタイムに配信するためにチャンクされる方法だけに影響します。つまり、サイズの大きいチャンクを少数にするか、サイズの小さいチャンクを多数にするか、です。クライアントアプリケーションは、常にキュー内のすべてのメッセージを受信します。属性の値の変更は、パフォーマンスに影響することがありますが、受信するデータの総量には影響しません。ブール型の imqLoadMaxToServerSession 属性では、アプリケーションサーバーセッションでの接続コンシューマの動作を制御します。この属性の値が true の場合、クライアントは、1 回のサーバーセッションで最大数までのメッセージを読み込みます。false の場合は、一度に 1 つのメッセージだけを読み込みます。
『Java Message Service 仕様書』では、Message Queue などの JMS プロバイダが任意でサポートできる、いくつかの標準メッセージプロパティーを定義しています。規定によって、これらの標準プロパティーの名前はすべて、JMSX という文字列で始まります。表 16–7 control whether the Message Queue に示されている接続ファクトリ属性では、クライアントランタイムがこれらいずれかの標準プロパティーを設定するかどうかを制御します。生成されたメッセージについては、次のプロパティーがあります。
JMSXUserID メッセージを送信するユーザーの識別情報
JMSXAppID メッセージを送信するアプリケーションの識別情報
JMSXProducerTXID メッセージが生成されたトランザクションのトランザクション識別子
消費されたメッセージについては、次のものがあります。
JMSXConsumerTXID メッセージが消費されたトランザクションのトランザクション識別子
JMSXRcvTimestamp コンシューマにメッセージが配信された時刻
表 16–8に示されている接続ファクトリ属性を使用して、クライアントが特定の JMS メッセージヘッダーフィールドに設定した値を上書きできます。指定した設定は、その接続ファクトリから取得された接続が生成するすべてのメッセージに使用されます。この方法で上書きできるヘッダーフィールドには次のものがあります。
これらのフィールドにはそれぞれ、2 つの属性があります。フィールドが上書き可能であるかどうかを制御するブールの属性と、フィールドの値を指定する属性です。たとえば、優先度のレベルを設定するための属性は、imqOverrideJMSPriority と imqJMSPriority です。さらに、上書きの値を一時送信先に適用するかどうかを制御する imqOverrideJMSHeadersToTemporaryDestinations 属性もあります。
メッセージヘッダーを上書きすると、特定のアプリケーションの要件に支障を及ぼす可能性があるため、これらの属性は、必ずアプリケーションの設計者またはユーザーに相談した上で使用することをお勧めします。