第29章 クラスターの概要

JBoss EAP メッセージングクラスターを使用すると、メッセージ処理負荷を共有するために JBoss EAP メッセージングサーバーのグループをグループ化できます。クラスター内のアクティブな各ノードは、独自のメッセージを管理し、独自の接続を処理するアクティブな JBoss EAP メッセージングサーバーです。

警告

異なるバージョンの JBoss EAP で構成される混合クラスターは messaging-activemq サブシステムによってサポートされていません。メッセージングクラスターを形成するサーバーはすべて、同じバージョンの JBoss EAP を使用する必要があります。

クラスターは、JBoss EAP 設定ファイルの他のノードへクラスター接続を宣言する各ノードによって形成されます。ノードが別のノードへのクラスター接続を形成すると、内部的には、そのノードと他のノード間のコアブリッジ接続を作成します。これは、背後で透過的に実行されます。各ノードに明示的なブリッジを宣言する必要はありません。これらのクラスター接続により、クラスターのノード間でメッセージが流れ、負荷分散を行います。

クラスタリングの重要な部分が、クライアントまたは他のサーバーが最小設定で接続できるようにサーバーが接続の詳細をブロードキャストできるサーバー検出です。

このセクションでは、クラスターのノード間でクライアント接続のバランスを取るためのクライアント側のロードバランシング、JBoss EAP メッセージングが枯渇を回避するためにノード間でメッセージを再分配するメッセージ再分配についても説明します。

警告

クラスターノードを設定したら、その設定を他のノードに単純にコピーしてシンメトリッククラスターを生成することが一般的です。

実際、予期しないエラーを防ぐために、クラスターの各ノードは、次の要素に対して同じ設定を共有する必要があります。

  • cluster-connection
  • broadcast-group
  • discovery-group
  • address-settings (キューとトピックを含む)

ただし、JBoss EAP のメッセージングファイルをコピーする際は注意が必要です。メッセージングデータ、bindings、journal、large-messages のディレクトリーをノード間でコピーしないでください。クラスターノードが初めて起動され、そのジャーナルファイルを初期化するとき、特別な識別子がジャーナルディレクトリーに保持されます。識別子は、クラスターが適切に形成できるようにノード間で一意である必要があります。

29.1. サーバー検出

サーバー検出は、サーバーが以下の対象に接続詳細を伝播できるメカニズムです。

  • メッセージングクライアント

    メッセージングクライアントは、ある時点でクラスター内で稼働しているサーバーの具体的な情報を持たずにクラスターのサーバーに接続することができます。

  • 他のサーバー

    クラスター内のサーバーは、クラスター内の他のすべてのサーバーについて事前の情報を持たずに相互のクラスター接続を作成することができます。

この情報、またはクラスタートポロジーは、通常の JBoss EAP メッセージング接続をクライアントに送信、およびクラスター接続を介して他のサーバーに送信されます。ただし、最初の接続を確立する方法が必要です。これを行うには、UDP や JGroups などの動的な検出技術を使用するか、初期コネクターの静的リストを指定します。

29.1.1. ブロードキャストグループ

ブロードキャストグループは、サーバーがネットワーク経由でコネクターをブロードキャストする手段です。コネクターは、クライアントまたは他のサーバーがサーバーに接続できる方法を定義します。

ブロードキャストグループはコネクターのセットを取得し、ネットワーク上でブロードキャストします。クラスターを設定するブロードキャスト技術に応じて、UDP または JGroups を使用してコネクターのペア情報をブロードキャストします。

ブロードキャストグループは、サーバー設定の messaging-activemq サブシステム内に定義されます。JBoss EAP メッセージングサーバーごとに多くのブロードキャストグループが存在します。

UDP を使用したブロードキャストグループの設定

以下は、UDP ブロードキャストグループを定義するメッセージングサーバーの設定例です。この設定は、messaging-group ソケットバインディングに依存することに注意してください。

<subsystem xmlns="urn:jboss:domain:messaging-activemq:4.0">
  <server name="default">
    ...
    <broadcast-group name="my-broadcast-group" connectors="http-connector" socket-binding="messaging-group"/>
    ...
  </server>
</subsystem>
...
<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
  ...
  <socket-binding name="messaging-group" interface="private" port="5432" multicast-address="231.7.7.7" multicast-port="9876"/>
  ...
</socket-binding-group>

この設定は、以下の管理 CLI コマンドを使用して実現できます。

  1. messaging-group ソケットバインディングを追加します。

    /socket-binding-group=standard-sockets/socket-binding=messaging-group:add(interface=private,port=5432,multicast-address=231.7.7.7,multicast-port=9876)
  2. ブロードキャストグループを追加します。

    /subsystem=messaging-activemq/server=default/broadcast-group=my-broadcast-group:add(socket-binding=messaging-group,broadcast-period=2000,connectors=[http-connector])
