22.2. 与 JGroups 的集群通信


22.2.1. 关于 JGroups

JGroups 是可靠消息传递的工具包,可用于创建节点可以互相发送消息的集群。

jgroups 子系统为 JBoss EAP 中高可用性服务提供组通信支持。它允许您配置命名的频道和协议堆栈,并查看频道的运行时统计信息。使用提供高可用性功能的配置(如受管域中的 hafull-ha 配置文件)或 standalone-ha.xml 或单机服务器的 standalone-full-ha.xml 配置文件时,可以使用 jgroups 子系统。

JBoss EAP 预配置有两个 JGroups 堆栈:

udp
集群中的节点使用用户数据报协议(UDP)多播相互通信。这是默认的堆栈。
tcp
集群中的节点使用传输控制协议(TCP)相互通信。
注意

TCP 的开销更多,并且通常被视为比 UDP 慢,因为它处理错误检查、数据包排序和拥塞控制本身。JGroups 处理 UDP 的这些功能,而 TCP 保证了它们本身。当在不可靠或高拥塞网络上使用 JGroups 时,或者多播不可用时,TCP 是不错的选择。

您可以使用预配置的堆栈,或者自行定义以满足您的系统特定要求。有关可用协议及其属性的更多信息,请参阅以下部分。

22.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>
Copy to Clipboard Toggle word wrap

22.2.2.1. 使用多播配置 TCP

有些网络只允许使用 TCP。

流程

  1. 使用以下管理 CLI 命令,将 ee 频道切换为使用预配置的 tcp 堆栈:

    /subsystem=jgroups/channel=ee:write-attribute(name=stack,value=tcp)
    Copy to Clipboard Toggle word wrap

    这个默认 tcp 堆栈使用 MPING 协议,它使用 IP 多播来发现初始集群成员资格。

22.2.2.2. 在没有多播的情况下配置 TCP

当安全策略不首选或允许多播时,您可以将默认协议堆栈更改为不使用 TCP。

流程

要在没有多播的情况下配置基于 TCP 的集群,请执行以下步骤:

  1. 要将 ee 频道切换为使用 JGroups 子系统中预先配置的 tcp 堆栈,请运行以下命令:

    <channel name="ee" stack="tcp" cluster="ejb"/>
    Copy to Clipboard Toggle word wrap
  2. 设置集群节点的名称:

    • 在独立配置模式中执行以下步骤之一:

      • 运行以下命令:

        <server xmlns="urn:jboss:domain:8.0" name="node_1">
        Copy to Clipboard Toggle word wrap
      • 在启动实例时,为系统属性 jboss.node.name 指定唯一名称。
    • 在域模式中,集群服务器列在服务器标签的 host netobserv.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>
      Copy to Clipboard Toggle word wrap
  3. 选择以下协议之一来发现其他群集成员:

    • TCPGOSSIP :此协议使用外部 gosip 路由器服务来发现集群的成员。这要求配置和管理额外的进程,但允许各个 EAP 实例不列出其他群集成员。如果群集成员经常发生变化,此协议具有优势。如需了解更多详细信息,请参阅 TCPPING
    • TCPPING :此协议定义静态集群成员资格列表,并要求每个节点列出所有潜在的群集成员。当集群成员地址已知且经常更改时,这个协议是首选的。如需了解更多详细信息,请参阅 TCPGOSSIP

22.2.3. 配置 TCPPING

此流程创建新的 JGroups 堆栈,它使用 TCPPING 协议来定义静态集群成员资格列表。提供了一个基础脚本,它会创建一个 tcpping 堆栈,并设置默认的 ee 频道来使用此新堆栈。这个脚本中的管理 CLI 命令必须针对您的环境进行自定义,并将作为批处理进行处理。

