37.2. フェイルオーバーモード

HornetQ は以下の 2 つの種類のクライアントフェイルオーバーを定義します。
  • 自動クライアントフェイルオーバー
  • アプリケーションレベルのクライアントフェイルオーバー
HornetQ は、同じサーバーに対する透過的な自動再接続を提供します (たとえば、一時的なネットワーク障害の場合)。これは、接続が同じサーバーに対して最実行される点を除いてフェイルオーバーと似ています。このトピックの詳細については、32章クライアントの再接続とセッションの再割り当て を参照してください。
フェイルオーバー中に、クライアントでコンシューマーが非永続的または一時的なキューにある場合、これらのキューはバックアップノードでのフェイルオーバー中に自動的に再作成されます。これは、バックアップノードが非永続キューを認識しないためです。

37.2.1. 自動クライアントフェイルオーバー

HornetQ クライアントは、ライブおよびバックアップサーバーの認識で設定できるため、クライアントで接続 (ライブサーバー接続) が失敗した場合に、クライアントがこれを検出し、バックアップサーバーに再接続します。次に、バックアップサーバーは、フェイルオーバーの実行前に各接続で存在したセッションとコンシューマーを自動的に再作成し、ユーザーは再接続ロジックを手動でコーディングする必要がなくなります。
15章使用済みの接続の検出 で説明されたように、HornetQ クライアントは、client-failure-check-period で指定された時間内にサーバーからパケットを受信しない場合に接続失敗を検出します。クライアントが適切な時間内にデータを受け取らない場合は、接続が失敗したと見なされ、フェイルオーバーが試行されます。
HornetQ クライアントは、ライブおよびバックアップサーバーのペアのリストを使用してさまざまな方法で設定できます。これらは、明示的に設定できます。これを行う最も一般的な方法は、クライアントがリストを自動的に検出するために server discovery を使用することです。サーバー検出の設定方法については、「サーバー検出」 を参照してください。また、「静的なクラスターサーバーリストの指定」 で説明されたように、クライアントはライブおよびバックアップサーバーのペアを明示的に指定できます。
自動クライアントフェイルオーバーを有効にするには、非ゼロ再接続試行を許可するようクライアントを設定する必要があります (32章クライアントの再接続とセッションの再割り当て を参照)。
場合によっては、ライブサーバーがクラッシュや接続の失敗ではなく正常にシャットダウンされた場合であっても、クライアントがバックアップサーバーにフェイルオーバーすることが適切であることがあります。これを設定するには、HornetQConnectionFactory (JMS を使用している場合)、 JBOSS_DIST/jboss-as/server/PROFILE/deploy/hornetq/hornetq-jms.xml ファイル (接続ファクトリーを定義する場合)、または ClientSessionFactoryImpl (プロパティーを直接設定してコアを使用する場合) でプロパティー FailoverOnServerShutdown を true に設定します。このプロパティーのデフォルト値は false です。つまり、デフォルトでは、ライブサーバーが正常にシャットダウンされた場合に、HornetQ クライアントはバックアップサーバーにフェイルオーバーされません。

注記

サーバーを正常にシャットダウンした場合はデフォルトでクライアントでのフェイルオーバーがトリガーされません。サーバーが正常にシャットダウンされたときにクライアントがフェイルオーバーするためには、FailoverOnServerShutdowntrue に設定します。
Ctrl+C (Linux ターミナルで) を使用すると、サーバーが正常にシャットダウンされ、このプロパティーが正常に設定されている限り、クライアントフェイルオーバーがトリガーされません。
デフォルトでは、フェイルオーバーは少なくとも 1 つの接続がライブサーバーに対して確立された後にのみ実行されます。このロジックを適用すると、クライアントがライブサーバーに対して最初の接続を確立するのに失敗した場合に、フェイルオーバーは実行されません。クライアントは、再接続試行プロパティーに基づいてライブサーバーへの接続を再試行し、この試行回数後に失敗します。
場合によっては、クライアントで、失敗したバックアップサーバーを自動的に試してライブサーバーに対する最初の接続を確立したいことがあります。この場合は、XML、ClientSessionFactoryImpl、または HornetQConnectionFactory でプロパティー FailoverOnInitialConnection、またはfailover-on-initial-connection を設定します。このパラメーターのデフォルト値は false です。