JGroups を使用したブロードキャストグループの設定

以下は、デフォルトの JGroups ブロードキャストグループを使用するブロードキャストグループを定義するメッセージングサーバーの設定例で、UDP を使用します。JGroups を使用してブロードキャストできるようにするには、jgroups-channel を設定する必要があります。

<subsystem xmlns="urn:jboss:domain:messaging-activemq:4.0">
  <server name="default">
    ...
    <broadcast-group name="my-broadcast-group" connectors="http-connector" jgroups-cluster="activemq-cluster"/>
    ...
  </server>
</subsystem>

これは、以下の管理 CLI コマンドを使用して設定できます。

/subsystem=messaging-activemq/server=default/broadcast-group=my-broadcast-group:add(connectors=[http-connector],jgroups-cluster=activemq-cluster)
ブロードキャストグループの属性

以下の表は、ブロードキャストグループの設定可能な属性を示しています。

属性説明

broadcast-period

連続するブロードキャストの間隔 (ミリ秒単位)。

connectors

ブロードキャストされるコネクターの名前。

jgroups-channel

jgroups サブシステムに定義されているチャネルの名前。クラスターを形成するために jgroups-cluster 属性と組み合わせて使用されます。定義されていない場合は、default のチャネルが使用されます。jgroups-channel は、jgroups-cluster 属性によって識別される個別の論理グループ間のグループ通信を多重化することに注意してください。

jgroups-cluster

ブロードキャストグループと検出グループ間の通信に使用される論理名。特定のブロードキャストグループからのメッセージを受信しようとする検出グループは、ブロードキャストグループで使用されるものと同じクラスター名を使用する必要があります。

jgroups-stack

クラスターの形成に使用される jgroups サブシステムに定義されているスタックの名前。この属性は非推奨です。代わりに、jgroups-channel を使用してクラスターを形成します。各 jgroups-stack はすでに jgroups-channel に関連付けられているため、そのチャネルを使用するか、新しい jgroups-channel を作成して jgroups-stack に関連付けることができます。

重要

jgroups-stackjgroups-channel の両方を指定すると、新しい jgroups-channel が生成され、jgroups-stack および jgroups-channel と同じ名前空間に登録されます。そのため、jgroups-stackjgroup-channel の名前は一意である必要があります。

socket-binding

ブロードキャストグループソケットバインディング。

29.1.2. 検出グループ

ブロードキャストグループは、コネクター情報がサーバーからブロードキャストされる方法を定義し、検出グループは、UDP マルチキャストアドレスや JGroup チャネルなど、ブロードキャストエンドポイントからコネクター情報を受け取る方法を定義します。

検出グループは、個別のサーバー別にブロードキャストごとに 1 つずつ、コネクターのリストを維持します。特定のサーバーからブロードキャストエンドポイントでブロードキャストを受け取ると、そのサーバーのリスト内のエントリーが更新されます。特定のサーバーから一定時間ブロードキャストを受信していない場合は、そのサーバーのエントリーがリストから削除されます。

検出グループは JBoss EAP メッセージングの 2 つの場所で使用されます。

  • クラスター接続により、トポロジーをダウンロードするために初期接続を取得する方法を把握します。
  • メッセージングクライアントにより、トポロジーをダウンロードするために初期接続を取得する方法を把握します。

検出グループは常にブロードキャストを受け付けますが、現在の利用可能なライブおよびバックアップサーバーの一覧は、初期接続が確立された場合にのみ使用されます。その後、サーバー検出は通常の JBoss EAP メッセージング接続で行われます。

注記

各検出グループは、対応するブロードキャストグループと一致するブロードキャストエンドポイント (UDP または JGroups) で設定する必要があります。たとえば、ブロードキャストグループが UDP を使用して設定されている場合、検出グループも UDP を使用し、同じマルチキャストアドレスを使用する必要があります。

29.1.2.1. サーバー上の検出グループの設定

検出グループは、サーバー設定の messaging-activemq サブシステムで定義します。JBoss EAP メッセージングサーバーごとに多くの検出グループが存在します。

UDP を使用した検出グループの設定

以下は、UDP 検出グループを定義するメッセージングサーバーの設定例です。この設定は、messaging-group ソケットバインディングに依存することに注意してください。

<subsystem xmlns="urn:jboss:domain:messaging-activemq:4.0">
  <server name="default">
    ...
    <discovery-group name="my-discovery-group" refresh-timeout="10000" socket-binding="messaging-group"/>
    ...
  </server>