流程

  1. 将以下脚本复制到文本编辑器,并将其保存到本地文件系统中。

    # 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
    Copy to Clipboard Toggle word wrap

    请注意,定义的协议顺序很重要。您还可以通过将 add-index 值传递给 add 命令,在特定索引中插入协议。索引基于零,因此以下管理 CLI 命令会将 UNICAST3 协议添加为第七个协议。

    /subsystem=jgroups/stack=tcpping/protocol=UNICAST3:add(add-index=6)
    Copy to Clipboard Toggle word wrap
  2. 修改您的环境的脚本。

    • 如果您在受管域中运行,您必须在 /subsystem=jgroups 命令前使用 /profile=PROFILE_NAME 指定要更新的配置集。
    • 根据您的环境调整以下属性:

      • socket-bindings: 以逗号分隔的主机和端口组合列表,它们被视为众所周知,并可用于查找初始成员资格。有关定义套接字绑定 的更多信息,请参阅配置套接字绑定。
      • initial_hosts :主机和端口组合的逗号分隔列表,其语法是 HOST[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 属性。
  3. 通过将脚本文件 传递给管理 CLI,运行脚本。

    $ EAP_HOME/bin/jboss-cli.sh --connect --file=/path/to/SCRIPT_NAME
    Copy to Clipboard Toggle word wrap

TCPPING 堆栈现在可用,TCP 用于网络通信。

22.2.3.1. 在独立模式中配置 TCPPING

此流程帮助您在独立模式中为集群应用程序配置 TCP 堆栈和节点。

流程

  1. 在 JGroups 子系统中将默认堆栈从 udp 更改为 tcp :

    <channel name="ee" stack="tcp" cluster="ejb"/>
    Copy to Clipboard Toggle word wrap
  2. 将 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>
    Copy to Clipboard Toggle word wrap
    注意

    initial_hosts 中设置的端口号 7600 必须与 jgroups-tcp socket-binding 定义中定义的端口号相同。如果将 port-offset 功能用于 socket-binding,则需要在 initial_hosts 中偏移后指定相同的值。

  3. 设置 private 接口的 IP 地址,供 JGroups 组件使用。IP 地址应与 initial_hosts 中指定的 IP 地址之一关联:

    <interface name="private">
      <inet-address value="${jboss.bind.address.private:192.168.1.5}"/>
    </interface>
    Copy to Clipboard Toggle word wrap
  4. 重复上述步骤,以配置集群中的其他节点。配置节点时,启动每个节点并部署一个集群应用。

验证

  • 您可以检查日志以验证节点是否已启动并在运行:

    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]
    Copy to Clipboard Toggle word wrap

22.2.3.2. 在域模式中配置 TCPPING

此流程帮助您在域模式中为集群应用程序配置 TCP 堆栈和节点。

流程

  1. 如果将同一配置集用于多个集群,请将系统属性值设置为 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>
    Copy to Clipboard Toggle word wrap
  2. 在主机控制器的 XML 配置中设置私有接口的 IP 地址。专用接口的 IP 地址应当与 initial_hosts 中列出的 IP 地址之一关联。

    <interfaces>
        ....
      <interface name="private">
        <inet-address value="${jboss.bind.address.private:192.168.1.5}"/>
      </interface>
    </interfaces>
    Copy to Clipboard Toggle word wrap

验证

  • 您可以检查日志以验证节点是否已启动并在运行:

    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]
    Copy to Clipboard Toggle word wrap

22.2.4. 配置 TCPGOSSIP

此流程创建新的 JGroups 堆栈,它使用 TCPGOSSIP 协议使用外部 gosip 路由器来发现集群的成员。提供了一个基础脚本,它会创建一个 tcpgossip 堆栈,并设置默认的 ee 频道来使用此新堆栈。这个脚本中的管理 CLI 命令必须针对您的环境进行自定义,并将作为批处理进行处理。