注記

HornetQ は、ライブサーバーとバックアップサーバー間で完全なサーバーステータスをレプリケートしません。新しいセッションがバックアップで自動的に作成された場合は、そのセッションですでに送信または承認されたメッセージが認識されません。また、フェイルオーバー時のすべての in-flight 送信または承認が失われることがあります。

37.2.1.1. フェイルオーバー中のブロッキングコールの処理

クライアントコードがサーバーに対するブロッキングコールにある場合は、応答が実行を続行するまで待機します。フェイルオーバーが実行された場合、新しいセッションは処理中のコールを認識しません。認識する場合、このコールは永久的にハングし、到着しない応答を待つことがあります。
これを回避するために、コールで javax.jms.JMSException (JMS を使用している場合) または HornetQException (エラーコード HornetQException.UNBLOCKED) をスローすることにより、HornetQ はフェイルオーバー時に処理中のすべてのブロッキングコールをブロック解除します。クライアントコードに応じて、この例外がキャッチされ、必要に応じて任意の操作を再試行されます。
ブロック解除されるメソッドが commit() または prepare() へのコールの場合、トランザクションは自動的にロールバックされ、HornetQ が javax.jms.TransactionRolledBackException (JMS を使用している場合) またはエラーコード HornetQException.TRANSACTION_ROLLED_BACK を持つ HornetQException (コア API を使用している場合) をスローします。

37.2.1.2. トランザクションのフェイルオーバーの処理

セッションがトランザクション対応であり、メッセージがすでに現在のトランザクションで送信または承認された場合、サーバーは、送信されたメッセージまたは承認がフェイルオーバー中に失われないことを保証できません。
結果的に、トランザクションはロールバック専用としてマークされ、以降のコミットで javax.jms.TransactionRolledBackException (JMS を使用している場合) またはエラーコードHornetQException.TRANSACTION_ROLLED_BACK を持つ HornetQException (コア API を使用している場合) がスローされます。
ユーザーは例外をキャッチし、必要に応じてクライアントサイドのローカルロールバックコードを実行できます。セッションを手動でロールバックする必要はありません (すでにロールバックされています)。ユーザーは同じセッションでトランザクション操作を再試行できます。
コミットコールが実行されるときにフェイルオーバーが行われる場合、応答が送り返されないため、以前に説明したように、ハングを回避するためにサーバーがコールをブロック解除します。この場合は、障害が発生する前にライブサーバーで実際にトランザクションコミットが処理されたかどうかをクライアントが判断することは簡単ではありません。
これに対処するために、クライアントはトランザクションで重複検出 (35章重複メッセージ検出) を有効にし、コールのブロック解除後にトランザクション操作を再試行できます。フェイルオーバー前にトランザクションが実際にライブサーバーで正常にコミットされた場合は、トランザクションが再試行されたときに、重複検出により、トランザクションで再送信されたすべての耐性メッセージが、複数回送信されることを防ぐためにサーバーで無視されます。

注記

ロールバック例外をキャッチし、ブロック解除されたコールを再試行およびキャッチし、重複検出を有効にすることにより、障害発生時にメッセージに対する 1 度だけの配信保証を提供し、メッセージの損失や重複がないことを 100% 保証できます。

37.2.1.3. 非トランザクションセッションでのフェイルオーバーの処理

セッションが非トランザクションである場合は、フェイルオーバーの実行時に、メッセージがまたは承認が失われることがあります。
非トランザクションセッションに対して1 度だけ配信保証を提供するには、「フェイルオーバー中のブロッキングコールの処理」 で説明されたように、重複検出を有効にし、ブロック解除例外をキャッチします。