</subsystem>
...
<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
  ...
  <socket-binding name="messaging-group" interface="private" port="5432" multicast-address="231.7.7.7" multicast-port="9876"/>
  ...
</socket-binding-group>

この設定は、以下の管理 CLI コマンドを使用して実現できます。

  1. messaging-group ソケットバインディングを追加します。

    /socket-binding-group=standard-sockets/socket-binding=messaging-group:add(interface=private,port=5432,multicast-address=231.7.7.7,multicast-port=9876)
  2. 検出グループを追加します。

    /subsystem=messaging-activemq/server=default/discovery-group=my-discovery-group:add(socket-binding=messaging-group,refresh-timeout=10000)
JGroups を使用した検出グループの設定

以下は、JGroups 検出グループを定義するメッセージングサーバーの設定例です。

<subsystem xmlns="urn:jboss:domain:messaging-activemq:4.0">
  <server name="default">
    ...
    <discovery-group name="my-discovery-group" refresh-timeout="10000" jgroups-cluster="activemq-cluster"/>
    ...
  </server>
</subsystem>

これは、以下の管理 CLI コマンドを使用して設定できます。

/subsystem=messaging-activemq/server=default/discovery-group=my-discovery-group:add(refresh-timeout=10000,jgroups-cluster=activemq-cluster)
検出グループの属性

以下の表は、検出グループの設定可能な属性を示しています。

属性説明

initial-wait-timeout

最初のブロードキャストがクラスター内の少なくとも 1 つのノードを提供するまで待機する時間 (ミリ秒単位)。

jgroups-channel

jgroups サブシステムに定義されているチャネルの名前。クラスターを形成するために jgroups-cluster 属性と組み合わせて使用されます。定義されていない場合は、default のチャネルが使用されます。jgroups-channel は、jgroups-cluster 属性によって識別される個別の論理グループ間のグループ通信を多重化することに注意してください。

jgroups-cluster

ブロードキャストグループと検出グループ間の通信に使用される論理名。特定のブロードキャストグループからのメッセージを受信しようとする検出グループは、ブロードキャストグループで使用されるものと同じクラスター名を使用する必要があります。

jgroups-stack

クラスターの形成に使用される jgroups サブシステムに定義されているスタックの名前。この属性は非推奨です。代わりに、jgroups-channel を使用してクラスターを形成します。各 jgroups-stack はすでに jgroups-channel に関連付けられているため、そのチャネルを使用するか、新しい jgroups-channel を作成して jgroups-stack に関連付けることができます。

重要

jgroups-stackjgroups-channel の両方を指定すると、新しい jgroups-channel が生成され、jgroups-stack および jgroups-channel と同じ名前空間に登録されます。そのため、jgroups-stackjgroup-channel の名前は一意である必要があります。

refresh-timeout

特定のサーバーから最後のブロードキャストを受信した後、そのサーバーのコネクターペアエントリーをリストから削除するまで検出グループが待機する時間。

socket-binding

検出グループソケットバインディング。

警告

上記の JGroups 属性と UDP 固有属性は相互排他的です。検出グループ設定で指定できるのは、1 つのセットのみです。

29.1.2.2. クライアント側の検出グループの設定

JMS またはコア API を使用して JBoss EAP メッセージングクライアントを設定し、接続できるサーバーのリストを検出できます。

JMS を使用したクライアント検出の設定

JMS を使用するクライアントは、関連する ConnectionFactory を JNDI を使用して検索できます。connection-factory または pooled-connection-factoryentries 属性は、ファクトリーが公開される JNDI 名を指定します。以下は、JNDI を使用してルックアップするためにリモートクライアントに設定された ConnectionFactory の例です。

<subsystem xmlns="urn:jboss:domain:messaging-activemq:4.0">
  <server name="default">
    ...
    <connection-factory name="RemoteConnectionFactory" entries="java:jboss/exported/jms/RemoteConnectionFactory" connectors="http-connector"/>
    ...
  </server>
</subsystem>
注記

java:jboss/exported 名前空間にバインドされた JNDI 名のみがリモートクライアントに使用できることに注意してください。connection-factoryjava:jboss/exported 名前空間にバインドされたエントリーを持っている場合、リモートクライアントは java:jboss/exported の後のテキストを使用して connection-factory を検索します。たとえば、RemoteConnectionFactory はデフォルトで java:jboss/exported/jms/RemoteConnectionFactory にバインドされています。これは、リモートクライアントが jms/RemoteConnectionFactory を使用してこの connection-factory をルックアップすることを意味します。pooled-connection-factory はリモートクライアントに適していないため、pooled-connection-factory では java:jboss/exported 名前空間内にエントリーがバインドされないようにする必要があります。