流程

  1. 将以下脚本复制到文本编辑器,并将其保存到本地文件系统中。

    # 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
    Copy to Clipboard Toggle word wrap

    请注意,定义的协议顺序很重要。您还可以通过将 add-index 值传递给 add 命令,在特定索引中插入协议。索引基于零,因此以下管理 CLI 命令会将 UNICAST3 协议添加为第七个协议。

    /subsystem=jgroups/stack=tcpgossip/protocol=UNICAST3:add(add-index=6)
    Copy to Clipboard Toggle word wrap
  2. 修改您的环境的脚本。

    • 如果您在受管域中运行,您必须在 /subsystem=jgroups 命令前使用 /profile=PROFILE_NAME 指定要更新的配置集。
    • 根据您的环境调整以下属性:

      • socket-bindings: 以逗号分隔的主机和端口组合列表,它们被视为众所周知,并可用于查找初始成员资格。有关定义套接字绑定 的更多信息,请参阅配置套接字绑定。
      • initial_hosts :主机和端口组合的逗号分隔列表,其语法是 HOST[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 尝试重新连接到 gosip 路由器的时间间隔(以毫秒为单位)。
      • sock_conn_timeout :套接字创建的最大时间。默认值为 1000 毫秒。
      • sock_read_timeout :读取时阻止的最长时间,以毫秒为单位。值 0 将无限期阻止。
  3. 通过将脚本文件 传递给管理 CLI,运行脚本。

    $ EAP_HOME/bin/jboss-cli.sh --connect --file=/path/to/SCRIPT_NAME
    Copy to Clipboard Toggle word wrap

TCPGOSSIP 堆栈现在可用,TCP 用于网络通信。此堆栈配置为与 gossip 路由器搭配使用,以便 JGroups 集群成员能够找到其他群集成员。

22.2.5. 配置 JDBC_PING

您可以使用 JDBC_PING 协议来管理和发现集群中的成员资格。

JDBC_PING 使用 data-source 中指定的数据库来列出集群的成员。

流程

  1. 创建数据源以连接到您要用来管理集群成员资格的数据库。
  2. 将以下脚本复制到文本编辑器,并将其保存到本地文件系统中。

    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
    Copy to Clipboard Toggle word wrap
    注意

    定义的协议的顺序非常重要。您还可以通过将 add-index 值传递给 add 命令,在特定索引中插入协议。索引基于零,因此以下管理 CLI 命令会将 UNICAST3 协议添加为第七个协议。

    /subsystem=jgroups/stack=JDBC_PING/protocol=UNICAST3:add(add-index=6)
    Copy to Clipboard Toggle word wrap
  3. 修改您的环境的脚本。

    • 如果您在受管域中运行,您必须在 /subsystem=jgroups 命令前使用 /profile=PROFILE_NAME 指定要更新的配置集。
    • 将 'ExampleDS' 替换为在第 1 步中定义的 data-source 的名称。
  4. 通过将脚本文件 传递给管理 CLI,运行脚本。

    $ EAP_HOME/bin/jboss-cli.sh --connect --file=/path/to/SCRIPT_NAME
    Copy to Clipboard Toggle word wrap

JDBC_PING 堆栈现在可用,TCP 用于网络通信。

22.2.6. 将 JGroups 绑定到网络接口

默认情况下,JGroups 仅绑定到 私有 网络接口,该接口指向默认配置中的 localhost。为安全起见,JGroups 不会绑定到 JBoss EAP 启动期间指定的 -b 参数定义的网络接口,因为集群流量不应在公共网络接口上公开。

有关如何配置网络接口的详情,请参考本指南中的 网络和端口配置 章节。

重要

为安全起见,JGroups 应该只绑定到一个非公共网络接口。出于性能考虑,我们还建议 JGroups 流量的网络接口应该是专用虚拟局域网(VLAN)的一部分。

22.2.7. 保护集群

为了安全地运行集群,需要注意几个问题:

  • 防止未授权节点加入集群。这可以通过 需要身份验证 来解决。
  • 防止非成员与群集成员通信。这可以通过加密消息 来解决

22.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"/>
...
Copy to Clipboard Toggle word wrap
带有摘要算法令牌的 AUTH

这个格式可用于任何摘要算法,如 MD5 或 SHA-2。JBoss EAP 8.0 中的默认摘要算法是 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"/>
...
Copy to Clipboard Toggle word wrap
带有 X509 令牌的 AUTH

本例在 elytron 子系统中创建新的密钥存储,并在 JGroups AUTH 配置中引用它。

  1. 创建密钥存储:

    $ keytool -genkeypair -alias jgroups_key -keypass my_password -storepass my_password -storetype jks -keystore jgroups.keystore -keyalg RSA
    Copy to Clipboard Toggle word wrap
  2. 使用管理 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)
    Copy to Clipboard Toggle word wrap
  3. 在 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"/>
    ...
    Copy to Clipboard Toggle word wrap

22.2.7.2. 配置加密

要加密消息,JGroups 使用由集群成员共享的 secret 密钥。发送者使用共享 secret 密钥加密消息,并且接收器使用相同的 secret 密钥解密消息。使用对称加密 (使用 SYM_ENCRYPT 协议配置),节点使用共享密钥存储来检索机密密钥。通过 非对称加密 (使用 ASYM_ENCRYPT 协议进行配置),节点会在使用 AUTH 进行身份验证后从集群的协调器检索机密密钥。

使用对称加密

要使用 SYM_ENCRYPT,您必须设置一个密钥存储,它将在每个节点的 JGroups 配置中引用该密钥存储。

  1. 创建密钥存储。

    在以下命令中,将 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
    Copy to Clipboard Toggle word wrap

    这将生成一个 defaultStore.keystore 文件,它将在 JGroups 配置中引用该文件。

  2. 生成密钥存储后,会使用以下两种方法之一在 SYM_PROTOCOL 中定义。

注意

使用 SYM_ENCRYPT 时配置 AUTH 是可选的。

