Oracle® Fusion Middleware Oracle WebLogic Server JMSのプログラミング 11gリリース1 (10.3.6) B61629-04 |
|
前 |
次 |
この章では、サーバーやネットワークの障害発生時にWebLogic JMSクライアント・アプリケーションが再接続または回復する方法、および障害後にJMSデータを移行する方法について説明します。
JMSクライアントの自動再接続機能では、サーバーまたはネットワークに障害が発生した場合でも、一部のJMSクライアント・オブジェクトは、使用可能な他のサーバー・インスタンスがある限りそのサーバー・インスタンスに透過的にフェイルオーバーします。たとえば、致命的なサーバー障害が発生した場合、サーバーが使用可能な状態になるとJMSクライアントが自動的に再接続を試みます。
ネットワーク接続の失敗の原因としては、一過性のもの(ネットワーク接続の一時的な中断)と一過性でないもの(サーバーのバウンスまたはネットワーク障害)が考えられます。これらの場合、一部のJMSクライアント・オブジェクトは、クラスタ内の他のサーバー・インスタンス(可能であればホスト・サーバー)での稼動を自動的に試みます。
デフォルトでは、既存のクライアント・コードを手動で構成または変更しなくても、JMSプロデューサ・セッション・オブジェクトが自動的に使用可能なサーバー・インスタンスに再接続しようとします。JMSプロデューサが自動的に再接続しないようにするには、プログラムまたは管理機能を使用して、この機能を明示的に無効にする必要があります。
また、JMSコンシューマ・セッション・オブジェクトが自動的に使用可能なサーバーに再接続するように構成することもできます。ただし、JMSコンシューマ・セッション・オブジェクトは本質的に非同期オブジェクトであるため、管理コンソールまたは公開されているWebLogic JMS APIを使用して、この機能を明示的に有効にする必要があります。
詳細については、以下の節を参照してください。
自動再接続ロジックは、多数の障害シナリオでクライアントにシームレスなフェイルオーバーを提供します。ただし、メッセージ処理結果が不明でWebLogic Serverが例外をスローするいくつかの接続障害シナリオがあります。使用するアプリケーションは例外を適切に処理する必要があります。たとえば:
メッセージの送信処理が冪等の場合、メッセージを再送信します。
それ以外の場合、使用するアプリケーションは一部のアクションを実行する必要があります。たとえば、重複を避けるために再送信する前にメッセージがキュー上で使用可能かどうかを確認する必要があります。
注意: 宛先または分散宛先メンバーが使用できない場合、当該メンバーが使用可能になるまでメッセージの送信処理が正常に実行されたかどうかを判定できません。 |
次のJMSオブジェクトの暗黙的なフェイルオーバーは、WebLogic Server 9.2ではサポートされていません。
キュー・ブラウザ(javax.jms.QueueBrowser
)。
WebLogic JMSシン・クライアント(wljmsclient.jar)は、自動的に再接続しません。
再接続ごとにリセットされるクライアントの統計(結果としてクライアントの履歴データは失われます)。
ある状況下では、自動再接続は可能になりません。可能にならない場合、例外が報告されます。
一時的な宛先(javax.jms.TemporaryQueue
およびjavax.jms.TemporaryTopic
)。
ヒント: サーバーやネットワークに障害が発生した後でも、一時的な宛先にアクセスできることがあります。これは、サーバーのロード・バランシングの結果として、一時的な宛先が常にローカル接続ファクトリと同じサーバー・インスタンスにあるとは限らないためです。したがって、サーバーやネットワークに障害が発生した後も一時的な宛先にアクセスでき、プロデューサからのメッセージが引続き送信されている場合、自動的に再接続されたコンシューマが、障害前に接続されていたのと同じ一時宛先からのメッセージを消費できるかどうかは分かりません。 |
ほとんどの場合、JMSプロデューサ・アプリケーションは、使用可能な他のサーバー・インスタンスがあれば透過的にフェイルオーバーします。以下に示すWebLogic JMSプロデューサ指向のオブジェクトは、既存のクライアント・コードを手動で構成または変更しなくても、使用可能なサーバー・インスタンスへの再接続を自動的に試みます。
接続
セッション
MessageProducer
JMSクライアントが自動的に再接続しないようにするには、プログラムまたは管理機能を使用して、この機能を明示的に無効にする必要があります。詳細については、「JMSクライアントの自動フェイルオーバーを明示的に無効にする」を参照してください。
ネットワーク障害が発生すると、メッセージ生成用のWebLogic JMSクライアント・コードによって、使用可能なサーバーへの再接続が試行されます(例14-1のステップ3 - 8を参照)。
例14-1 メッセージ生成用のJMSクライアント・コードのサンプル
//set exception listener 1. public void onException(javax.jms.JMSException jsme) { connection.setExceptionListener // handle the exception, which may require checking for duplicates // or sending the message again } 2. Context ctx = create WebLogic JNDI context with credentials etc. 3. ConnectionFactory cf = ctx.lookup(JNDI name of connection factory) 4. Destination dest = ctx.lookup(JNDI name of destination) // the following operations recover from network failures 5. Connection con = cf.createConnection() 6. Session sess = con.createSession(no transactions, ack mode) 7. MessageProducer prod = sess.createProducer(dest) 8. Loop over: 9. Message msg = sess.createMessage() // try block to handle destination availablitiy scenarios 10. try { prod.send(msg)} catch (Some Destination Availability Exception e) { //handle the exception, in most cases, the destination or member //is not yet available, so the code should try to resend } //end loop // done sending messages 11. con.close(); ctx.close();
JMSプロデューサは、使用可能な他のサーバー・インスタンスがあれば透過的にフェイルオーバーします。これにより、クライアント・コードは上記のように単純な記述のまま保持され、ネットワーク障害の時点で再試行するクライアント・コードは不要になりました。
WebLogic JMSのデフォルトでは、MessageConsumerは再接続されません。これがプログラム的に再接続されるようにするには、setReconnectPolicy
を"all"
に設定したWebLogic WLConnection
拡張をクライアント・アプリケーション・コードから呼び出す必要があります。詳細については、「JMSコンシューマの自動フェイルオーバーの構成」を参照してください。
JNDIでルックアップされたConnectionFactoryオブジェクト(例14-1および例14-2のステップ1を参照)は、サーバーまたはネットワークの障害後に再度ルックアップすることなく再使用できます。ネットワーク障害には、JMSクライアントJVMと、それがJNDIルックアップの一部として接続されているリモートWebLogic Serverインスタンスとの間の障害の場合、またはJMSクライアントJVMと、JMSクライアントが後で接続する同じクラスタ内の任意のリモートWebLogic Serverインスタンスとの間の障害の場合があります。
JNDIでルックアップされたDestinationオブジェクト(キューまたはトピック。例14-1および例14-2のステップ2を参照)は、サーバーまたはネットワークの障害後に再度ルックアップすることなく再使用できます。この点は、分散宛先への送信を行うプロデューサの場合も同様です。クライアントは、JNDIで分散宛先をルック・アップし、使用不能な分散メンバーはルック・アップされないためです。
ネットワーク障害には、クライアントJVMと、それが接続されているWebLogic Serverインスタンスとの間の障害の場合、またはそのWebLogic Serverインスタンスと、実際に宛先をホストしているWebLogic Serverインスタンスとの間の障害の場合があります。Destinationオブジェクトは、その宛先をホストしているWebLogic Serverインスタンスが再起動した後も引続き使用できます。
JMS Connectionオブジェクトは、クライアントJVMとリモートWebLogic Serverインスタンスとの間の物理的なネットワーク接続に1対1でマップするために使用されます。JMSクライアントの再接続機能では、ConnectionFactory.createConnection()
メソッドからクライアントが取得するJMS Connectionオブジェクト(例14-1および例14-2のステップ3を参照)は、「一度に1対1」の方式で物理的なネットワーク接続にマップされます。結果として、JMSクライアントは引続き同じConnectionオブジェクトを使用している一方で、暗黙的なフェイルオーバーの後、実際には異なるWebLogic Serverインスタンスと通信している場合があります。
ネットワークが切断された後、接続が暗黙的にリフレッシュされると、その接続から派生するすべてのオブジェクト(javax.jms.Session
オブジェクト、javax.jms.MessageProducer
オブジェクトなど)も暗黙的にリフレッシュされます。リフレッシュ時には、サーバーにアクセスする接続やその派生オブジェクトでのすべての同期処理(producer.send()
、connection.createSession()
など)を、接続がリフレッシュされていないと判断される前に一定時間ブロックすることができます。この時間は、管理コンソールを使用して構成するか、weblogic.jms.extension.WLConnection
インタフェースのsetReconnectBlockingMillis(long)
APIを使用して構成します。
再接続機能では、アプリケーションがconnection.close()
を呼び出すまで、WebLogic ServerインスタンスのConnectionFactoryオブジェクトへの再接続がバックグラウンドで試行され続けます。ReconnectBlockingMillis
パラメータは、接続がバックグラウンドで再試行されているときに接続を使用しようとしている同期呼出し側のタイムアウトです。
接続がリフレッシュされる前に同期呼出しがタイムアウトすると、暗黙的な再接続が行われない場合とまったく同じように動作します(同じ例外がスローされます)。つまり、同期呼出しは再接続機能のない古くなった接続で呼び出された場合と同じように動作します。
その後、呼出し側は同期呼出しを単純に再試行するか(重複メッセージのようにサービスの質は低くなるおそれがあります)、または接続のバックグラウンドでの再試行を終了するconnection.close()
を呼び出すかを決定できます。
以下では、プロデューサ接続がリフレッシュされるときに発生する可能性のある特殊なケースについて説明します。
恒久サブスクライバのClientIDが指定されているConnection - 「再接続ポリシー」フィールドが「なし」または「プロデューサ」に設定されている場合、ネットワークまたはサーバーの障害が発生したときにJMS ConnectionにClientIDが指定されていると、そのConnectionは自動的にはリフレッシュされません。この制限の理由は下位互換性にあります。障害の後、同じ接続名でJMS Connectionを再作成しようとする既存のJMSアプリケーションが中断されるのを回避するためです。ネットワーク障害に対して暗黙的なフェイルオーバーも実行されると、アプリケーションによる接続の作成は重複したClientIDが原因で失敗します。
クローズされたオブジェクトはリフレッシュされない - アプリケーションがjavax.jms.Connection.close()
、javax.jms.Session.close()
などを呼び出した場合、そのオブジェクトとその派生オブジェクトはリフレッシュされません。同様に、JMSクライアントのConnectionが管理上の理由で破棄された場合も、そのConnectionはリフレッシュされません。
例外リスナーが登録されているConnection - JMS ConnectionにアプリケーションのExceptionListenerが登録されている場合、そのExceptionListenerのonException()
コールバックは接続が暗黙的にリフレッシュされた場合でも呼び出されます。このコールバックは、アプリケーション・コードにネットワーク切断イベントを通知します。JMSクライアント・アプリケーション・コードは通常、onException
でconnection.close()
を呼び出しますが、再接続機能を使用する場合はconnection.close()
を呼び出さないように選択することもできます。登録済みのExceptionListenerも内部的にリフレッシュされた接続に透過的に移行され、リフレッシュされた接続で例外をリスニングします。
複数のConnection - 同じConnectionFactoryオブジェクトから作成された複数のJMS Connectionがある場合、再接続機能の点では、各接続は他の接続とは関係なく動作します。各接続には独自の接続ステータス、接続再試行機能などがあります。
「再接続されるConnectionオブジェクト」で説明したように、JMS Connectionに関連付けられているJMS Sessionオブジェクトはリフレッシュされます(例14-1および例14-2のステップ4を参照)。確認応答モード、トランザクション・モードなどのセッション・ステートは、リフレッシュが発生するたびに保持されます。リフレッシュ後もcreateMessageProducer()
などの呼出しに対して同じセッション・オブジェクトを使用できます。
以下では、Sessionが再接続されるときに発生する可能性のある特殊なケースについて説明します。
保留中のコミットまたはロールバックのあるトランザクション・セッション - 非トランザクションJMS Sessionと同様に、JMSトランザクション・セッションも自動的にリフレッシュされます。ただし、ネットワークの切断時にコミットまたはロールバックを保留しているSessionに送信または受信処理があった場合には、Sessionリフレッシュ後の最初のコミット呼出しはjavax.jms.TransactionRolledBackException
をスローして失敗します。JMS Sessionのトランザクションがネットワークのリフレッシュにまたがっている場合、そのトランザクションのコミットは(アプリケーション・コードから見て)リフレッシュの前にトランザクションの一部として実行された処理を保証できません。
Sessionリフレッシュ後のsend()
やreceive()
などの処理では例外はスローされません。例外がスローされるのはリフレッシュ後の最初のコミットだけです。ただし、ネットワークの切断時にJMS Sessionに保留中のトランザクション処理がなかった場合は、Sessionリフレッシュ後の最初のコミットでも例外はスローされません。Session.commit()
で例外がスローされると、クライアント・アプリケーション・コードでは再度同じ(暗黙的にリフレッシュされた)JMSオブジェクトを使用するトランザクションですべての処理を単純に再試行できます。リフレッシュ前の古くなった処理は、コミットも複製もされません。
保留中の未応答メッセージ - Sessionのリフレッシュ前にセッションに未応答メッセージがあった場合、リフレッシュ後の最初のWLSession.acknowledge()
呼出しでweblogic.jms.common.LostServerException
がスローされます。これは、acknowledge()
呼出しによってメッセージがサーバーからまだ削除されていない可能性があることを示します。その結果、リフレッシュされたSessionが切断前に配信されたメッセージを重複して受信するおそれがあります。
「再接続されるConnectionオブジェクト」で説明したように、JMS Connectionに関連付けられているJMS MessageProducerオブジェクトはリフレッシュされます(例14-1のステップ5を参照)。プロデューサが非匿名である場合、つまり、特定のDestinationオブジェクト(スタンドアロンの宛先または分散宛先)専用である場合は、そのプロデューサの宛先も暗黙的にリフレッシュされます(「再使用可能なDestinationオブジェクト」を参照)。プロデューサが匿名である場合(つまり、特定のDestinationオブジェクト専用でない場合)は、そのプロデューサのsend()
処理で指定されている古くなった可能性のあるDestinationオブジェクトが暗黙的にリフレッシュされます。
分散宛先メンバーが使用不能になるのと同時に、プロデューサがメッセージを送信する可能性もあります。WebLogic JMSでは、分散宛先メンバーが使用不能であることを検知したり、メッセージを送信したときに使用不能だったことが検出されると、システムが別の分散メンバーへのメッセージの送信を再試行します。ただし、分散メンバーが使用不能になる前にメッセージが届いたかどうかを確認できない場合は、メッセージが重複して作成されるおそれがあるため再送は行われません。この場合は例外がスローされます。その例外を捕捉してメッセージを再送するかどうかを決めるのはアプリケーションの役割です。
JMS Sessionを通じてJMS Connectionオブジェクトの一部になっているJMS MessageConsumerオブジェクトは、JMS接続のリフレッシュ中にリフレッシュできます(例14-2のステップ5を参照)。ただし、JMSコンシューマはステートフルで本質的に非同期なオブジェクトであるため、weblogic.jms.extension.WLConnection
APIまたは管理コンソールを使用してこの機能を明示的に有効にする必要があります。
コンシューマの自動リフレッシュを明示的に有効にすると、恒久サブスクライバのClientIDが構成されている接続もリフレッシュされます(「恒久サブスクリプションのClientIDが指定されたコンシューマ接続」を参照)。ただし、リフレッシュされたコンシューマにはQueueBrowserクライアントは含まれません。「自動再接続の制限事項」で説明するように、QueueBrowserクライアントはリフレッシュされることのないクライアントです。
メッセージ・コンシューマのリフレッシュを明示的に有効にした場合、ネットワーク障害が発生すると、メッセージ消費用のWebLogic JMSクライアント・コードによって再接続が試行されます(例14-2のステップ3 - 8を参照)。
例14-2 メッセージ消費用のJMSクライアント・コードのサンプル
0. Context ctx = create WebLogic JNDI context with credentials etc. 1. ConnectionFactory cf = ctx.lookup(JNDI name of connection factory) 2. Destination dest = ctx.lookup(JNDI name of destination) // the following operations recover from network failures 3. Connection con = cf.createConnection() (weblogic.jms.extensions.WLConnection)con).setReconnectPolicy("all") 4. Session sess = con.createSession(no transactions, auto ack) 5. MessageConsumer cons = sess.createConsumer(dest, message selector) - also for async consumers : cons.setMessageListener(onMessage impl) 6. con.start() 7. Loop over: for sync consumers: Message msg = consumer.receive() for async consumers (in different thread): onMessage() invoked 8. con.close(), ctx.close()
なお、デフォルトでは、接続ファクトリはMessageConsumerオブジェクトをリフレッシュしません。これがプログラム的にリフレッシュされるようにするには、setReconnectPolicy
を"all"
に設定したWebLogic WLConnection
拡張をクライアント・アプリケーション・コードから呼び出す必要があります(例14-2のステップ3を参照)。
JMSクライアント再接続APIには、以下の構成パラメータが含まれています。これらのパラメータを使用して、コンシューマの再接続機能の動作を制御できます。
表14-1 JMSクライアントの自動再接続オプション
フィールド名/MBean属性 | 値 | 説明 |
---|---|---|
再接続ポリシー ReconnectPolicy |
|
ネットワークの切断時やサーバーの再起動時に、どのJMSクライアント・オブジェクトを暗黙的にリフレッシュするかを指定します。この属性は、この接続ファクトリから派生したConnection、Session、Producer、およびConsumerの暗黙的なリフレッシュにのみ適用されます。この属性はJMSクライアント内のDestinationオブジェクトやConnectionFactoryオブジェクトは、常に暗黙的にリフレッシュされるため適用外です。また、JMSクライアント内のQueueBrowserも、リフレッシュされることのないオブジェクトであるため適用外です。 |
再接続ブロッキング時間 ReconnectBlockingTimeMillis |
6000 |
任意の同期JMS呼出し( |
TotalReconnectPeriodMillis |
-1 |
ネットワークの最初の中断、または同期JMS呼出しの最後の試行のいずれかが起きた後、JMSクライアントがサーバーへの再接続を再試行し続ける時間(再試行をあきらめるまでの時間)を指定します。 |
管理コンソールを使用して接続ファクトリのクライアント・パラメータを構成する手順については、Oracle WebLogic Server管理コンソール・ヘルプ』の接続ファクトリのクライアント・パラメータの構成に関する項を参照してください。これらのパラメータの詳細は、『Oracle WebLogic Server MBeanリファレンス』のClientParamsBean
に関する項を参照してください。
この節では、同期および非同期コンシューマをリフレッシュする一般的なケースについて説明します。
同期コンシューマは、MessageConsumer.receive()
、MessageConsumer.receive(timeout)
、およびMessageConsume.receiveNoWait()
メソッドを使用してメッセージを消費します。1番目と2番目のメソッドではアプリケーション・コードをブロックする可能性が想定されていますが、3番目のメソッドではアプリケーション・コードのブロックは想定されていません。これらのセマンティクスを維持するため、同期コンシューマ呼出しでの再接続機能の対話には以下のルールが適用されます。
MessageConsumer.receive()
- この呼出しの場合は、呼出しの間に切断されたネットワークがあると、再接続を試行するためにアプリケーション・コードがブロックされます。例外がスローされるまでの時間は、構成セクションにある「再接続ブロッキング時間」プロパティの値が最大値となります。
MessageConsumer.receive(timeout)
- この呼出しの場合は、呼出し側によって指定されたタイムアウトを最大値としてアプリケーション・コードがブロックされます。「再接続ブロッキング時間」プロパティがタイムアウトより短い場合は、再接続ブロッキング時間の設定がブロックの上限となり、「再接続ブロッキング時間」プロパティがタイムアウトより長い場合は、タイムアウトがブロックの上限となります。
MessageConsumer.receiveNoWait()
- この呼出しの場合は、JMS Connectionによる再接続処理中もアプリケーション・コードはブロックされません。「再接続ブロッキング時間」は、この呼出しには適用されません。
これらのメソッドがそれぞれのタイムアウト/待機時間に達すると、再接続されることなく同じ例外がスローされます。これらのメソッドのブロックまたは呼出しの間に再接続に成功した場合は、引続きメソッドからメッセージが返されます。ただし、回復後は、サービス品質が低下したり、似たようなセマンティクスでのメッセージ受信(たとえばメッセージの再配信)が発生したりする可能性があります。このような可能性は、Connection ExceptionListenerコールバックによるLostServerException
によってアプリケーションに通知されます。また、確認応答モードがAUTO_ACK
以外の場合は、リフレッシュ後の最初の確認応答呼出しによってスローされるLostServerException
でアプリケーションに通知されます。
再接続のコンテキストでは、非同期コンシューマの動作は「再接続の合計期間」プロパティの設定によって制御されます。接続失敗が起こった後「再接続の合計期間」プロパティに設定されている時間内に再接続が成功した場合は、JMS Consumerに登録されているメッセージ・リスナーのonMessage()
が引続き呼び出されます。ユーザーがJMS Connection (または、非同期のConsumerに対応するJMS Session)に対して明示的にclose()
を呼び出した場合は、そのConsumerに対するonMessages
はそれ以降呼び出されません。Connection ExceptionListenerのonException
がLostServerException
で呼び出された場合に備え、onMessage()
においてリカバリ後の動作(たとえばメッセージの再配信)を想定しておく必要があります。
以下の節では、コンシューマがリフレッシュされるときに発生する可能性のある特殊なケースについて説明します。
WebLogic Server 9.2より前のリリースでは、分散宛先のコンシューマは、その生存時間中は特定の宛先メンバーに固定されていました。これが当てはまるのは、分散キューのキュー・コンシューマと、分散トピックの非恒久サブスクライバです(恒久サブスクライバでは分散トピックはサポートされません)。
MessageConsumerの再接続時には、分散宛先コンシューマもリフレッシュされます。しかし、リフレッシュされたコンシューマが、古くなったコンシューマと同じ宛先を使用することはほとんどありません。つまり、アプリケーションではリフレッシュ前と同じ分散宛先コンシューマを使用していても、そのコンシューマがリフレッシュ前と同じ宛先メンバーに固定されているわけではありません。
メッセージドリブンEJB (MDB)は非同期コンシューマの一種で、独自の動作要件とリフレッシュ・フレームワークを備えています。そのため、MessageConsumerのリフレッシュに参加することは想定されておらず、他のどの方法によってもJMSクライアント再接続フレームワークの影響を受けることはありません。
スタンドアロン・トピックの恒久サブスクリプションは、切断後の再接続によってトピックが使用可能になれば、クライアント再接続機能で生じた違いに関係なく機能します。JMSクライアント再接続フレームワークでは、そのトピックの恒久サブスクライバが暗黙的にリフレッシュされ、中断された位置から継続されます。なお、「再接続ポリシー」が「すべて」
に設定されている場合は、ClientIDが指定されたJMS Connectionも自動的にリフレッシュされるため、ClientIDによってスコープが指定されている恒久サブスクリプションを自動的にリフレッシュすることは可能です。ClientIDが指定されたConnectionは、それ以外の「再接続ポリシー」設定では再接続されません。
注意: ネットワークまたはサーバーの障害が発生したときにJMS接続にClientIDが指定されている場合、そのクライアントの再接続にかかる時間は他のクライアントに比べてかなり長くなる場合があります。たとえば、クラスタ内のJMSサーバーは、クラスタの他のメンバーからブロードキャストされるWebLogic Serverの「ハートビート」通知を待機する必要があります。詳細は、『Oracle WebLogic Serverクラスタの使用』の「クラスタのフェイルオーバーとレプリケーション」を参照してください。WebLogic JMSでは、分散トピックでの恒久サブスクリプションはサポートされていません。したがって、リフレッシュ時の別の分散トピック・メンバーへのフェイルオーバーは問題にはなりません。 |
コンシューマがトピックの非恒久サブスクライバである場合、アプリケーションからはリフレッシュ後も問題なく消費が行われているように見えても、トピックにパブリッシュされたメッセージが、コンシューマの不足などが原因で再接続中に破棄されている可能性があります。このようなメッセージの破棄は、同期非恒久サブスクライバでも非同期恒久サブスクライバでも発生します。
コンシューマのリフレッシュ機能の性質上、クライアント・アプリケーション・コードから明示的にリカバリを呼び出さなくても、メッセージの再配信が発生する可能性があります。これは、コンシューマをリフレッシュすると、暗黙的にリカバリと同等の効果が生じるためです。これが、暗黙的なコンシューマのリフレッシュがデフォルトで有効になっていない主な理由です。なお、この場合でも、問題なく確認応答されたメッセージが再配信されることはありません。
また、これも稀なケースですが、分散トピックの非恒久サブスクライバが、再配信とマークされていない重複メッセージを受信することもあります(たとえば、トピック内でメッセージが破棄されるより前にフェイルオーバーが発生した場合)。これは、リフレッシュの前後で特定のトピック・メンバーに固定されていない分散トピックの非恒久サブスクライバをリフレッシュした結果として発生します。
確認応答モードの違いが原因で、コンシューマの再接続動作に差異が生じることはありません。ただし、すでに説明したように、AUTO_ACK
以外の確認応答モードでは、サービスの質が低下した可能性があることをアプリケーションに通知するため、リフレッシュ後の最初の確認応答呼出しでLostServerExceptionがスローされます。
JMSクライアントが自動的に再接続しないようにするには、プログラムまたは管理機能を使用して、この機能を明示的に無効にする必要があります。
プログラムを使用してJMSクライアントが自動的に再接続しないようにするには、アプリケーションから次のコードが呼び出されるようにします。
ConnectionFactory cf = (javax.jms.ConnectionFactory)ctx.lookup (JNDI name of connection factory) javax.jms.Connection con = cf.createConnection(); ((weblogic.jms.extensions.WLConnection)con).setReconnectPolicy("none")
詳細については、weblogic.jms.extension.WLConnection
APIのsetReconnectPolicy
メソッドを参照してください。
管理機能を使用してJMSクライアントが自動的に再接続しないようにするには、次の手順に従ってJMS接続ファクトリの「再接続ポリシー」を無効にします。
「JMS接続ファクトリ」→「構成」→「クライアント」ページに移動します。Oracle WebLogic Server管理コンソール・オンライン・ヘルプにある接続ファクトリのクライアント・パラメータの構成に関する項を参照してください。
選択した接続ファクトリでJMSクライアントの再接続機能を無効にするには、「再接続ポリシー」フィールドで「なし」を選択します。
「再接続ポリシー」フィールドの詳細は、Oracle WebLogic Server管理コンソール・オンライン・ヘルプのJMS接続ファクトリ: 構成: クライアントに関する項を参照してください。
「保存」をクリックします。
その他のJMS接続ファクトリ・クライアント・パラメータの詳細は、Oracle WebLogic Server MBeanリファレンスのClientParamsBean
に関する項を参照してください。
Oracleでは、JMSクライアントの自動再接続機能を使用する場合のベスト・プラクティスとして以下を推奨しています。
メッセージ処理結果が不明でWebLogic Serverが例外をスローするいくつかの接続障害シナリオがあります。使用するアプリケーションは例外を適切に処理する必要があります。次を参照してください。
関連する作業や依存関係にある作業(メッセージング作業を含む)は、トランザクション・セッション(JMS)またはユーザー・トランザクション(JTA)を使用してグループ化することをお薦めします。このようにすると、すべての作業が完了しているか、すべての作業が完了していないか、どちらかの状態になります。サーバー・インスタンスに障害が発生して転送中のメッセージが消失しても、トランザクション全体をロールバックすれば、障害後に各メッセージをどのように処理するかをアプリケーションで判断する必要はありません。
ヒント: サーバーの再接続後は、トランザクションのコミットの失敗に注意してください。トランザクション・サブシステムがトランザクションに関係するすべての参加者にアクセスできないと、トランザクションのコミットに失敗することがあります。 |
ベスト・プラクティスとして、アプリケーションではJVMガベージ・コレクションを使用してJMS接続をクリーンアップしないことをお薦めします。これは、JMS自動再接続機能ではJMS接続への参照が保持されるためです。したがって、常にconnection.close()
を使用して接続をクリーンアップします。また、接続リソースを確実にクリーンアップするため、Finally
ブロックを使用することも検討してください。このようにしない場合、接続を使用可能な状態に維持するためにシステム・リソースが割り当てられてしまいます。
JMSクライアント接続を閉じることに関する詳細については、「ベスト・プラクティス:問題が発生したJMS ClientIDは常に閉じる」を参照してください。
WebLogic Server 9.0以前のリリースで実行されるJMSクライアント・アプリケーションでは、サーバー障害の後にjavax.jmsオブジェクトを再確立する必要がありました。9.0以前のリリースのJMSクライアントを実行している場合は、サーバー障害の発生時に正常に終了するよう、JMSクライアントをプログラミングすることもできます。例:
表14-2 サーバー障害に関するプログラミングの考慮事項
WebLogic Serverインスタンスの障害発生時の状態 | 対応 |
---|---|
障害が発生したWebLogic Serverインスタンスに接続しています。 |
|
障害が発生したWebLogic ServerインスタンスがJMSサーバーのターゲットになっています。 |
|
WebLogic JMSでは、移行フレームワークを使用することによって、WebLogic JMSが移行リクエストに正しく応答できるようになり、WebLogic JMSサーバーのオンラインとオフラインの切替えが順序立って行われるようになります。これには、スケジューリングされた移行だけでなく、WebLogic Serverの障害への応答としての移行も含まれます。
いったん適切に構成すると、JMSサーバーとそのすべての宛先をクラスタ内の別のWebLogic Serverへ移行できます。
新しくサーバーを起動し、表14-0のタスクのうち1つ以上を実行することで、障害が発生したWebLogic ServerからJMSデータを手動でリカバリできます。
注意: クラッシュした、または管理サーバーからアクセスできないサーバー・インスタンスからサービスを移行する場合は、特別な考慮事項があります。移行を実行する時点で、以前アクティブだったサービスのホストに管理サーバーからアクセスできない場合は、『Oracle WebLogic Serverクラスタの使用』の「使用不能サーバーからのサービスの移行」を参照してください。 |
表14-3 移行タスク・ガイド
JMSアプリケーションが次を使用している場合... | 次のタスクを実行します... |
---|---|
永続的なメッセージング - JDBCストア |
|
永続的なメッセージング - ファイル・ストア |
ファイルを新しいサーバーに移行し、WebLogic Serverホーム・ディレクトリ内のファイルのパス名が元のサーバーにあったパス名と同じであることを確認します。 |
トランザクション |
クラッシュ後のリカバリを容易にするため、WebLogic Serverではトランザクション・リカバリ・サービスを提供しています。このサービスでは、システムの起動時にトランザクションのリカバリが自動的に行われます。トランザクション・リカバリ・サービスでは、サーバーのトランザクションのログが記録されます。 障害の発生したサーバーからトランザクションを回復する手順の詳細は、『Oracle WebLogic Server JTAのプログラミング』の「サーバーの障害後のトランザクションのリカバリ」を参照してください。 |
注意: JMS永続ストアに格納されているメッセージ数が増加するにつれて、WebLogic Serverの初期化に必要なメモリー量も増加します。WebLogic Serverの再起動中にメモリー不足で初期化が失敗した場合は、Java仮想マシン(JVM)のヒープ・サイズを、現在JMS永続ストアに格納されているメッセージ数に比例するよう増加させてから、再起動してください。 |
新しくWebLogic Serverを起動する方法の詳細は、「サーバーの起動と停止: クイック・リファレンス」を参照してください。障害が発生したサーバーのリカバリについては、『Oracle WebLogic Serverサーバーの起動と停止の管理』の「サーバー障害の回避とリカバリ」を参照してください。
移行可能サービスの定義の詳細は、『Oracle WebLogic Serverクラスタの使用』の「サービスの移行」を参照してください。