24.2. 使用 JGroups 进行群集通信
24.2.1. 关于 JGroups
JGroups 是用于可靠消息传递的工具包,可用于创建节点可以互相发送消息的群集。
jgroups
子系统提供对 JBoss EAP 中高可用性服务的组通信支持。它允许您配置指定的频道和协议堆栈,以及查看频道的运行时统计信息。当使用提供高可用性功能的配置(如受管域中的 ha 或 full-ha 配置文件)或 standalone-ha.xml 或 standalone-
配置文件时,可以使用 full-ha.
xmljgroups
子系统。
JBoss EAP 预配置了两个 JGroups 堆栈:
- udp
- 群集中的节点使用用户数据报协议(UDP)多播互相通信。这是默认的堆栈。
- tcp
- 群集中的节点使用传输控制协议(TCP)相互通信。
TCP 的开销更大,通常被视为比 UDP 慢,因为它处理错误检查、数据包排序和拥塞控制本身。JGroups 为 UDP 处理这些功能,而 TCP 则保证其自身。在不可靠或高拥塞网络上使用 JGroups 时,或者多播不可用时,TCP 是一种不错的选择。
您可以使用预配置的堆栈或自行定义以满足系统特定要求。有关可用协议及其属性的更多信息,请参见以下部分。
24.2.2. 将默认 JGroups 频道切换为使用 TCP
默认情况下,集群节点使用为 ee
JGroups 频道配置的 udp
协议堆栈进行通信。
<channels default="ee"> <channel name="ee" stack="udp"/> </channels> <stacks> <stack name="udp"> <transport type="UDP" socket-binding="jgroups-udp"/> <protocol type="PING"/> ... </stack> <stack name="tcp"> <transport type="TCP" socket-binding="jgroups-tcp"/> <protocol type="MPING" socket-binding="jgroups-mping"/> ... </stack> </stacks>
使用多播配置 TCP
某些网络仅允许使用 TCP。使用以下管理 CLI 命令,切换 ee
频道以使用预配置的 tcp
堆栈:
/subsystem=jgroups/channel=ee:write-attribute(name=stack,value=tcp)
此默认 tcp
堆栈使用 MPING
协议,它使用 IP 多播来发现初始群集成员资格。
在没有多播的情况下配置 TCP
当安全策略不首选或允许多播时,您可以将默认协议堆栈更改为使用 TCP。要在没有多播的情况下配置基于 TCP 的集群,请执行以下步骤:
运行以下命令,将
ee
频道切换为使用 JGroups 子系统中预先配置的tcp
堆栈:<channel name="ee" stack="tcp" cluster="ejb"/>
设置集群节点的名称:
在独立配置模式中,执行以下步骤之一:
运行以下命令:
<server xmlns="urn:jboss:domain:8.0" name="node_1">
-
在启动实例时,为系统属性
jboss.node.name
指定唯一名称。
在域模式中,集群服务器在 server 标签的
host-*.xml
文件中列出。默认配置指定以下服务器名称,您可以根据需要进行编辑。<servers> <server name="server-one" group="main-server-group"/> <server name="server-two" group="other-server-group"> <socket-bindings port-offset="150"/> </server> </servers>
选择以下协议之一来发现其他群集成员:
24.2.3. 配置 TCPPING
此流程创建一个新的 JGroups 堆栈,它使用 TCPPING
协议来定义静态集群成员资格列表。系统提供了基础脚本,该脚本可创建 tcpping
堆栈并将默认 频道
设置为使用此新堆栈。此脚本中的管理 CLI 命令必须为您的环境自定义,并将作为批处理处理。
将以下脚本复制到文本编辑器中,并将它保存到本地文件系统。
# Define the socket bindings /socket-binding-group=standard-sockets/remote-destination-outbound-socket-binding=jgroups-host-a:add(host=HOST_A,port=7600) /socket-binding-group=standard-sockets/remote-destination-outbound-socket-binding=jgroups-host-b:add(host=HOST_B,port=7600) batch # Add the tcpping stack /subsystem=jgroups/stack=tcpping:add /subsystem=jgroups/stack=tcpping/transport=TCP:add(socket-binding=jgroups-tcp) /subsystem=jgroups/stack=tcpping/protocol=TCPPING:add(socket-bindings=[jgroups-host-a,jgroups-host-b]) /subsystem=jgroups/stack=tcpping/protocol=MERGE3:add /subsystem=jgroups/stack=tcpping/protocol=FD_SOCK:add /subsystem=jgroups/stack=tcpping/protocol=FD_ALL:add /subsystem=jgroups/stack=tcpping/protocol=VERIFY_SUSPECT:add /subsystem=jgroups/stack=tcpping/protocol=pbcast.NAKACK2:add /subsystem=jgroups/stack=tcpping/protocol=UNICAST3:add /subsystem=jgroups/stack=tcpping/protocol=pbcast.STABLE:add /subsystem=jgroups/stack=tcpping/protocol=pbcast.GMS:add /subsystem=jgroups/stack=tcpping/protocol=MFC:add /subsystem=jgroups/stack=tcpping/protocol=FRAG3:add # Set tcpping as the stack for the ee channel /subsystem=jgroups/channel=ee:write-attribute(name=stack,value=tcpping) run-batch reload
请注意,定义的协议的顺序非常重要。您还可以通过传递
add-index 值到 add
命令,将协议插入到特定的索引中。索引基于零,因此以下管理 CLI 命令添加
UNICAST3
协议作为第七个协议:/subsystem=jgroups/stack=tcpping/protocol=UNICAST3:add(add-index=6)
为您的环境修改 脚本。
-
如果您在受管域中运行,则必须通过 /profile=
PROFILE_NAME在
。/subsystem=jgroups
命令之前指定要更新的配置集 根据您的环境调整以下属性:
-
套接字绑定:
以逗号分隔的主机和端口组合列表,这些组合被视为众所周知的,并可用于查找初始成员身份。有关定义 套接字绑定的更多信息,请参阅配置 套接字绑定。 -
initial_hosts
:以逗号分隔的主机和端口组合列表,使用语法HOST[PORT ],
这些 [ PORT ] 被视为广为人知且可用于查找初始成员资格,如host1[1000],host2[2000]
。 -
port_range
:此属性用于将initial_hosts
端口范围扩展为指定的值。例如,如果您将initial_hosts
设置为host1[1000],host2[2000]
,并且port_range
设为1
,则initial_hosts
设置将扩展到host1[1000],host1[1001],host2[2000],host2[2001]
。此属性仅适用于initial_hosts
属性。
-
-
如果您在受管域中运行,则必须通过 /profile=
通过将 脚本文件传递到管理 CLI 来运行 脚本。
$ EAP_HOME/bin/jboss-cli.sh --connect --file=/path/to/SCRIPT_NAME
TCPPING 堆栈现已可用,TCP 用于网络通信。
24.2.3.1. 在独立模式中配置 TCPPING
此流程可帮助您在独立模式下为集群应用程序配置 TCP 堆栈和节点。
流程
在 JGroups 子系统中将默认堆栈从
udp
改为tcp
:<channel name="ee" stack="tcp" cluster="ejb"/>
将 TCP 堆栈配置为使用 TCPPING 协议代替默认的 MPING 协议。在以下代码中,
initial_hosts
属性与群集内所有节点的列表相关联,而7600
表示默认的jgroups-tcp
端口可以根据您的配置和环境而变化。<stack name="tcp"> <transport type="TCP" socket-binding="jgroups-tcp"/> <protocol type="TCPPING"> <property name="initial_hosts">192.168.1.5[7600],192.168.1.9[7600]</property> <property name="port_range">0</property> </protocol> <protocol type="MERGE3"/> <protocol type="FD_SOCK" socket-binding="jgroups-tcp-fd"/> <protocol type="FD_ALL"/> <protocol type="VERIFY_SUSPECT"/> <protocol type="pbcast.NAKACK2"/> <protocol type="UNICAST3"/> <protocol type="pbcast.STABLE"/> <protocol type="pbcast.GMS"/> <protocol type="MFC"/> <protocol type="FRAG3"/> </stack>
注意initial_hosts
中设置的端口号7600
必须与jgroups-tcp
套接字绑定定义中定义的端口号相同。如果将 port-offset 功能用于 socket-binding,则需要在initial_hosts
中指定偏移后相同的值。设置专用接口的 IP 地址,供 JGroups 组件使用。IP 地址应与
initial_hosts
中指定的 IP 地址之一相关联:<interface name="private"> <inet-address value="${jboss.bind.address.private:192.168.1.5}"/> </interface>
- 重复上述步骤来配置集群中的其他节点。配置节点时,启动每个节点并部署集群应用。
验证
您可以检查日志以验证节点是否已启动并在运行:
INFO [org.infinispan.remoting.transport.jgroups.JGroupsTransport] (thread-2,ee,node_1) ISPN000094: Received new cluster view for channel server: [node_1|1] (2) [node_1, node_2] INFO [org.infinispan.remoting.transport.jgroups.JGroupsTransport] (thread-2,ee,node_1) ISPN000094: Received new cluster view for channel web: [node_1|1] (2) [node_1, node_2]
24.2.3.2. 在域模式中配置 TCPPING
此流程可帮助您在域模式中为集群应用程序配置 TCP 堆栈和节点。
流程
如果同一配置集用于多个集群,请将系统属性值设置为
initial_hosts
:<protocol type="TCPPING"> <property name="initial_hosts">${jboss.cluster.tcp.initial_hosts}</property> Set the system property at the `server-group` level: <server-groups> <server-group name="a-server-group" profile="ha"> <socket-binding-group ref="ha-sockets"/> <system-properties> <property name="jboss.cluster.tcp.initial_hosts" value="192.168.1.5[7600],192.168.1.9[7600]" /> </system-properties>
在主机控制器的 XML 配置中设置专用接口的 IP 地址。专用接口的 IP 地址应当与
initial_hosts
中列出的 IP 地址之一相关联。<interfaces> .... <interface name="private"> <inet-address value="${jboss.bind.address.private:192.168.1.5}"/> </interface> </interfaces>
验证
您可以检查日志以验证节点是否已启动并在运行:
INFO [org.infinispan.remoting.transport.jgroups.JGroupsTransport] (thread-2,ee,node_1) ISPN000094: Received new cluster view for channel server: [node_1|1] (2) [node_1, node_2] INFO [org.infinispan.remoting.transport.jgroups.JGroupsTransport] (thread-2,ee,node_1) ISPN000094: Received new cluster view for channel web: [node_1|1] (2) [node_1, node_2]
24.2.4. 配置 TCPGOSSIP
此流程创建一个新的 JGroups 堆栈,它使用 TCPGOSSIP
协议来使用外部 Gosip 路由器发现群集的成员。我们提供了一个基础脚本,该脚本可创建 tcpgosip
堆栈,并将 default ee
通道设置为使用此新堆栈。此脚本中的管理 CLI 命令必须为您的环境自定义,并将作为批处理处理。
将以下脚本复制到文本编辑器中,并将它保存到本地文件系统。
# Define the socket bindings /socket-binding-group=standard-sockets/remote-destination-outbound-socket-binding=jgroups-host-a:add(host=HOST_A,port=13001) batch # Add the tcpgossip stack /subsystem=jgroups/stack=tcpgossip:add /subsystem=jgroups/stack=tcpgossip/transport=TCP:add(socket-binding=jgroups-tcp) /subsystem=jgroups/stack=tcpgossip/protocol=TCPGOSSIP:add(socket-bindings=[jgroups-host-a]) /subsystem=jgroups/stack=tcpgossip/protocol=MERGE3:add /subsystem=jgroups/stack=tcpgossip/protocol=FD_SOCK:add /subsystem=jgroups/stack=tcpgossip/protocol=FD_ALL:add /subsystem=jgroups/stack=tcpgossip/protocol=VERIFY_SUSPECT:add /subsystem=jgroups/stack=tcpgossip/protocol=pbcast.NAKACK2:add /subsystem=jgroups/stack=tcpgossip/protocol=UNICAST3:add /subsystem=jgroups/stack=tcpgossip/protocol=pbcast.STABLE:add /subsystem=jgroups/stack=tcpgossip/protocol=pbcast.GMS:add /subsystem=jgroups/stack=tcpgossip/protocol=MFC:add /subsystem=jgroups/stack=tcpgossip/protocol=FRAG3:add # Set tcpgossip as the stack for the ee channel /subsystem=jgroups/channel=ee:write-attribute(name=stack,value=tcpgossip) run-batch reload
请注意,定义的协议的顺序非常重要。您还可以通过传递
add-index 值到 add
命令,将协议插入到特定的索引中。索引基于零,因此以下管理 CLI 命令添加
UNICAST3
协议作为第七个协议:/subsystem=jgroups/stack=tcpgossip/protocol=UNICAST3:add(add-index=6)
为您的环境修改 脚本。
-
如果您在受管域中运行,则必须通过 /profile=
PROFILE_NAME在
。/subsystem=jgroups
命令之前指定要更新的配置集 根据您的环境调整以下属性:
-
套接字绑定:
以逗号分隔的主机和端口组合列表,这些组合被视为众所周知的,并可用于查找初始成员身份。有关定义 套接字绑定的更多信息,请参阅配置 套接字绑定。 -
initial_hosts
:以逗号分隔的主机和端口组合列表,使用语法HOST[PORT ],
这些 [ PORT ] 被视为广为人知且可用于查找初始成员资格,如host1[1000],host2[2000]
。 -
port_range
:此属性用于将initial_hosts
端口范围扩展为指定的值。例如,如果您将initial_hosts
设置为host1[1000],host2[2000]
,并且port_range
设为1
,则initial_hosts
设置将扩展到host1[1000],host1[1001],host2[2000],host2[2001]
。此属性仅适用于initial_hosts
属性。 -
reconnect_interval
:断开连接的 stub 尝试重新连接到 gossip 路由器的间隔(以毫秒为单位)。 -
sock_conn_timeout
:套接字创建的最大时间。默认值为1000
毫秒。 -
sock_read_timeout
:阻止读取的最大时间(以毫秒为单位)。值0
将无限期阻止。
-
-
如果您在受管域中运行,则必须通过 /profile=
通过将 脚本文件传递到管理 CLI 来运行 脚本。
$ EAP_HOME/bin/jboss-cli.sh --connect --file=/path/to/SCRIPT_NAME
TCPGOSSIP 堆栈现已可用,TCP 用于网络通信。此堆栈配置为与 gossip 路由器搭配使用,以便 JGroups 群集成员能够查找其他群集成员。
24.2.5. Configure JDBC_PING
您可以使用 JDBC_PING
协议管理和发现群集中的成员资格。
JDBC_PING 使用数据源中指定的数据库来列出群集的成员。
- 创建一个数据源,以连接到您要用于管理集群成员资格的数据库。
将以下脚本复制到文本编辑器中,并将它保存到本地文件系统。
batch # Add the JDBC_PING stack /subsystem=jgroups/stack=JDBC_PING:add /subsystem=jgroups/stack=JDBC_PING/transport=TCP:add(socket-binding=jgroups-tcp) /subsystem=jgroups/stack=JDBC_PING/protocol=JDBC_PING:add(data-source=ExampleDS) /subsystem=jgroups/stack=JDBC_PING/protocol=MERGE3:add /subsystem=jgroups/stack=JDBC_PING/protocol=FD_SOCK:add /subsystem=jgroups/stack=JDBC_PING/protocol=FD_ALL:add /subsystem=jgroups/stack=JDBC_PING/protocol=VERIFY_SUSPECT:add /subsystem=jgroups/stack=JDBC_PING/protocol=pbcast.NAKACK2:add /subsystem=jgroups/stack=JDBC_PING/protocol=UNICAST3:add /subsystem=jgroups/stack=JDBC_PING/protocol=pbcast.STABLE:add /subsystem=jgroups/stack=JDBC_PING/protocol=pbcast.GMS:add /subsystem=jgroups/stack=JDBC_PING/protocol=MFC:add /subsystem=jgroups/stack=JDBC_PING/protocol=FRAG3:add # Set JDBC_PING as the stack for the ee channel /subsystem=jgroups/channel=ee:write-attribute(name=stack,value=JDBC_PING) run-batch reload
请注意,定义的协议的顺序非常重要。您还可以通过传递
add-index 值到 add
命令,将协议插入到特定的索引中。索引基于零,因此以下管理 CLI 命令添加
UNICAST3
协议作为第七个协议:/subsystem=jgroups/stack=JDBC_PING/protocol=UNICAST3:add(add-index=6)
为您的环境修改 脚本。
-
如果您在受管域中运行,则必须通过 /profile=
PROFILE_NAME在
。/subsystem=jgroups
命令之前指定要更新的配置集 - 将 'ExampleDS' 替换为在第 1 步中定义的数据源的名称。
-
如果您在受管域中运行,则必须通过 /profile=
通过将 脚本文件传递到管理 CLI 来运行 脚本。
$ EAP_HOME/bin/jboss-cli.sh --connect --file=/path/to/SCRIPT_NAME
JDBC_PING 堆栈现已可用,TCP 用于网络通信。
相关信息
jdbc_PING: https://developer.jboss.org/wiki/JDBCPING
创建数据源:关于 JBoss EAP 数据源 ???
24.2.6. 将 JGroups 绑定到网络接口
默认情况下,JGroups 仅绑定到 专用
网络接口,后者指向默认配置中的 localhost。出于安全考虑,JGroups 不会绑定到 JBoss EAP 启动期间由 -b
参数定义的网络接口,因为集群流量不应在公共网络接口上公开。
有关如何 配置网络接口的详情, 请查看本指南中的网络配置章节。
出于安全考虑,JGroups 仅应绑定到非公共网络接口。出于性能原因,我们还建议 JGroups 流量的网络接口应该是专用虚拟局域网(VLAN)的一部分。
24.2.7. 保护集群
要安全运行集群,需要解决几个问题:
24.2.7.1. 配置身份验证
JGroups 身份验证由 AUTH
协议执行。目的是确保只有经过身份验证的节点才能加入群集。
在适用的服务器配置文件中,使用适当的属性设置添加 AUTH
协议。AUTH
协议应该在 pbcast.GMS
协议之前配置。
以下示例演示了如何将 AUTH
与不同类型的授权令牌搭配使用。
带有简单令牌的AUTH
...
<protocol type="pbcast.STABLE"/>
<auth-protocol type="AUTH">
<plain-token>
<shared-secret-reference clear-text="my_password"/>
</plain-token>
</auth-protocol>
<protocol type="pbcast.GMS"/>
...
带有 Digest Algorithm 令牌的 AUTH
此格式可与任何摘要算法一起使用,如 MD5 或 SHA-2。JBoss EAP 7.4 的默认摘要算法是 SHA-256,JVM 支持最强大的摘要算法。很多 JVM 还将实施 SHA-512。
...
<protocol type="pbcast.STABLE"/>
<auth-protocol type="AUTH">
<digest-token algorithm="SHA-512">
<shared-secret-reference clear-text="my_password"/>
</digest-token>
</auth-protocol>
<protocol type="pbcast.GMS"/>
...
带有 X509 令牌的 AUTH
本例在 elytron
子系统中创建新的密钥存储,并在 JGroups AUTH
配置中引用它。
创建密钥存储:
$ keytool -genkeypair -alias jgroups_key -keypass my_password -storepass my_password -storetype jks -keystore jgroups.keystore -keyalg RSA
使用管理 CLI 将密钥存储添加到
elytron
子系统:/subsystem=elytron/key-store=jgroups-token-store:add(type=jks,path=/path/to/jgroups.keystore,credential-reference={clear-text=my_password}, required=true)
在 JGroups 堆栈定义中,将
AUTH
配置为使用密钥存储:... <protocol type="pbcast.STABLE"/> <auth-protocol type="AUTH"> <cipher-token algorithm="RSA" key-alias="jgroups_key" key-store="jgroups-token-store"> <shared-secret-reference clear-text="my_password"/> <key-credential-reference clear-text="my_password"/> </cipher-token> </auth-protocol> <protocol type="pbcast.GMS"/> ...
24.2.7.2. 配置加密
为加密消息,JGroups 使用由群集成员共享的机密密钥。发送方使用共享机密密钥加密消息,接收方使用相同的机密密钥解密消息。通过使用 SYM_ENCRYPT
协议配置的 对称加密,节点使用共享密钥存储来检索密钥。使用 ASYM_ENCRYPT
协议配置的非 对称加密 时,节点在使用 AUTH
进行身份验证后,从集群的协调人员检索机密密钥。
使用对称加密
要使用 SYM_ENCRYPT
,您必须设置一个密钥存储,该存储将在每个节点的 JGroups 配置中引用。
创建密钥存储.
在以下命令中,将
VERSION
替换为适当的 JGroups JAR 版本,并将PASSWORD
替换为密钥存储密码。$ java -cp EAP_HOME/modules/system/layers/base/org/jgroups/main/jgroups-VERSION.jar org.jgroups.demos.KeyStoreGenerator --alg AES --size 128 --storeName defaultStore.keystore --storepass PASSWORD --alias mykey
这将生成一个
defaultStore.keystore
文件,该文件将在 JGroups 配置中引用。生成密钥存储后,将使用以下两种方法之一在
SYM_PROTOCOL
中定义它。- 在配置中直接 指定密钥存储。
- 使用 Elytron 子系统 引用密钥存储。
使用 SYM_ENCRYPT
时配置 AUTH
是可选的。
通过直接引用密钥存储使用对称加密
在
jgroups
子系统中配置SYM_ENCRYPT
协议。在适用的服务器配置文件中,使用适当的属性设置添加
SYM_ENCRYPT
协议。此协议将引用之前创建的密钥存储。SYM_ENCRYPT
协议应该在pbcast.NAKACK2
协议之前立即配置。<subsystem xmlns="urn:jboss:domain:jgroups:6.0"> <stacks> <stack name="udp"> <transport type="UDP" socket-binding="jgroups-udp"/> <protocol type="PING"/> <protocol type="MERGE3"/> <protocol type="FD_SOCK"/> <protocol type="FD_ALL"/> <protocol type="VERIFY_SUSPECT"/> <protocol type="SYM_ENCRYPT"> <property name="provider">SunJCE</property> <property name="sym_algorithm">AES</property> <property name="encrypt_entire_message">true</property> <property name="keystore_name">/path/to/defaultStore.keystore</property> <property name="store_password">PASSWORD</property> <property name="alias">mykey</property> </protocol> <protocol type="pbcast.NAKACK2"/> <protocol type="UNICAST3"/> <protocol type="pbcast.STABLE"/> <protocol type="pbcast.GMS"/> <protocol type="UFC"/> <protocol type="MFC"/> <protocol type="FRAG3"/> </stack> </stacks> </subsystem>
通过 Elytron 使用对称加密
利用管理 CLI,在
elytron
子系统中创建密钥存储,该子系统引用 使用对称加密 在 中创建的defaultStore.keystore
。/subsystem=elytron/key-store=jgroups-keystore:add(path=/path/to/defaultStore.keystore,credential-reference={clear-text=PASSWORD},type=JCEKS)
使用适当的属性设置,在
jgroups
子系统中添加SYM_ENCRYPT
协议。SYM_ENCRYPT
协议应该在pbcast.NAKACK2
协议之前配置,如以下配置所示。<subsystem xmlns="urn:jboss:domain:jgroups:6.0"> <stacks> <stack name="udp"> <transport type="UDP" socket-binding="jgroups-udp"/> <protocol type="PING"/> <protocol type="MERGE3"/> <protocol type="FD_SOCK"/> <protocol type="FD_ALL"/> <protocol type="VERIFY_SUSPECT"/> <encrypt-protocol type="SYM_ENCRYPT" key-alias="mykey" key-store="jgroups-keystore"> <key-credential-reference clear-text="PASSWORD"/> <property name="provider">SunJCE</property> <property name="encrypt_entire_message">true</property> </encrypt-protocol> <protocol type="pbcast.NAKACK2"/> <protocol type="UNICAST3"/> <protocol type="pbcast.STABLE"/> <protocol type="pbcast.GMS"/> <protocol type="UFC"/> <protocol type="MFC"/> <protocol type="FRAG3"/> </stack> </stacks> </subsystem>
注意上例使用明文密码;但是,也可以定义凭据存储来定义配置文件外的密码。有关配置此存储的更多信息,请参阅 如何配置服务器安全 指南中 的凭证存储 部分。
使用对称加密
要使用 ASYM_ENCRYPT
,必须定义 AUTH
协议。有关在 jgroups
子系统中配置 AUTH
协议的说明,请参阅配置 身份验证 部分。
ASYM_ENCRYPT
使用以下两种方法之一进行配置:
- 生成机密密钥并在 配置中直接 引用该密钥。
- 创建密钥存储 并使用 Elytron 子系统 引用它。
通过生成 secret 密钥使用对称加密
在
jgroups
子系统中配置ASYM_ENCRYPT
协议。在适用的服务器配置文件中,使用适当的属性设置添加
ASYM_ENCRYPT
协议。ASYM_ENCRYPT
协议应该在pbcast.NAKACK2
协议之前配置,如以下配置所示。<subsystem xmlns="urn:jboss:domain:jgroups:6.0"> <stacks> <stack name="udp"> <transport type="UDP" socket-binding="jgroups-udp"/> <protocol type="PING"/> <protocol type="MERGE3"/> <protocol type="FD_SOCK"/> <protocol type="FD_ALL"/> <protocol type="VERIFY_SUSPECT"/> <protocol type="ASYM_ENCRYPT"> <property name="encrypt_entire_message">true</property> <property name="sym_keylength">128</property> <property name="sym_algorithm">AES/ECB/PKCS5Padding</property> <property name="asym_keylength">512</property> <property name="asym_algorithm">RSA</property> </protocol> <protocol type="pbcast.NAKACK2"/> <protocol type="UNICAST3"/> <protocol type="pbcast.STABLE"/> <!-- Configure AUTH protocol here --> <protocol type="pbcast.GMS"/> <protocol type="UFC"/> <protocol type="MFC"/> <protocol type="FRAG3"/> </stack> </stacks> </subsystem>
通过 Elytron 使用非对称加密
创建密钥存储以包含密钥对。以下命令使用
mykey
条目创建一个密钥存储:$ keytool -genkeypair -alias mykey -keyalg RSA -keysize 1024 -keystore defaultKeystore.keystore -dname "CN=localhost" -keypass secret -storepass secret
使用管理 CLI,在
elytron
子系统中创建密钥存储,以引用defaultStore.keystore
。/subsystem=elytron/key-store=jgroups-keystore:add(path=/path/to/defaultStore.keystore,credential-reference={clear-text=PASSWORD},type=JCEKS)
使用适当的属性设置,在
jgroups
子系统中添加ASYM_ENCRYPT
协议。ASYM_ENCRYPT
协议应该在pbcast.NAKACK2
协议之前配置,如以下配置所示。<subsystem xmlns="urn:jboss:domain:jgroups:6.0"> <stacks> <stack name="udp"> <transport type="UDP" socket-binding="jgroups-udp"/> <protocol type="PING"/> <protocol type="MERGE3"/> <protocol type="FD_SOCK"/> <protocol type="FD_ALL"/> <protocol type="VERIFY_SUSPECT"/> <encrypt-protocol type="ASYM_ENCRYPT" key-alias="mykey" key-store="jgroups-keystore"> <key-credential-reference clear-text="secret" /> <property name="encrypt_entire_message">true</property> </encrypt-protocol> <protocol type="pbcast.NAKACK2"/> <protocol type="UNICAST3"/> <protocol type="pbcast.STABLE"/> <!-- Configure AUTH protocol here --> <protocol type="pbcast.GMS"/> <protocol type="UFC"/> <protocol type="MFC"/> <protocol type="FRAG3"/> </stack> </stacks> </subsystem>
注意上例使用明文密码;但是,也可以定义凭据存储来定义配置文件外的密码。有关配置此存储的更多信息,请参阅 如何配置服务器安全 指南中 的凭证存储 部分。
24.2.8. 配置 JGroups 线程池
jgroups
子系统包含 default
、internal、
oob
和 timer
线程池。可以为任何 JGroups 堆栈配置这些池,并且不影响本地节点上配置的 bean 或其他池。JGroup 线程池用于支持集群通信。
下表列出了您可以为每个线程池配置的属性以及每个线程的默认值。
线程池名称 | 描述 | keepalive-time | max-threads | Min-threads | queue-length |
---|---|---|---|---|---|
default | 此池用于处理没有标记为带外的传入信息。 | 60000L | 300 | 20 | 100 |
internal | 此池用于处理 EAP 维护所需的内部进程。 | 60000L | 4 | 2 | 100 |
oob | 此池用于处理传入的带外信息。 | 60000L | 300 | 20 | 0 |
计时器 | 此池用于处理时间绑定调度程序消息。 | 5000L | 4 | 2 | 500 |
利用下列语法,通过管理 CLI 配置 JGroups 线程池:
/subsystem=jgroups/stack=STACK_TYPE/transport=TRANSPORT_TYPE/thread-pool=THREAD_POOL_NAME:write-attribute(name=ATTRIBUTE_NAME, value=ATTRIBUTE_VALUE)
以下是管理 CLI 命令的示例,可将 the udp
堆栈 的默认
线程池中的 max-threads
值设置为 500
:
/subsystem=jgroups/stack=udp/transport=UDP/thread-pool=default:write-attribute(name="max-threads", value="500")
24.2.9. 配置 JGroups 发送和接收缓冲区
解决缓冲区大小警告
默认情况下,JGroups 配置有特定的发送和接收缓冲区值;但是,您的操作系统可能会限制可用的缓冲区大小,JBoss EAP 可能无法使用其配置的缓冲区值。在这种情况下,您将在 JBoss EAP 日志中看到类似如下的警告:
WARNING [org.jgroups.protocols.UDP] (ServerService Thread Pool -- 68) JGRP000015: the send buffer of socket DatagramSocket was set to 640KB, but the OS only allocated 212.99KB. This might lead to performance problems. Please set your max send buffer in the OS correctly (e.g. net.core.wmem_max on Linux) WARNING [org.jgroups.protocols.UDP] (ServerService Thread Pool -- 68) JGRP000015: the receive buffer of socket DatagramSocket was set to 20MB, but the OS only allocated 212.99KB. This might lead to performance problems. Please set your max receive buffer in the OS correctly (e.g. net.core.rmem_max on Linux)
要解决这个问题,请查阅您的操作系统文档来了解如何增加缓冲区大小。对于 Red Hat Enterprise Linux 系统,以 root 用户身份编辑 /etc/sysctl.conf
,为在系统重启后保留的缓冲区大小配置最大值。例如:
# Allow a 25MB UDP receive buffer for JGroups net.core.rmem_max = 26214400 # Allow a 1MB UDP send buffer for JGroups net.core.wmem_max = 1048576
修改 /etc/sysctl.conf
后,运行 sysctl -p
以使更改生效。
配置 JGroups 缓冲器大小
您可以通过在 UDP 和 TCP JGroups 堆栈中设置以下传输属性来配置 JBoss EAP 使用的 JGroups 缓冲区大小:
- UDP Stack
-
ucast_recv_buf_size
-
ucast_send_buf_size
-
mcast_recv_buf_size
-
mcast_send_buf_size
-
- TCP Stack
-
recv_buf_size
-
send_buf_size
-
可以使用管理控制台或管理 CLI 来配置 JGroups 缓冲区大小。
使用以下语法,通过管理 CLI 设置 JGroups 缓冲区大小属性:
/subsystem=jgroups/stack=STACK_NAME/transport=TRANSPORT/property=PROPERTY_NAME:add(value=BUFFER_SIZE)
以下是一个管理 CLI 命令示例,可将 tcp
堆栈上的 recv_buf_size
属性设置为 20000000
:
/subsystem=jgroups/stack=tcp/transport=TRANSPORT/property=recv_buf_size:add(value=20000000)
也可以使用管理控制台,从 Configuration 选项卡导航到 JGroups 子系统,单击 View,选择 Stack 选项卡,选择适当的堆栈,再单击 传输,编辑 Properties 字段,以此配置 JGroups 缓冲区大小。
24.2.10. 调整 JGroups 子系统
有关监控 jgroups
子系统性能并优化性能的提示,请参阅 性能调优指南中的 JGroups Subsystem Tuning 部分。
24.2.11. JGroups 故障排除
24.2.11.1. 节点不构建集群
确保您的计算机已针对 IP 多播正确设置。JBoss EAP 随附了两个测试程序,它们可用于测试 IP 多播: McastReceiverTest
和 McastSenderTest
。
在终端中,启动 McastReceiverTest
。
$ java -cp EAP_HOME/bin/client/jboss-client.jar org.jgroups.tests.McastReceiverTest -mcast_addr 230.11.11.11 -port 5555
然后,在另一个终端窗口中启动 McastSenderTest
。
$ java -cp EAP_HOME/bin/client/jboss-client.jar org.jgroups.tests.McastSenderTest -mcast_addr 230.11.11.11 -port 5555
如果要绑定到特定网络接口卡(NIC),请使用 -bind_addr YOUR_BIND_ADDRESS
,其中 YOUR_BIND_ADDRESS
是您要绑定的 NIC 的 IP 地址。在发送方和接收方中使用此参数。
在 McastSenderTest
终端窗口中键入时,您应当会在 McastReceiverTest
窗口中看到输出。如果没有,请尝试以下步骤:
-
通过向 sender 命令添加
-ttl VALUE
来提高多播数据包的生存时间。此测试程序使用的默认值为32
,VALUE
不得大于255
。 - 如果计算机有多个接口,请验证您是否正在使用正确的接口。
- 联系系统管理员以确保多播能够处理您选择的接口。
旦您知道多播在集群中的每一台机器上正常工作,您可以重复上述测试来测试网络,将发送者放在一台机器上,接收方放在另一台机器上。
24.2.11.2. 缺少 Heartbeats 失败检测的原因
有时,群集成员因故障检测(FD)而怀疑,因为某些时间段内未收到心跳确认,T
是由 超时
和 max_tries
定义的。
例如,节点 A、B、C 和 D 的集群,其中 A ping B、B ping C、C ping D 和 D ping A,C 可能会因为以下原因而怀疑:
-
B 或 C 以 100% CPU 运行,超过
T
秒。因此,即使 C 发送心跳确认到 B,B 可能无法处理它,因为它处于 100% 的 CPU 使用率。 - B 或 C 是垃圾收集方式,导致的情况与上方相同。
- 以上两个案例的组合。
- 网络丢失数据包。网络中有很多流量时通常会出现这种情况,交换机开始丢弃数据包,通常首先广播,然后是 IP 多播,最后是 TCP 数据包。
-
B 或 C 正在处理回调。例如,如果 C 在其通道上收到处理用
T
+ 1 秒的远程方法调用,此时 C 将不会处理任何其他消息,包括心跳。因此,B 将不会收到心跳确认,并将怀疑 C。