通过直接引用密钥存储来使用对称加密
  1. jgroups 子系统中配置 SYM_ENCRYPT 协议。

    在适用的服务器配置文件中,使用适当的属性设置添加 SYM_ENCRYPT 协议。此协议将引用之前创建的密钥存储。SYM_ENCRYPT 协议应在 pbcast.NAKACK2 协议之前立即配置。

    <subsystem xmlns="{JgroupsSubsystemNamespace}">
      <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>
    Copy to Clipboard Toggle word wrap
使用 elytron 的对称加密
  1. 使用管理 CLI,在 elytron 子系统中创建一个密钥存储,该密钥存储引用 使用对称加密 中创建的 defaultStore.keystore

    /subsystem=elytron/key-store=jgroups-keystore:add(path=/path/to/defaultStore.keystore,credential-reference={clear-text=PASSWORD},type=JCEKS)
    Copy to Clipboard Toggle word wrap
  2. 使用适当的属性设置,在 jgroups 子系统中添加 SYM_ENCRYPT 协议。SYM_ENCRYPT 协议应在 pbcast.NAKACK2 协议之前立即配置,如以下配置中所示:

    <subsystem xmlns="{JgroupsSubsystemNamespace}">
      <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>
    Copy to Clipboard Toggle word wrap
    注意

    上例使用明文密码;但是,还可以定义凭据存储来定义配置文件外的密码。有关配置此存储的更多信息,请参阅如何配置服务器安全 指南中的 凭证存储 部分。

使用非对称加密

要使用 ASYM_ENCRYPT,必须定义 AUTH 协议。有关在 jgroups 子系统中配置 AUTH 协议的说明,请参阅 配置身份验证 部分。

ASYM_ENCRYPT 使用两种方法之一进行配置。

通过生成 secret 密钥来使用非对称加密
  1. jgroups 子系统中配置 ASYM_ENCRYPT 协议。

    在适用的服务器配置文件中,使用适当的属性设置添加 ASYM_ENCRYPT 协议。ASYM_ENCRYPT 协议应在 pbcast.NAKACK2 协议之前立即配置,如以下配置中所示:

    <subsystem xmlns="{JgroupsSubsystemNamespace}">
      <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>
    Copy to Clipboard Toggle word wrap
在 elytron 中使用非对称加密
  1. 创建密钥存储以包含密钥对。以下命令使用 mykey 条目创建密钥存储:

    $ keytool -genkeypair -alias mykey -keyalg RSA -keysize 1024 -keystore defaultKeystore.keystore -dname "CN=localhost" -keypass secret -storepass secret
    Copy to Clipboard Toggle word wrap
  2. 使用管理 CLI,在 elytron 子系统中创建一个引用 defaultStore.keystore 的密钥存储。

    /subsystem=elytron/key-store=jgroups-keystore:add(path=/path/to/defaultStore.keystore,credential-reference={clear-text=PASSWORD},type=JCEKS)
    Copy to Clipboard Toggle word wrap
  3. 使用适当的属性设置,在 jgroups 子系统中添加 ASYM_ENCRYPT 协议。ASYM_ENCRYPT 协议应在 pbcast.NAKACK2 协议之前立即配置,如以下配置中所示:

    <subsystem xmlns="{JgroupsSubsystemNamespace}">
      <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>
    Copy to Clipboard Toggle word wrap
    注意

    上例使用明文密码;但是,还可以定义凭据存储来定义配置文件外的密码。有关配置此存储的更多信息,请参阅如何配置服务器安全 指南中的 凭证存储 部分。

22.2.8. 配置 JGroups 线程池

jgroups 子系统包含 默认的内部oobtimer 线程池。这些池可以针对任何 JGroups 堆栈配置,不会影响本地节点上配置的 bean 或其他池。JGroup 线程池用于支持集群通信。

下表列出了您可以为每个线程池配置的属性,以及每个线程池的默认值。

Expand
线程池名称描述keepalive-timemax-threadsmin-threadsqueue-length

default

此池用于处理未标记为带外的传入消息。

60000L

300

20

100

internal

此池用于处理 EAP 维护所需的内部进程。

60000L

4

2

100

OOB

此池用于处理带外信息。

60000L

300

20

0

timer

此池用于处理时间密集型调度程序消息。

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)
Copy to Clipboard Toggle word wrap

以下是管理 CLI 命令的一个示例,可在 udp 堆栈 的默认 线程池中将 max-threads 值设置为 500

/subsystem=jgroups/stack=udp/transport=UDP/thread-pool=default:write-attribute(name="max-threads", value="500")
Copy to Clipboard Toggle word wrap

22.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)
Copy to Clipboard Toggle word wrap

