第 29 章 集群概述
JBoss EAP 消息传递群集允许将 JBoss EAP 消息传递服务器组分组在一起,以便共享消息处理负载。群集中的每个活动节点都是活跃的 JBoss EAP 消息传递服务器,用于管理自己的消息并处理自己的连接。
messaging-activemq 子系统不支持由不同版本的 JBoss EAP 组成的混合集群。构成消息传递群集的服务器必须全部使用相同的 JBoss EAP 版本。
群集由每个节点组成,每个节点声明到 JBoss EAP 配置文件中其他节点的群集连接。当节点组成到另一节点的集群连接时,它在内部创建其自身与其他节点之间的核心桥接连接。这在幕后透明执行,您不必为每个节点声明一个明确的桥接。这些集群连接允许集群节点之间流动的消息来平衡负载。
集群的一个重要部分是服务器发现,服务器可以广播其连接详细信息,以便客户端或其他服务器可以通过最小配置进行连接。
本节还讨论客户端侧负载平衡、平衡群集节点之间的客户端连接和 消息重新发布,其中 JBoss EAP 消息传递将在节点之间重新分发消息,以避免出现缺失。
配置了群集节点后,通常只需将该配置复制到其他节点,即可生成对称集群。
实际上,集群中的每个节点都必须共享以下元素的相同配置,以避免意外错误:
- cluster-connection
- broadcast-group
- discovery-group
- address-settings,包括队列和主题
但是,在复制 JBoss EAP 消息文件时必须小心。不要将消息传递数据、绑定、日志和大型消息目录从一个节点复制到另一个节点。当首次启动集群节点并初始化其日志文件时,它会持久保留日志目录的特殊标识符。节点之间的标识符必须是唯一的,集群才能正确组成。
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 命令实现:
添加
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)添加广播组。
/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 | 连续广播之间相隔的时间,以毫秒为单位。 |
| 连接器 | 要广播的连接器的名称。 |
| jgroups-channel |
|
| jgroups-cluster | 用于广播组与发现组之间通信的逻辑名称。希望从特定广播组接收消息的发现组必须使用与广播组相同的群集名称。 |
| jgroups-stack |
重要
如果同时指定了 |
| socket-binding | 广播组套接字绑定。 |
29.1.2. 发现组 复制链接链接已复制到粘贴板!
广播组定义如何从服务器广播连接器信息,但发现组定义如何从广播端点接收连接器信息,如 UDP 多播地址或 JGroup 通道。
发现组维护一个连接器列表,每个连接器由不同的服务器广播。当它从特定服务器在广播端点上接收广播时,它会更新该服务器的列表中的条目。如果在一段时间内没有从特定服务器收到广播,它将从列表中删除该服务器的条目。
发现组用于 JBoss EAP 消息传递的两个位置:
- 通过集群连接,它们知道如何获取初始连接来下载拓扑。
- 通过消息传递客户端,他们知道如何获取用于下载拓扑的初始连接。
尽管发现组将始终接受广播,但其当前可用的实时和备份服务器列表仅在进行初始连接时使用。从 起,服务器发现通过普通的 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 命令实现:
添加
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)添加发现组。
/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 | 以毫秒为单位等待初始广播为我们提供集群中的至少一个节点。 |
| jgroups-channel |
|
| jgroups-cluster | 用于广播组与发现组之间通信的逻辑名称。希望从特定广播组接收消息的发现组必须使用与广播组相同的群集名称。 |
| jgroups-stack |
重要
如果同时指定了 |
| refresh-timeout | 在从特定服务器接收最后一次广播后,发现组等待一次,然后从列表中删除该服务器的连接器对条目。 |
| socket-binding | 发现组套接字绑定。 |
上面描述的 JGroups 属性和 UDP 相关属性是相互排斥的。在发现组配置中只能指定一个设置。
29.1.2.2. 在客户端幻灯片上配置发现组 复制链接链接已复制到粘贴板!
您可以使用 JMS 或核心 API 配置 JBoss EAP 消息传递客户端,以发现其可以连接的服务器列表。
使用 JMS 配置客户端发现
使用 JMS 的客户端可以通过 JNDI 查找相关的 ConnectionFactory。connection-factory 或 的 pooled- connection-factoryentries 属性指定将在其中公开工厂的 JNDI 名称。以下是为远程客户端配置的 ConnectionFactory 配置为使用 JNDI 进行查找的示例:
<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-factory 在 java:jboss/exported 命名空间中绑定了条目,远程客户端将使用 java:jboss/exported 后面的文本来查找 connection-factory。例如,RemoteConnectionFactory 默认绑定到 java:jboss/exported/jms/RemoteConnectionFactory,这意味着远程客户端 将使用 事实。jms/RemoteConnectionFactory 来查找此连接pooled-connection-factory 应当不会在 java:jboss/exported 命名空间内绑定任何条目,因为 pooled-connection-factory 不适合于远程客户端。
自 JMS 2.0 起,默认的 JMS 连接工厂可供 Java EE 应用访问,其位于 JNDI 名称 java:comp/DefaultJMSConnectionFactory 下。JBoss EAP messaging-activemq 子系统定义一个 pooled-connection-factory,用于提供此默认连接工厂。任何 Java EE 应用将考虑此 pooled-connection-factory 的任何参数更改,查找 JNDI 名称 java:comp/DefaultJMSConnectionFactory 下的默认 JMS 提供程序。以下是 *-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();
您可以使用 DiscoveryGroupConfiguration 上的 setDiscoveryRefreshTimeout() setter 方法设置 refresh-timeout 值,默认值为 10000 毫秒。
您还可以在 DiscoveryGroupConfiguration 上使用 setDiscoveryInitialWaitTimeout() setter 方法设置 initial-wait-timeout 值,它决定了会话工厂在创建第一个会话前将等待的时长。默认值为 10000 毫秒。
29.1.3. 静态发现 复制链接链接已复制到粘贴板!
如果您不能或不想在网络上使用 UDP,您可以使用一个或多个服务器的初始列表配置连接。
这并不表示您必须知道要托管所有服务器的位置。您可以将这些服务器配置为连接到可靠的服务器,并通过该服务器传播其连接详细信息。
配置集群连接
对于这里的集群连接,您只需要确保以常规方式定义任何连接器。然后,集群连接配置会引用它们。
配置客户端连接
客户端也可以使用可能的服务器的静态列表。
使用 JMS 配置客户端发现
在 JMS 中使用静态发现的建议方法是通过多个连接器( 分别指向群集中的唯一节点)配置连接 事实,并让客户端使用 JNDI 查找 ConnectionFactory。以下是仅显示此类 连接因素的配置片段 :
<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 连接器,以此类推。有关在服务器配置中配置连接器的信息,请参阅 Connectors 和 Acceptors 部分。
使用核心 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();