JMS 2.0 以降、デフォルトの JMS 接続ファクトリーは、JNDI 名 java:comp/DefaultJMSConnectionFactory で Java EE アプリケーションを利用できます。JBoss EAP の messaging-activemq サブシステムでは、このデフォルトの接続ファクトリーを提供するために使用される pooled-connection-factory を定義します。この pooled-connection-factory のパラメーターの変更は、JNDI 名 java:comp/DefaultJMSConnectionFactory で、デフォルトの JMS プロバイダーを検索する Java EE アプリケーションによって考慮されます。以下は、*-full プロファイルおよび *-full-ha プロファイルに定義されているデフォルトのプールされた接続ファクトリーです。

<subsystem xmlns="urn:jboss:domain:messaging-activemq:4.0">
  <server name="default">
    ...
    <pooled-connection-factory name="activemq-ra" transaction="xa" entries="java:/JmsXA java:jboss/DefaultJMSConnectionFactory" connectors="in-vm"/>
    ...
  </server>
</subsystem>
コア API を使用したクライアント検出の設定

コア API を使用して ClientSessionFactory インスタンスを直接インスタンス化する場合、セッションファクトリーの作成時に検出グループパラメーターを直接指定できます。例を以下に示します。

final String groupAddress = "231.7.7.7";
final int groupPort = 9876;

ServerLocator factory =
  ActiveMQClient.createServerLocatorWithHA(new DiscoveryGroupConfiguration(
      groupAddress,
      groupPort,
      new UDPBroadcastGroupConfiguration(groupAddress, groupPort, null, -1)));
ClientSessionFactory factory = locator.createSessionFactory();
ClientSession session1 = factory.createSession();
ClientSession session2 = factory.createSession();

DiscoveryGroupConfigurationsetDiscoveryRefreshTimeout() セッターメソッドを使用して refresh-timeout 値を設定できます。デフォルトは 10000 ミリ秒です。

また、DiscoveryGroupConfigurationsetDiscoveryInitialWaitTimeout() セッターメソッドを使用して initial-wait-timeout 値を設定することもできます。これは、最初のセッションを作成する前にセッションファクトリーが待機する時間を決定します。デフォルト値は、10000 ミリ秒です。

29.1.3. 静的検出

ネットワークで UDP を使用できない、または使用しない場合は、1 つ以上のサーバーの初期リストで接続を設定できます。

これは、すべてのサーバーがホストされる場所を、認識しなければならないという意味ではありません。これらのサーバーが、信頼できるサーバーに接続するように設定すると、そのサーバーを使用して接続の詳細を伝播できます。

クラスター接続の設定

クラスター接続の場合、追加の設定は必要ありません。コネクターが通常の方法で定義されていることを確認するだけです。これらは、クラスター接続の設定によって参照されます。

クライアント接続の設定

使用可能なサーバーの静的リストは、クライアントからも使用できます。

JMS を使用したクライアント検出の設定

JMS で静的検出を使用するには、複数のコネクター (それぞれがクラスター内の一意のノードを指す) で connection-factory を設定し、JNDI を使用してクライアントで ConnectionFactory を検索する方法が推奨されます。以下は、このような connection-factory を示す設定のスニペットです。

<subsystem xmlns="urn:jboss:domain:messaging-activemq:4.0">
  <server name="default">
    ...
    <connection-factory name="MyConnectionFactory" entries="..." connectors="http-connector http-node1 http-node2"/>
    ...
  </server>
</subsystem>

上記の例では、http-connector はローカルサーバーを指す HTTP コネクター (<http-connector>)、http-node1 はサーバー node1 を指す HTTP コネクターというようになります。サーバー設定にコネクターを設定するには、「コネクターとアクセプター」セクションを参照してください。

コア API を使用したクライアント検出の設定

コア API を使用している場合は、クラスター内の各サーバーに一意の TransportConfiguration を作成し、以下のサンプルコードのように ServerLocator を作成するメソッドに渡します。

HashMap<String, Object> map = new HashMap<String, Object>();
map.put("host", "myhost");
map.put("port", "8080");

HashMap<String, Object> map2 = new HashMap<String, Object>();
map2.put("host", "myhost2");
map2.put("port", "8080");

TransportConfiguration server1 = new TransportConfiguration(NettyConnectorFactory.class.getName(), map);
TransportConfiguration server2 = new TransportConfiguration(NettyConnectorFactory.class.getName(), map2);

ServerLocator locator = ActiveMQClient.createServerLocatorWithHA(server1, server2);
ClientSessionFactory factory = locator.createSessionFactory();
ClientSession session = factory.createSession();