要解决这个问题,请参考您的操作系统文档来了解如何增加缓冲区大小。对于 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
Copy to Clipboard Toggle word wrap

修改 /etc/sysctl.conf 后,运行 sysctl -p 以使更改生效。

配置 JGroups 缓冲区大小

您可以通过在 UDP 和 TCP JGroups 堆栈上设置以下传输属性来配置 JBoss EAP 使用的 JGroups 缓冲区大小。

UDP 堆栈
  • ucast_recv_buf_size
  • ucast_send_buf_size
  • mcast_recv_buf_size
  • mcast_send_buf_size
TCP 堆栈
  • recv_buf_size
  • send_buf_size

JGroups 缓冲区大小可以使用管理控制台或管理 CLI 来配置。

通过以下语法,通过管理 CLI 设置 JGroups 缓冲区 size 属性:

/subsystem=jgroups/stack=STACK_NAME/transport=TRANSPORT/property=PROPERTY_NAME:add(value=BUFFER_SIZE)
Copy to Clipboard Toggle word wrap

以下是将 tcp 堆栈上的 recv_buf_size 属性设置为 20000000 的管理 CLI 命令。

/subsystem=jgroups/stack=tcp/transport=TRANSPORT/property=recv_buf_size:add(value=20000000)
Copy to Clipboard Toggle word wrap

也可以使用管理控制台,从 Configuration 选项卡导航到 JGroups 子系统,单击 View,选择 Stack 选项卡,选择适当的堆栈,单击 Transport,再编辑 Properties 字段来配置 JGroups 缓冲区大小。

22.2.10. 调整 JGroups 子系统

有关监控并优化 jgroups 子系统性能的提示,请参阅 JBoss EAP 性能调优的 JGroups 子系统调优 部分。

22.2.11. JGroups 故障排除

22.2.11.1. 节点不组成集群

确保为 IP 多播正确设置您的机器。JBoss EAP 附带两个测试程序,可用于测试 IP 多播: McastReceiverTestMcastSenderTest

在终端中,启动 McastReceiverTest

$ java -cp EAP_HOME/bin/client/jboss-client.jar org.jgroups.tests.McastReceiverTest -mcast_addr 230.11.11.11 -port 5555
Copy to Clipboard Toggle word wrap

然后,在另一个终端窗口中,启动 McastSenderTest

$ java -cp EAP_HOME/bin/client/jboss-client.jar org.jgroups.tests.McastSenderTest -mcast_addr 230.11.11.11 -port 5555
Copy to Clipboard Toggle word wrap

如果要绑定到特定网络接口卡(NIC),请使用 -bind_addr YOUR_BIND_ADDRESS,其中 YOUR_BIND_ADDRESS 是您要绑定到的 NIC 的 IP 地址。在发送者和接收器中使用此参数。

当您在 McastSenderTest 终端窗口中键入时,您应该在 McastReceiverTest 窗口中看到输出。如果没有,请尝试以下步骤。

  • 通过在 sender 命令中添加 -ttl VALUE 来增加多播数据包的时间。此测试程序使用的默认值是 32VALUE 不得大于 255
  • 如果机器有多个接口,请确定您使用正确的接口。
  • 联系系统管理员,以确保多播可以在您选择的接口上正常工作。

一旦您知道,多播可以在集群中的每个机器上正常工作,您可以重复上述测试来测试网络,将发送者放在一台机器上,将发件人放在另一台机器上。

22.2.11.2. 在失败检测中缺少心跳的原因

有时,故障检测(FD)会怀疑群集成员,因为在某些情况下未收到心跳确认,T 表示由 timeoutmax_tries 定义。

例如,节点 A、B、C 和 D (其中 A ping B、B ping C、C pings D 和 D pings A)会因为以下任何原因怀疑 C:

  • B 或 C 在 100% CPU 上运行,超过 T 秒。因此,即使 C 向 B 发送心跳确认,B 可能无法处理它,因为它是 100% CPU 用量。
  • B 或 C 是垃圾回收,这会导致与以上相同的情况。
  • 上述两个情况的组合。
  • 网络会丢失数据包。当网络上有很多流量时,通常会发生这种情况,并且交换机开始丢弃数据包,通常是首先广播,然后是 IP 多播,最后会发生 TCP 数据包。
  • b 或 C 是处理回调。例如,如果 C 收到对其需要 T + 1 秒进行处理的频道的远程方法调用,则 C 将无法处理任何其他消息,包括心跳(包括心跳)。因此,B 将不会收到心跳确认,并且会怀疑 C。
返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2025 Red Hat