第 22 章 配置高可用性

22.1. 高可用性介绍

JBoss EAP 提供下列高可用性服务来保证部署的 Java EE 应用程序的可用性。

负载平衡
这允许服务将负载分散到多个服务器从而处理大量请求。即使在处理大量请求时,客户都可以及时从服务得到响应。
故障切换
故障切换功能确保了,在硬件或网络出现问题时,客户端对服务的访问也不会被中断。如果服务失败,另外一个集群成员会接替来处理客户端的请求,从而使服务可以继续进行。

集群(Clustering)是实现这些功能的一个技术。一个集群中的成员可以被配置为用来共享负载(负载均衡),或在其它集群成员出现故障时接替它们来处理用户的请求(故障切换)。

注意

需要注意的一点是,所选的 JBoss EAP 操作模式(独立服务器(standalone server)受管域(managed domain))代表了您希望如何管理您的服务器。而无论选择什么操作模式,都可以在 JBoss EAP 中配置高可用性服务。

通过不同的组件,JBoss EAP 可以在不同级别上支持高可用性。这些运行时组件以及应用程序包括:

  • 应用服务器实例
  • 和内部的 JBoss Web Server、Apache HTTP Server、Microsoft IIS 或 Oracle iPlanet Web Server 一起使用的 Web 应用程序
  • 有状态(Stateful)和无状态(stateless)的 Session Enterprise JavaBeans (EJB)
  • 单点登录(SSO)机制
  • HTTP 会话
  • JMS 服务和 message-driven beans (MDB)
  • Singleton MSC 服务
  • Singleton 部署

通过 jgroupsinfinispanmodcluster 子系统,可以在 JBoss EAP 中使用高可用性。hafull-ha 配置集可以启用这些子系统。在 JBoss EAP 中,这些服务会根据需要被启动或关闭,但它们只会当部署在服务器上的应用应用程序被配置为 distributable 时才可以启用。

关于如何创建分布式应用程序,请参考《JBoss EAP 开发指南》

22.2. 与 JGroups 的集群通讯

22.2.1. 关于 JGroups

JGroups 是创建可靠消息通讯的工具包,它可用来创建集群,其中的节点可以彼此发送消息。

jgroups 子系统为 JBoss EAP 中的高可用性服务提供了组交流的支持。当一个配置提供了高可用性功能时(如在受管域中的 hafull-ha 配置集;或一个独立服务器的 standalone-ha.xmlstandalone-full-ha.xml 配置文件),jgroups 子系统才可用。

JBoss EAP 预配置了两个 JGroups 栈:

udp
集群里的节点使用 Datagram Protocol (UDP) 多播进行彼此间的通讯。这是默认设置。
tcp
集群中的节点使用 TCP 协议和其它节点进行通讯。

您可以使用预配置的设置,或根据您系统的具体情况定义自己的设置。

注意

因为 TCP 需要进行错误检查、数据包排序、阻塞控制等操作,所以会消耗更多额外的资源,并通常被认为比 UDP 的性能要低。JGroups 会为 UDP 处理这些操作,而 TCP 可以保证自己实现这些功能。当在一个不稳定或具有大量数据阻塞的网络中使用 JGroups,或多播不可用时,使用 TCP 是一个好的选择。

22.2.2. 切换默认的 JGroups 频道以使用 TCP

在默认情况下,集群节点使用 UDP 协议来通讯。默认的 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。使用下列管理 CLI 命令来切换 ee 频道以使用预配置的 tcp 栈。

/subsystem=jgroups/channel=ee:write-attribute(name=stack,value=tcp)

这个默认的 tcp 栈使用 MPING 协议,它使用 IP 多播来发现初始的集群成员资格。关于配置用于其他成员资格发现协议的栈的内容,请参考下列章节:

  • 使用 TCPPING 协议来定义静态的集群成员资格列表。
  • 使用 TCPGOSSIP 协议以使用外部的 Gossip 路由器来发现集群的成员。

22.2.3. 配置 TCPPING

以下过程会创建一个新的 JGroups 栈,它使用 TCPPING 协议来定义一个静态的集群成员列表。一个基本的脚本会被提供,它会创建一个 tcpping 栈,并设置默认的 ee 频道来使用这个新栈。这个脚本中的管理 CLI 命令需要根据您的具体环境进行定制,并会以批处理的形式运行。

  1. 复制下列脚本至文本编辑器并保存至本地的文件系统。

    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
    # Set the properties for the TCPPING protocol
    /subsystem=jgroups/stack=tcpping/protocol=TCPPING:write-attribute(name=properties,value={initial_hosts="HOST_A[7600],HOST_B[7600]",port_range=0,timeout=3000})
    /subsystem=jgroups/stack=tcpping/protocol=MERGE3:add
    /subsystem=jgroups/stack=tcpping/protocol=FD_SOCK:add(socket-binding=jgroups-tcp-fd)
    /subsystem=jgroups/stack=tcpping/protocol=FD: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=FRAG2:add
    # Set tcpping as the stack for the ee channel
    /subsystem=jgroups/channel=ee:write-attribute(name=stack,value=tcpping)
    run-batch
    reload

    请注意,定义协议的顺序非常重要。

  2. 根据您的环境修改这个脚本。

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

      • initial_hosts:一个以逗号分隔的主机列表。这些主机被认为是已知的,并可以用来查找初始的成员。
      • port_range:如果需要,可以分配一个端口范围。如果把端口范围设置为 2,初始的端口是 7600,则 TCPPING 会试图通过端口 7600-7601 来联系每个主机。
      • timeout:集群成员的超时时间,单位为毫秒。
  3. 将脚本文件传入管理 CLI 来运行脚本。

    $ EAP_HOME/bin/jboss-cli.sh --connect --file=/path/to/SCRIPT_NAME

TCPPING 栈现在已可用而 TCP 被用于网络通讯。

22.2.4. 配置 TCPGOSSIP

以下过程会创建一个新的 JGroups 栈,它通过 TCPGOSSIP 协议使用一个外部的 gossip 路由器来发现一个集群的成员列表。一个基本的脚本会被提供,它会创建一个 tcpgossip 栈,并设置默认的 ee 频道来使用这个新栈。这个脚本中的管理 CLI 命令需要根据您的具体环境进行定制,并会以批处理的形式运行。

  1. 复制下列脚本至文本编辑器并保存至本地的文件系统。

    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
    # Set the properties for the TCPGOSSIP protocol
    /subsystem=jgroups/stack=tcpgossip/protocol=TCPGOSSIP:write-attribute(name=properties,value={initial_hosts="HOST_A[13001]"})
    /subsystem=jgroups/stack=tcpgossip/protocol=MERGE3:add
    /subsystem=jgroups/stack=tcpgossip/protocol=FD_SOCK:add(socket-binding=jgroups-tcp-fd)
    /subsystem=jgroups/stack=tcpgossip/protocol=FD: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=FRAG2:add
    # Set tcpgossip as the stack for the ee channel
    /subsystem=jgroups/channel=ee:write-attribute(name=stack,value=tcpgossip)
    run-batch
    reload

    请注意,定义协议的顺序非常重要。

  2. 根据您的环境修改这个脚本。

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

      • initial_hosts:一个以逗号分隔的主机列表。这些主机被认为是已知的,并可以用来查找初始的成员。
      • reconnect_interval:已断开的 stub 试图重连 Gossip 路由器的间隔(毫秒)。
      • sock_conn_timeout:套接字创建的最长时间。默认值是 1000 毫秒。
      • sock_read_timeout:阻塞块读取的最长时间(毫秒)。0 表示无限期阻塞。
  3. 将脚本文件传入管理 CLI 来运行脚本。

    $ EAP_HOME/bin/jboss-cli.sh --connect --file=/path/to/SCRIPT_NAME

TCPGOSSIP 栈现在已可用而 TCP 被用于网络通讯。这个栈被配置和 Gossip 路由器一起使用,所以 JGroups 集群成员可以找到其他的集群成员。

22.2.5. 绑定 JGroups 到网络接口

在默认情况下,JGroups 只绑定 private 网络接口,它执行默认设置的 localhost。因为集群的网络数据不应该暴露到公共网络接口,所以为了安全的原因,JGroups 不会绑定在 JBoss EAP 启动时使用 -b 参数定义的网络接口。

关于如何配置网络接口的信息,请参考网络和端口配置章节。

重要

出于安全原因,JGroups 只应该绑定到非公共网络接口。而出于性能考量,我们还推荐 JGroups 的网络接口应该是专属的虚拟局域网(Virtual Local Area Network,VLAN)的一部分。

22.2.6. 保护集群

要安全运行集群,您需要解决几个问题:

  • 防止未授权的节点加入集群。这是通过验证来解决的。
  • 防止非成员与集群成员通讯。这是通过消息加密实现的。
配置验证

JGroups 验证是由 AUTH 协议执行的。其目的是确保只有经过验证的节点才能加入集群。

在相关的服务器配置文件里,添加 AUTH 协议和合适的属性设置。 AUTH 协议应该恰好在 pbcast.GMS 协议之前配置。

<subsystem xmlns="urn:jboss:domain:jgroups:4.0">
  <stacks>
    <stack name="udp">
      <transport type="UDP" socket-binding="jgroups-udp"/>
      <protocol type="PING"/>
      <protocol type="MERGE3"/>
      <protocol type="FD_SOCK" socket-binding="jgroups-udp-fd"/>
      <protocol type="FD_ALL"/>
      <protocol type="VERIFY_SUSPECT"/>
      <protocol type="pbcast.NAKACK2"/>
      <protocol type="UNICAST3"/>
      <protocol type="pbcast.STABLE"/>
      <protocol type="AUTH">
        <property name="auth_class">org.jgroups.auth.MD5Token</property>
        <property name="auth_value">mytoken</property> <!-- Change this password -->
        <property name="token_hash">MD5</property>
      </protocol>
      <protocol type="pbcast.GMS"/>
      <protocol type="UFC"/>
      <protocol type="MFC"/>
      <protocol type="FRAG2"/>
    </stack>
  </stacks>
</subsystem>
配置加密

为了加密信息,JGroups 使用一个由集群成员共享的密钥。信息的发送者使用这个密钥对信息进行加密,接收者使用相同的密钥进行解密。对于对称加密(配置为使用 SYM_ENCRYPT 协议),节点使用共享的 keystore 来获取这个密钥。对于非对称加密(配置为使用 ASYM_ENCRYPT 协议),节点在使用 AUTH 被验证后,从集群的 coordinator 中获得这个密钥。

重要

You must apply Red Hat JBoss Enterprise Application Platform 7.0 Update 01 or a newer cumulative patch to your JBoss EAP installation in order to have access to the SYM_ENCRYPT and ASYM_ENCRYPT protocols.

See the JBoss EAP Patching and Upgrading Guide for information on applying cumulative patches.

使用对称加密

要使用 SYM_ENCRYPT,您必须设立每个节点在 JGroups 配置里引用的密钥库(keystore)。

  1. 创建密钥库

    在下面的命令里,请用合适的 JGroups JAR 版本替换 VERSION,并用密钥库密码替换 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

    这将生成一个在 JGroups 配置里引用的 defaultStore.keystore 文件。

  2. jgroups 子系统中配置 SYM_ENCRYPT 协议。

    在相关的服务器配置文件里,添加 SYM_ENCRYPT 协议和合适的属性设置。 SYM_ENCRYPT 协议应该恰好在 pbcast.NAKACK2 协议之前配置。

    <subsystem xmlns="urn:jboss:domain:jgroups:4.0">
      <stacks>
        <stack name="udp">
          <transport type="UDP" socket-binding="jgroups-udp"/>
          <protocol type="PING"/>
          <protocol type="MERGE3"/>
          <protocol type="FD_SOCK" socket-binding="jgroups-udp-fd"/>
          <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="FRAG2"/>
        </stack>
      </stacks>
    </subsystem>
注意

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

使用不对称加密
  1. jgroups 子系统中配置 ASYM_ENCRYPT 协议。

    在相关的服务器配置文件里,添加 ASYM_ENCRYPT 协议和合适的属性设置。 ASYM_ENCRYPT 协议应该恰好在 pbcast.NAKACK2 协议之前配置。

    <subsystem xmlns="urn:jboss:domain:jgroups:4.0">
      <stacks>
        <stack name="udp">
          <transport type="UDP" socket-binding="jgroups-udp"/>
          <protocol type="PING"/>
          <protocol type="MERGE3"/>
          <protocol type="FD_SOCK" socket-binding="jgroups-udp-fd"/>
          <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="FRAG2"/>
        </stack>
      </stacks>
    </subsystem>
  2. jgroups 子系统中配置 AUTH 协议。

    AUTHASYM_ENCRYPT 要求的。相关说明请参考配置验证章节。

22.2.7. 配置 JGroups 线程池

jgroups 子系统包含 defaultinternaloobtimer 线程池。这些池可以对每个 JGroups 栈进行配置。

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

线程池的名称keepalive-timemax-threadsmin-threadsqueue-length

default

60000L

300

20

100

internal

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)

以下管理 CLI 命令示例会把 udp 栈的 default 线程池里的 max-threads 的值设置为 500

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

22.2.8. 配置 JGroups Send 和 Receive 缓冲

解决缓冲区大小警告

在默认情况下,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 栈
  • 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 缓冲大小属性。

/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)

JGroups 缓冲区大小也可以通过管理控制台进行配置。从 Configuration 标签页进入 JGroups 子系统,查看相关的栈,选择 Transport,然后选择 Properties 标签页。

22.2.9. JGroups 的故障排除

22.2.9.1. 节点没有组成一个集群

确认您的机器已正确配置了 IP 多播。JBoss EAP 带有两个可以用来测试多播的程序:McastReceiverTestMcastSenderTest

在一个终端中启动 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

使用 -bind_addr YOUR_BIND_ADDRESS可以绑定一个特定的网络接口卡(NIC),其中的 YOUR_BIND_ADDRESS 是要绑定的 NIC 的 IP 地址。在接收方和发送方都要使用这个参数。

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

  • 在 sender 命令中使用 -ttl VALUE 来增加多播的 time-to-live 值。这个测试程序使用的默认值是 32VALUE 的值不能超过 255
  • 如果机器有多个接口,您需要检查是否使用了正确的接口。
  • 联系一个系统管理员来确认,多播可以在所选接口中工作。

在您确定多播可以在集群的所有机器上都可以正常工作后,就可以重复上面的测试来对网络进行测试,把 sender 放到一个机器上,把 receiver 放到另外一个机器上。

22.2.9.2. 在故障监测中导致丢失“心跳”的原因

有时,当在一定时间内(T,由 timeoutmax_tries 指定)故障监测(failure detection - FD)没有获得“心跳”确认时,会认为集群中的一个成员可能出现了问题。

例如,在一个包括节点 A、B、C 和 D 的集群中,A ping B、B ping C、C ping D、D ping A。当出现以下情况时 C 会被认可能出现了问题:

  • B 或 C 的 CPU 使用率为 100% 的时间超过了一定长度(T 秒)。当 C 向 B 发送了一个心跳确认时,B 可能因为处于 100% CPU 使用率而无法处理 C 发送的心跳确认。
  • B 或 C 正在进行垃圾收集操作,这会和以上情况相同。
  • 以上两种情况的组合。
  • 网络丢失了数据包。这通常发生在网络中有大量数据时,交换机会开始丢掉数据包,一般是先广播,然后是 IP 多播,最后是 TCP 数据包。
  • B 或 C 正在处理回调。例如,C 通过它的频道接收到一个远程方法调用,并用了 T + 1 秒的时间进行处理。在这个期间,C 将不会处理包括心跳在内的其它信息。因此,B 将不会收到 C 的心跳确认信息,并认为 C 可能出现了问题。

22.3. Infinispan

22.3.1. 关于 Infinispan

Infinispan 是一个 Java 数据网格平台,它提供了一个与 JSR-107 兼容的缓存接口用来管理缓存的数据。如需了解更多与 Infinispan 相关的信息,请参阅 Infinispan Documentation

infinispan 子系统为 JBoss EAP 提供了缓存支持。它允许您配置并查看命名的缓存容器和缓存区的运行时的指标。

在使用一个可以提供高可用性功能的配置中(如受管域中的 hafull-ha 配置集,或独立服务器的 standalone-ha.xmlstandalone-full-ha.xml 配置文件),infinispan 子系统提供了缓存、状态复制和状态分布的支持。在一个非高可用性配置中,infinispan 子系统提供了本地的缓存支持。

重要

在 JBoss EAP 中,Infinispan 作为一个私人模块提供,它为 JBoss EAP 提供了缓存功能。Infinispan 不能被应用程序直接使用。

22.3.2. 缓存容器

缓存容器是子系统使用的缓存的仓库。每个缓存容器都会定义一个要使用的默认缓存。

JBoss EAP 7 定义了下列默认的 Infinispan 缓存容器:

  • 用于单点缓存的 server
  • 用于 Web 会话集群的 web
  • 用于 stateful session bean 集群的 ejb
  • 用于实体缓存的 hibernate

示例:默认的 Infinispan 配置

<subsystem xmlns="urn:jboss:domain:infinispan:4.0">
  <cache-container name="server" aliases="singleton cluster" default-cache="default" module="org.wildfly.clustering.server">
    <transport lock-timeout="60000"/>
    <replicated-cache name="default" mode="SYNC">
      <transaction mode="BATCH"/>
    </replicated-cache>
  </cache-container>
  <cache-container name="web" default-cache="dist" module="org.wildfly.clustering.web.infinispan">
    <transport lock-timeout="60000"/>
    <distributed-cache name="dist" mode="ASYNC" l1-lifespan="0" owners="2">
      <locking isolation="REPEATABLE_READ"/>
      <transaction mode="BATCH"/>
      <file-store/>
    </distributed-cache>
  </cache-container>
  <cache-container name="ejb" aliases="sfsb" default-cache="dist" module="org.wildfly.clustering.ejb.infinispan">
    <transport lock-timeout="60000"/>
    <distributed-cache name="dist" mode="ASYNC" l1-lifespan="0" owners="2">
      <locking isolation="REPEATABLE_READ"/>
      <transaction mode="BATCH"/>
      <file-store/>
    </distributed-cache>
  </cache-container>
  <cache-container name="hibernate" default-cache="local-query" module="org.hibernate.infinispan">
    <transport lock-timeout="60000"/>
    <local-cache name="local-query">
      <eviction strategy="LRU" max-entries="10000"/>
      <expiration max-idle="100000"/>
    </local-cache>
    <invalidation-cache name="entity" mode="SYNC">
      <transaction mode="NON_XA"/>
      <eviction strategy="LRU" max-entries="10000"/>
      <expiration max-idle="100000"/>
    </invalidation-cache>
    <replicated-cache name="timestamps" mode="ASYNC"/>
  </cache-container>
</subsystem>

记录下每个容器定义的默认缓存。例如,web 缓存容器定义了 dist 分布的缓存作为默认缓存。因此,当对 web 会话进行集群时,dist 缓存会被使用。

重要

另外,您还可以添加额外的缓存和缓存容器。如为 HTTP 会话、有状态的会话 bean、singleton 服务或部署增加缓存。用户应用程序不能直接使用这些缓存。

22.3.2.1. 配置缓存容器

缓存容器和缓存属性可以用管理控制台或管理 CLI 来配置。

警告

因为配置中的其它组件可能在使用它们,所以您不应该修改缓存或缓存容器的名称。

用管理控制台配置缓存

从管理控制台的 Configuration 标签页进入 Infinispan 子系统,您就可以配置缓存和缓存容器。在一个受管域中,确定选择适当的配置集进行配置。

  • 添加缓存容器。

    Cache Container 旁边的 Add 按钮,输入新缓存容器的设置。

  • 更新缓存容器的设置。

    选择适当的缓存容器,从下拉菜单中选 Container Settings。根据需要配置缓存容器。

  • 更新缓存容器的传输设置。

    选择适当的缓存容器,从下拉菜单中选 Transport Settings。根据需要配置缓存容器的传输设置。

  • 配置缓存。

    选择适当的缓存容器,选 View。在相关的缓存标签页中(如Replicated Caches)可以添加、更新和删除缓存。

用管理 CLI 配置缓存

您可以使用管理 CLI 配置缓存和缓存容器。在一个受管域中,您可以使用带有 /profile=PROFILE_NAME 的命令指定要更新的配置集。

  • 添加缓存容器。

    /subsystem=infinispan/cache-container=CACHE_CONTAINER:add
  • 添加复制缓存。

    /subsystem=infinispan/cache-container=CACHE_CONTAINER/replicated-cache=CACHE:add(mode=MODE)
  • 设置缓存容器的默认缓存。

    /subsystem=infinispan/cache-container=CACHE_CONTAINER:write-attribute(name=default-cache,value=CACHE)
  • 配置复制缓存的批处理。

    /subsystem=infinispan/cache-container=CACHE_CONTAINER/replicated-cache=CACHE/component=transaction:write-attribute(name=mode,value=BATCH)

22.3.3. 集群模式

在使用 Infinispan 的 JBoss EAP 中有两种方式配置集群,而您的应用程序需要使用哪种方式取决于您的具体需要。每种模式都会在可用性、可靠性和可扩展性间进行相应的协调。在选择一个集群模式前,您需要决定在网络中哪些功能是最重要的,并对这些要求进行平衡。

缓存模式
复制模式(Replicated)
复制模式会自动检测并在集群中添加新实例。对这些实例所做的改变会被复制到集群中的所有节点上。复制模式通常适合于一个小的集群,因为不需要在网络间复制太多信息。Infinispan 可以被配置为使用 UDP 多播,它在一定程度上可以减缓网络堵塞问题。
分布模式(Distributed)

分布模式允许 Infinispan 对集群进行线性扩展。分布模式使用一个一致哈希算法来决定一个新节点应该放置在集群中的什么地方。需要保存的信息副本(所有者)的数量是可以配置的。需要保存的副本数量、数据保持有效的时间,以及性能间会有相互折衷。保持的副本越多,对性能的影响就越大,但可以减少在服务器出现故障时丢失数据的可能性。这个哈希算法还可以在不进行多播或对元数据进行排序的情况下定位相关的数据,从而达到减少网络流量的效果。

当集群的节点数量超过 6 到 8 个时,可以考虑使用分布模式。分布模式中的数据只会被分布到集群中的一部分节点中,而不是分布到所有节点上。

同步和异步复制

复制可用同步或异步模式,选择的模式取决于您的要求和应用程序。

同步复制
当使用同步复制时,用来处理用户请求的线程会被禁止执行,直到复制已成功完成。当复制成功后,会向客户端发送一个反馈信息,客户端只有在接收到这个响应后才会释放线程。因此同步复制需要从集群中的每个节点上获得响应信息,所以它对网络流量会有影响。但是,它也有自己的优点 ,它可以保证所有的改变都应用到集群中的所有节点上。
异步复制
复制时,Infinispan 使用一个线程池在后台处理复制操作。发送方不需要等待集群中其它节点的响应。但是,在前一个复制完成前,同一个会话的读缓存操作会被禁用,这可以保证正在处理中的数据不被读取。复制操作会基于时间被触发,或基于队列的长度触发。如果复制失败,相关信息会写入日志,而不会实时进行通知。

22.3.3.1. 配置缓存模式

您可以用管理 CLI 修改默认的缓存。

注意

本节介绍了配置 web 会话缓存的信息,这个缓存在默认情况下被配置为分配模式。这里所使用的步骤和管理 CLI 命令可以被修改来应用到其它缓存容器中。

修改复制缓存模式

默认 JBoss EAP 7 的 web 会话缓存配置不包括一个 repl 复制的缓存。这个缓存需要被首先添加。

注意

以下是一个针对独立服务器的管理 CLI 命令。如果运行在一个受管域中,在 /subsystem=jgroups 命令中使用 /profile=PROFILE_NAME 指定要更新的配置集。

  1. 添加 repl 复制缓存。

    /subsystem=infinispan/cache-container=web/replicated-cache=repl:add(mode=ASYNC)
    /subsystem=infinispan/cache-container=web/replicated-cache=repl/component=transaction:write-attribute(name=mode,value=BATCH)
    /subsystem=infinispan/cache-container=web/replicated-cache=repl/component=locking:write-attribute(name=isolation, value=REPEATABLE_READ)
    /subsystem=infinispan/cache-container=web/replicated-cache=repl/store=file:add
  2. 修改默认缓存为 repl 复制缓存。

    /subsystem=infinispan/cache-container=web:write-attribute(name=default-cache,value=repl)
  3. 重新加载服务器。

    重新载入
修改为分布式缓存模式

JBoss EAP 7 对 web 会话缓存的默认配置已经包括了一个 dist 分布的缓存。

注意

以下是一个针对独立服务器的管理 CLI 命令。如果运行在一个受管域中,在 /subsystem=jgroups 命令中使用 /profile=PROFILE_NAME 指定要更新的配置集。

  1. 修改默认缓存为 dist 分布式缓存。

    /subsystem=infinispan/cache-container=web:write-attribute(name=default-cache,value=dist)
  2. 设置分布式缓存的所有者。下列命令设置了5 个所有者。默认值是 2

    /subsystem=infinispan/cache-container=web/distributed-cache=dist/:write-attribute(name=owners,value=5)
  3. 重新加载服务器。

    重新载入

22.3.3.2. 缓存策略性能

当使用 SYNC 缓存策略时,复制的代价可以被方便地评估。因为请求只有在复制完成后才可以完成,因此可以直接看到请求响应时间。

虽然从表面上看,ASYNC 缓存策略的响应时间会比 SYNC 缓存策略的响应时间要快,但这只在特定条件下才是正确的。ASYNC 缓存策略不容易被评估,但如果不同请求的间隔足够长(缓存操作可以在这个间隔内完成),这个策略的性能会比 SYNC 策略的性能要高。这是因为,复制的成本不会在响应时间中马上显现出来。

如果对同一个会话的两个请求的间隔时间太短,前一个请求所造成的复制成本会显现到后一个请求中,因为后一个请求需要等待前一个请求所造成的复制完成后才可以被处理。当一个请求接收到响应信息后马上就发送下一个请求,ASYNC 缓存策略的性能就会比 SYNC 的缓存性能差。因此,只有在对同一个会话的不同请求间有一定的间隔时间(间隔阈值)时,ASYNC 缓存策略的性能才会比 SYNC 缓存策略的性能好。在实际的环境中,对同一会话的不同请求间通常都会有一定的间隔时间,这个间隔时间一般都会有几秒钟或更长。在这种情况下,把 ASYNC 缓存策略作为默认设置是合理的,它可以提供更快的响应时间。

22.3.4. 配置 Infinispan 线程池

infinispan 子系统包括 async-operationsexpirationlistenerpersistenceremote-commandstate-transfertransport 线程池。可以为任何 Infinispan 缓存容器配置这些池。

下表列出了您可以为 infinispan子系统中的每个线程池配置的属性和默认值。

线程池的名称keepalive-timemax-threadsmin-threadsqueue-length

async-operations

60000L

25

25

1000

expiration

60000L

1

N/A

N/A

listener

60000L

1

1

100000

persistence

60000L

4

1

0

remote-command

60000L

200

1

0

state-transfer

60000L

60

1

0

transport

60000L

25

25

100000

使用下列管理 CLI 命令来配置 Infinispan 线程池。

/subsystem=infinispan/cache-container=CACHE_CONTAINER_NAME/thread-pool=THREAD_POOL_NAME:write-attribute(name=ATTRIBUTE_NAME, value=ATTRIBUTE_VALUE)

下面的管理 CLI 命令示例在 server 缓存容器的 persistence 线程池中把 max-threads 的值设为 10

/subsystem=infinispan/cache-container=server/thread-pool=persistence:write-attribute(name="max-threads", value="10")

22.3.5. Infinispan 统计

可以启用对 Infinispan 缓存和缓存容器的统计功能来进行监控。因为性能的原因,收集统计数据的功能在默认情况下没有被启用。

统计数据收集功能可以针对每个缓存容器、缓存或缓存容器及缓存启动。缓存容器的统计数据收集功能设置会被容器中的缓存继承,而对具体缓存的设置会覆盖从相应缓存容器中继承的设置。

22.3.5.1. 启用 Infinispan 统计

警告

启用 Infinispan 统计功能可能会对 infinispan 子系统的性能产生影响。请只在需要时启用统计功能。

您可以使用管理控制台或管理 CLI 来启用或禁用收集 Infinispan 统计数据的功能。在管理控制台中,从 Configuration 标签页中进入 Infinispan 子系统,选择相关的缓存或缓存容器,编辑 Statistics enabled 属性。使用以下管理 CLI 命令也可以启用统计功能。

为一个缓存容器启用统计数据收集功能。服务器需要被重新加载。

/subsystem=infinispan/cache-container=CACHE_CONTAINER:write-attribute(name=statistics-enabled,value=true)

为一个缓存启用统计数据收集功能。服务器需要被重新加载。

/subsystem=infinispan/cache-container=CACHE_CONTAINER/CACHE_TYPE=CACHE:write-attribute(name=statistics-enabled,value=true)
注意

您可以使用以下命令来取消定义一个缓存的 statistics-enabled 属性,这个缓存会继承它的缓存容器的 statistics-enabled 属性。

/subsystem=infinispan/cache-container=CACHE_CONTAINER/CACHE_TYPE=CACHE:undefine-attribute(name=statistics-enabled)

22.3.6. Infinispan 分区处理

Infinispan 集群是由一组节点组成的、用来存储数据的环境。为了防止在出现多个节点故障时不会丢失数据,Infinispan 会把相同数据复制到多个节点。使用 owners 属性可以配置数据冗余的级别。只要出现问题的节点数量少于配置的数量,Infinispan 就会具有有效的数据。

但是,当集群中的太多节点出现问题时,就可以会造成灾难性的情况发生。

裂脑

把集群分裂为两个或多个分区或子集群,每个分区都独立操作。在这种情况下,在不同分区中读或写的客户端就会使用同一个缓存项的不同版本,这对于许多应用程序来讲都会是问题。

注意

可以使用一些技术来缓解裂脑发生的可能性,如网络冗余,或 IP 绑定。但是,这只会减少可能发生问题的时间窗口。

多个节点相继崩溃
如果多个节点(特别是所有者)在非常短的时间内相继崩溃,Infinispan 将不会有足够时间在不同的崩溃间适当再平衡它们的状态,从而导致部分的数据丢失。

我们所要实现的目标是,尽量避免当出现裂脑或在短时间内出现多个节点崩溃时,为用户提供不正确数据的情况。

22.3.6.1. 裂脑

对于裂脑的情况,每个网络分区都会安装自己的 JGroups 视图,其中会删除其它分区中的节点。我们没有一个直接的方式来决定集群已被分隔为两个或多个分区,因为分区彼此间不知道其它分区的存在。但是,当一个或多个节点从 JGroups 集群中消失而没有发送明确的离开信息时。我们就认为集群已被分隔。

当分区处理被禁用时,每个这样的分区都会以一个独立集群的形式继续工作。每个分区可能只会看到数据的一部分,并在分区中写有冲突的数据。

当分区处理启动时,在发现分隔情况时每个分区不会马上开始再平衡操作,而是首先检查是否应该进入降级模式:

  • 当最少一个段已丢失了它的全部所有者时,就意味着从最后一次再平衡结束后,所指定数量的所有者已离开,分区进入降级模式。
  • 如果分区不包括最后稳定拓扑中的大多数节点(节点数量除以 2,结果取整数,再加 1),分区也会进入降级模式。
  • 其它所有情况,分区继续工作并开始一个再平衡操作。

当再平衡操作结束,协调程序决定不再需要另外一个再平衡操作时,稳定拓扑被更新。这些规则确保了,最起码有一个分区处于可用模式,其它分区变为降级模式。

当一个分区处于降级模式,则只能访问完全拥有的关键字:

  • 对在节点上有所有副本的项的请求(读请求和写请求)可以正确处理。
  • 对完全或部分由消失节点所拥有的项进行的请求会被拒绝(返回一个 AvailabilityException)。

这可以保证,分区不会为相同的项写不同的值(缓存不统一)。另外,一个分区也不会读已在其它分区被更新的关键字(过期数据)。

注意

只要两个分区不进行合并,它们就可以单独启动,并可以读和写不统一的数据。以后,我们可能会允许使用自定义的可用性策略(如检查一个特定节点是集群的一部分,或检查一个外部机器可以被访问)。

22.3.6.2. 配置分区处理

当前,分区处理在默认情况下被禁用。使用以下管理 CLI 命令来启用分区处理功能:

/subsystem=infinispan/cache-container=web/distributed-cache=dist/component=partition-handling:write-attribute(name=enabled, value=true)

22.3.7. 外部化 HTTP 会话到 JBoss Data Grid

注意

您需要 Red Hat JBoss Data Grid 订阅才可以使用这个功能。

Red Hat JBoss Data Grid 可以被用来作为 JBoss EAP 中特定应用程序(如 HTTP 会话)的外部缓存容器。这可以在独立于应用程序的情况下扩展数据层,并允许处于不同域中的不同 JBoss EAP 集群从相同的 JBoss Data Grid 集群中访问数据。另外,其它应用程序也可以和 Red Hat JBoss Data Grid 提供的缓存有接口。

以下示例显示了如何外部化 HTTP 会话。它适用于独立的 JBoss EAP 实例,也适用于受管域。但是,在一个受管域中,每个服务器组都需要配置一个唯一的远程缓存。当多个服务器组都可以利用同一个 Red Hat JBoss Data Grid 集群时,相应的远程缓存对于 JBoss EAP 服务器组将会是唯一的。

注意

对于每个发布的应用程序,需要创建一个全新的缓存。它可以在一个已存在的缓存容器(如 web)中创建。

外部化 HTTP 会话:

  1. 通过在 socket-binding-group 中添加网络信息来定义远程 Red Hat JBoss Data Grid 服务器的位置。

    添加远程套接字绑定的示例

    /socket-binding-group=standard-sockets/remote-destination-outbound-socket-binding=remote-jdg-server1:add(host=JDGHostName1, port=11222)
    
    /socket-binding-group=standard-sockets/remote-destination-outbound-socket-binding=remote-jdg-server2:add(host=JDGHostName2, port=11222)

    XML 结果

    <socket-binding-group name="standard-sockets" ... >
      ...
      <outbound-socket-binding name="remote-jdg-server1">
        <remote-destination host="JDGHostName1" port="11222"/>
      </outbound-socket-binding>
      <outbound-socket-binding name="remote-jdg-server2">
        <remote-destination host="JDGHostName2" port="11222"/>
      </outbound-socket-binding>
    </socket-binding-group>

    注意

    每个 Red Hat JBoss Data Grid 服务器都需要一个远程套接字绑定配置。

  2. 确定远程缓存容器已在 JBoss EAP 的 infinispan 子系统中进行了定义。在以下的示例中,remote-store 项的 cache 属性定义了远程 JBoss Data Grid 服务器上的缓存名。

    如果运行在一个受管域中,在这些命令中使用 /profile=PROFILE_NAME 参数。

    添加一个远程缓存容器的示例

    /subsystem=infinispan/cache-container=web/invalidation-cache=jdg:add(mode=SYNC)
    
    /subsystem=infinispan/cache-container=web/invalidation-cache=jdg/component=locking:write-attribute(name=isolation,value=REPEATABLE_READ)
    
    /subsystem=infinispan/cache-container=web/invalidation-cache=jdg/component=transaction:write-attribute(name=mode,value=BATCH)
    
    /subsystem=infinispan/cache-container=web/invalidation-cache=jdg/store=remote:add(remote-servers=["remote-jdg-server1","remote-jdg-server2"], cache=default, socket-timeout=60000, passivation=false, purge=false, shared=true)

    XML 结果

    <subsystem xmlns="urn:jboss:domain:infinispan:4.0">
      ...
      <cache-container name="web" default-cache="dist" module="org.wildfly.clustering.web.infinispan" statistics-enabled="true">
        <transport lock-timeout="60000"/>
        <invalidation-cache name="jdg" mode="SYNC">
          <locking isolation="REPEATABLE_READ"/>
          <transaction mode="BATCH"/>
          <remote-store cache="default" socket-timeout="60000" remote-servers="remote-jdg-server1 remote-jdg-server2" passivation="false" purge="false" shared="true"/>
        </invalidation-cache>
        ...
      </cache-container>
    </subsystem>

  3. 在应用程序的 jboss-web.xml 中添加缓存信息。在以下示例中,web 是缓存容器的名称;jdg 是在这个容器中的相应缓存的名称。

    jboss-web.xml 文件示例

    <?xml version="1.0" encoding="UTF-8"?>
    <jboss-web xmlns="http://www.jboss.com/xml/ns/javaee"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://www.jboss.com/xml/ns/javaee http://www.jboss.org/j2ee/schema/jboss-web_10_0.xsd"
               version="10.0">
        <replication-config>
            <replication-granularity>SESSION</replication-granularity>
            <cache-name>web.jdg</cache-name>
        </replication-config>
    </jboss-web>

22.4. 配置 JBoss EAP 作为一个前端负载均衡器

您可以把 JBoss EAP 和 undertow 子系统配置为一个前端的负载均衡器,使用它来代理到后端 JBoss EAP 服务器的请求。因为 Undertow 使用异步 IO,所以用来负责连接的 IO 线程是唯一参与到请求处理中的线程。这个线程还被用来进行到后端服务器的连接。

您可以使用以下协议:

  • 使用明文的 HTTP(http),支持 HTTP/1 和 HTTP/2(h2c

    注意

    HTTP/2 只作为技术预览被提供。

  • 安全的 HTTP(https),支持 HTTP/1 和 HTTP/2(h2

    注意

    HTTP/2 只作为技术预览被提供。

  • AJP(ajp

您可以定义一个静态负载均衡器并在配置中指定后端主机;或使用 mod_cluster 前端来动态更新主机。

22.4.1. 配置 Undertow 作为一个使用 mod_cluster 的负载均衡器

您可以使用内建的 mod_cluster 前端负载均衡器来进行负载均衡。

这个过程假设,您运行在一个受管域中,并已有以下配置:

  • 将充当负载平衡器的 JBoss EAP 服务器。

    • 这个服务器使用了绑定到 standard-sockets 套接字绑定组的 default 配置集。
  • 两个将充当后台服务器的 JBoss EAP 服务器。

    • 这些服务器在集群中运行,并适用绑定了 ha-sockets 套接字绑定组的 ha 配置集。
  • 发布的应用程序在后端服务器中部署了负载均衡功能。
配置 mod_cluster 前端负载平衡器

以下步骤在一个受管域中加载负载均衡服务器,但可以修改后应用于独立服务器。请根据您的环境修改相应的管理 CLI 命令。

  1. 设置 mod_cluster 的 advertise 安全密钥。

    增加广告密钥可以使负载均衡器和服务器在发现阶段进行身份验证。

    使用以下管理 CLI 命令设置 mod_cluster 广告密钥。

    /profile=ha/subsystem=modcluster/mod-cluster-config=configuration:write-attribute(name=advertise-security-key, value=mypassword)
  2. 使用多播地址和 mod_cluster 的端口创建一个套接字绑定。

    您需要为 mod_cluster 创建一个套接字配置用于发现将用于进行负载均衡的服务器,并和这些服务器进行通讯。

    使用以下管理 CLI 命令添加一个 modcluster 套接字绑定来绑定适当的多播地址和配置的端口。

    /socket-binding-group=standard-sockets/socket-binding=modcluster:add(multicast-port=23364, multicast-address=224.0.1.105)
  3. 包括 mod_cluster 负载均衡器。

    在设置了广告安全密钥和套接字绑定后,您就可以为 Undertow 添加 mod_cluster 过滤器来作为负载均衡,而不使用 JBoss EAP。

    使用以下管理 CLI 命令添加 mod_cluster 过滤器。

    /profile=default/subsystem=undertow/configuration=filter/mod-cluster=modcluster:add(management-socket-binding=http, advertise-socket-binding=modcluster, security-key=mypassword)

    使用以下管理 CLI 命令把 mod_cluster 过滤器绑定到默认主机。

    /profile=default/subsystem=undertow/server=default-server/host=default-host/filter-ref=modcluster:add
重要

我们推荐,mod_cluster 使用的管理和广告套接字只在内部网络中可间,而不是一个公共 IP 地址。

作为负载均衡器的 JBoss EAP 服务器现在可以对两个后端 JBoss EAP 服务器进行负载均衡。

22.4.2. 配置 Undertow 作为一个静态负载均衡器

为了配置 Undertow 作为静态负载均衡器,您需要在 undertow 子系统中配置一个代理处理程序(proxy handler)。要在 Undertow 中配置代理处理程序,需要在作为静态负载均衡器的 JBoss EAP 实例上进行以下操作:

  1. 添加一个反向代理处理程序
  2. 为每个远程主机定义外向的套接字绑定
  3. 把每个远程主机添加到反向代理处理程序
  4. 添加反向代理位置

以下示例展示了如何配置一个 JBoss EAP 实例作为一个静态负载均衡器。JBoss EAP 实例位于 lb.example.com,并会在服务器 server1.example.comserver2.example.com 间进行负载均衡。负载均衡器会把代理反向到 /app,并使用 AJP 协议。

  1. 添加反向代理处理程序:

    /subsystem=undertow/configuration=handler/reverse-proxy=my-handler:add
  2. 为每个远程主机定义外向的套接字绑定:

    /socket-binding-group=standard-sockets/remote-destination-outbound-socket-binding=remote-host1/:add(host=server1.example.com, port=8009)
    
    /socket-binding-group=standard-sockets/remote-destination-outbound-socket-binding=remote-host2/:add(host=server2.example.com, port=8009)
  3. 把每个远程主机添加到反向代理处理程序:

    /subsystem=undertow/configuration=handler/reverse-proxy=my-handler/host=host1:add(outbound-socket-binding=remote-host1, scheme=ajp, instance-id=myroute, path=/test)
    
    /subsystem=undertow/configuration=handler/reverse-proxy=my-handler/host=host2:add(outbound-socket-binding=remote-host2, scheme=ajp, instance-id=myroute, path=/test)
  4. 添加反向代理的位置:

    /subsystem=undertow/server=default-server/host=default-host/location=\/app:add(handler=my-handler)

当访问 lb.example.com:8080/app 时,您将可以看到内容是通过 server1.example.comserver2.example.com 进行代理的。

22.5. 使用一个外部 Web 服务器作为一个代理服务器

根据外部 web 服务器的配置,JBoss EAP 可以接受来自于使用 HTTP、HTTPS 或 AJP 协议的外部 web 服务器的请求。

如需了解每个 web 服务器所支持的 HTTP 连接器的详细信息,请参阅 HTTP 连接器概述。在决定使用什么 web 服务器和 HTTP 连接器后,请参阅相关的章节获得如何配置这些连接器的信息:

如需了解支持的 HTTP 连接器配置的最新信息,请参阅 JBoss EAP supported configurations

您还需要确定,JBoss EAP 已被配置为可以接收外部 web 服务器的请求

22.5.1. HTTP 连接器概述

JBoss EAP 可以使用外部 web 服务器(如 Apache HTTP Server、Microsoft IIS 和 Oracle iPlanet)中内建的、负载均衡和集群机制,或通过 Undertow 实现这些功能。JBoss EAP 使用一个连接器(connector)来和 web 服务器进行通讯。这些连接器在 JBoss EAP 的 undertow 子系统中进行配置。

web 服务器包括用来控制把 HTTP 请求路由到 JBoss EAP 节点的软件模块。这些模块中的每个模块的工作方式和配置方法都会不同。它们会被配置来在多个 JBoss EAP 节点间进行负载均衡;或配置来在服务器出现问题时,把工作负载移到其它服务器上;或配置为实现以上两种功能。

JBoss EAP 支持不同的连接器,您需要根据您所使用的 web 服务器,以及所需功能进行选择。下表包括了 JBoss EAP 支持的 HTTP 连接器的配置及功能比较信息。

注意

如果需要使用 JBoss EAP 7 作为一个多平台的负载均衡器,请参阅使用 mod_cluster 配置 Undertow 作为一个负载均衡器

如需了解支持的 HTTP 连接器配置的最新信息,请参阅 JBoss EAP supported configurations

表 22.1. HTTP 连接器支持的配置

连接器Web Server支持的操作系统支持的协议

mod_cluster

Red Hat JBoss Core Services Apache HTTP Server、Red Hat JBoss Web Server Apache HTTP Server

Red Hat Enterprise Linux、Microsoft Windows Server、Oracle Solaris

HTTP, HTTPS, AJP

mod_jk

Red Hat JBoss Core Services Apache HTTP Server、Red Hat JBoss Web Server Apache HTTP Server

Red Hat Enterprise Linux、Microsoft Windows Server、Oracle Solaris

AJP

mod_proxy

Red Hat JBoss Core Services Apache HTTP Server、Red Hat JBoss Web Server Apache HTTP Server

Red Hat Enterprise Linux、Microsoft Windows Server、Oracle Solaris

HTTP, HTTPS, AJP

ISAPI connector

Microsoft IIS

Microsoft Windows Server

AJP

NSAPI connector

Oracle iPlanet Web Server

Oracle Solaris

AJP

表 22.2. HTTP 连接器功能

连接器支持粘性会话(Sticky Session)根据部署状态进行调整

mod_cluster

是。检测应用程序的部署或卸载,根据应用程序是否在此服务器上部署来动态决定,是否把客户端请求发送到此服务器。

mod_jk

否。无论应用程序是什么状态,只要容器可用,就把客户端请求发送到此容器。

mod_proxy

否。无论应用程序是什么状态,只要容器可用,就把客户端请求发送到此容器。

ISAPI connector

否。无论应用程序是什么状态,只要容器可用,就把客户端请求发送到此容器。

NSAPI connector

否。无论应用程序是什么状态,只要容器可用,就把客户端请求发送到此容器。

22.5.2. Apache HTTP Server

一个独立的 Apache HTTP Server 现在可以使用 Red Hat JBoss Core Services 进行单独下载。这简化了安装和配置的过程,并使更新过程更统一。

22.5.2.1. 安装 Apache HTTP Server

如需了解安装 Apache HTTP Server 的信息,请参阅 JBoss Core Services Apache HTTP Server Installation Guide

22.5.3. 接受外部 web 服务器的请求

当配置了正确的协议 handler(如 AJP、HTTP 或 HTTPS)后,JBoss EAP 不需要特殊的配置就可以开始接受一个代理服务器的请求。

如果代理服务器使用 mod_jk、mod_proxy、ISAPI 或 NSAPI,它会把请求发送到 JBoss EAP,JBoss EAP 将会进行响应。对于 mod_cluster,则需要配置网络来允许 JBoss EAP 发送信息(如当前的负载、应用程序生命周期事件、健康状态)到代理服务器,代理服务器会根据这些信息决定把请求发送到什么地方。如需了解更多配置 mod_cluster 代理服务器的信息,请参阅 mod_cluster HTTP 连接器

更新 JBoss EAP 配置

使用您实际需要的配置替换以下过程中使用的协议和端口。

  1. 配置 Undertow 的 instance-id 属性。

    外部 web 服务器在它的连接器配置中使用 instance-id 来指代 JBoss EAP 实例。使用以下管理 CLI 命令在 Undertow 中配置 instance-id 属性。

    /subsystem=undertow:write-attribute(name=instance-id,value=node1)

    在上面的示例中,外部 web 服务器使用 node1 代表当前的 JBoss EAP 实例。

  2. 为 Undertow 添加所需的 listener。

    为了使外部服务器可以连接到 JBoss EAP,Undertow 需要一个 listener。每个协议都需要自己的 listener,它会和一个套接字绑定相关联。

    注意

    取决于您需要的协议和端口配置,这一步可能并不需要。HTTP listener 在所有默认 JBoss EAP 配置中都进行了配置;如果使用 hafull-ha 配置集,则 AJP listener 会被配置。

    查看默认服务器配置可以知道所需的 listener 是否已被配置:

    /subsystem=undertow/server=default-server:read-resource

    为 Undertow 添加一个 listener 需要有一个套接字绑定。套接字绑定被添加到服务器或服务器组所使用的套接字绑定组中。以下管理 CLI 命令把一个 ajp 套接字绑定(绑定端口 8009)添加到 standard-sockets 套接字绑定组中。

    /socket-binding-group=standard-sockets/socket-binding=ajp:add(port=8009)

    以下管理 CLI 命令使用 ajp 套接字绑定为 Undertow 添加了一个 ajp listener。

    /subsystem=undertow/server=default-server/ajp-listener=ajp:add(socket-binding=ajp)

22.6. mod_cluster HTTP 连接器

mod_cluster 连接器是一个基于 Apache HTTP Server 的负载平衡器。它使用一个通讯频道来转发来自 Apache HTTP Server 的请求至一系列应用服务器节点中的一个。

mod_cluster 连接器和其它连接器相比有一些优势。

  • mod_cluster 管理协议(MCMP)是在 JBoss EAP 服务和启用了 mod_cluster 模块的 Apache HTTP Server 间的一个额外的连接。JBoss EAP 服务器使用它来通过一组自定义的 HTTP 方法把传输服务器方的负载均衡因子和生命周期事件传输回 Apache HTTP Server。
  • 动态配置带有 mod_cluster 的 Apache HTTP Server 将可以在不需要手工配置的情况下,使 JBoss EAP 服务器可以加入到负载均衡协议中。
  • JBoss EAP 会进行负载均衡因子计算,而不是依赖于带有 mod_cluster 的 Apache HTTP Server。因此,它的负载均衡指标数据比其它连接器的数据更准确。
  • mod_cluster 连接器提供了细颗粒的应用程序生命周期控制。每个 JBoss EAP 服务器都会把 web 应用程序上下文生命周期事件转发到 Apache HTTP 服务器,通知它为特定上下文开始或停止路由请求。这可以防止最终用户因为不可用的资源而接收到错误信息。
  • 可以使用 AJP、HTTP 或 HTTPS 传输。

如需了解更多与 modcluster 子系统特定配置选项相关的信息,请参阅 ModCluster 子系统属性

22.6.1. 在 Apache HTTP Server 中配置 mod_cluster

在安装 JBoss Core Services Apache HTTP Server 或使用 JBoss Web Server 时,mod_proxy 模块已被包含,并在默认情况下被加载。

根据以下信息配置您的 mod_cluster 模块。

注意

红帽客户也可以使用红帽客户门户提供的 Load Balancer 配置工具快速生成用于 mod_cluster 和其他连接器的优化的配置模板。请注意,您必须先登录才能访问这个工具。

配置 mod_cluster

Apache HTTP Server 已经包括了一个 mod_cluster 配置文件(mod_cluster.conf),它会加载 mod_cluster 模块并提供基本的配置。这个文件中的 IP 地址、端口和其它设置都可以根据需要进行修改。

# mod_proxy_balancer should be disabled when mod_cluster is used
LoadModule proxy_cluster_module modules/mod_proxy_cluster.so
LoadModule cluster_slotmem_module modules/mod_cluster_slotmem.so
LoadModule manager_module modules/mod_manager.so
LoadModule advertise_module modules/mod_advertise.so

MemManagerFile cache/mod_cluster

<IfModule manager_module>
  Listen 6666
  <VirtualHost *:6666>
    <Directory />
      Require ip 127.0.0.1
    </Directory>
    ServerAdvertise on
    EnableMCPMReceive
    <Location /mod_cluster_manager>
      SetHandler mod_cluster-manager
      Require ip 127.0.0.1
   </Location>
  </VirtualHost>
</IfModule>

Apache HTTP Server 服务器可以被配置为一个负载均衡器,并和 JBoss EAP 上运行的 modcluster 子系统一起工作。您需要配置一个 mod_cluster worker 节点才可以使 JBoss EAP 支持 mod_cluster。

如果您需要为 mod_cluster 禁用广告,并配置一个静态代理列表来替代它,请参阅为 mod_cluster 禁用广告。如需了解在 Apache HTTP Server 中可用的 mod_cluster 配置选项,请参阅 Apache HTTP Server mod_cluster Directives

如需了解更多与配置 mod_cluster 相关的信息,请参阅 JBoss Web Server HTTP Connectors and Load Balancing Guide 中的 Configure Load Balancing Using Apache HTTP Server and mod_cluster 一节。

22.6.2. 为 mod_cluster 禁用广告

在默认情况下,modcluster 子系统的负载均衡器使用多播 UDP 来向后台的 worker 广告它的可用性。您可用使用以下操作来禁用广告功能,并使用一个代理列表来替代它。

注意

以下操作中使用的管理 CLI 命令假设您在一个受管域中使用 full-ha 配置集。如果您没有使用 full-ha 配置集,则需要在命令中使用实际的配置集名。如果您运行一个独立的服务器,完全删除 /profile=full-ha

  1. 修改 Apache HTTP Server 配置。

    编辑 httpd.conf Apache HTTP Server 配置文件。使用 EnableMCPMReceive 项对监听 MCPM 请求的虚拟主机进行以下更新。

    1. 添加一个项来禁用服务器广告。

      ServerAdvertise 项设置为 Off 来禁用服务器广告。

      ServerAdvertise Off
    2. 禁用广告的频率。

      如果配置指定了 AdvertiseFrequency 参数,使用 # 把它注释掉。

      # AdvertiseFrequency 5
    3. 启用接收 MCPM 信息的功能。

      确认存在 EnableMCPMReceive 项,这将允许 web 服务器从 worker 节点接收 MCPM 信息。

      EnableMCPMReceive
  2. 在 JBoss EAP modcluster 子系统中禁用广告。

    使用以下管理 CLI 命令禁用广告。

    /profile=full-ha/subsystem=modcluster/mod-cluster-config=configuration/:write-attribute(name=advertise,value=false)
    重要

    继续以下步骤来提供代理列表。如果代理列表为空,广告将不会被禁用。

  3. 在 JBoss EAP modcluster 子系统中提供代理列表。

    当广告被禁用时,modcluster 子系统不会自动发现代理,因此需要提供代理列表。

    首先,在适当的套接字绑定组中定义外向的套接字绑定。

    /socket-binding-group=full-ha-sockets/remote-destination-outbound-socket-binding=proxy1:add(host=10.33.144.3,port=6666)
    /socket-binding-group=full-ha-sockets/remote-destination-outbound-socket-binding=proxy2:add(host=10.33.144.1,port=6666)

    接下来,为 mod_cluster 配置添加代理。

    /profile=full-ha/subsystem=modcluster/mod-cluster-config=configuration:list-add(name=proxies,value=proxy1)
    /profile=full-ha/subsystem=modcluster/mod-cluster-config=configuration:list-add(name=proxies,value=proxy2)

Apache HTTP Server 均衡器将不再向 worker 节点广告它的存在,UDP 多播将不再被使用。

22.6.3. 配置一个 mod_cluster Worker 节点

mod_cluster worker 节点包括一个 JBoss EAP 服务器。这个服务器可以是一个独立的服务器,也可以是一个受管域中的一个服务器组中的一部分。一个独立的进程会在 JBoss EAP 中运行,它用来管理集群中的所有 worker 节点。它被称为主节点(master)。

在一个受管域中的 worker 节点会在服务器组的范围内共享一个相同的配置。作为独立服务器运行的 worker 节点需要单独配置。配置的步骤是相同的。

  • 一个独立的服务器需要在启动时带有 standalone-hastandalone-full-ha 配置集。
  • 受管域中的服务器组需要使用 hafull-ha 配置集,ha-socketsfull-ha-sockets 套接字绑定组。JBoss EAP 带有一个名为 other-server-group 的服务器组,它启用了集群功能,并满足以上要求。
配置一个 worker 节点

以下操作中使用的管理 CLI 命令假设您使用了一个带有 full-ha 配置集的受管域。如果您运行一个独立的服务器,把命令中的 /profile=full-ha 部分删除。

  1. 配置网络接口

    在默认情况下,网络接口都被默认设置为 127.0.0.1。用来运行一个独立服务器或一个服务器组中的一个或多个服务器的主机都需要配置为使用它的公共 IP 地址,从而使其它服务器可以看到它。

    根据您的环境,使用以下管理 CLI 命令为 managementpublicunsecure 接口修改外部 IP 地址。使用主机的实际外部 IP 地址替换命令中的 EXTERNAL_IP_ADDRESS

    /interface=management:write-attribute(name=inet-address,value="${jboss.bind.address.management:EXTERNAL_IP_ADDRESS}")
    /interface=public:write-attribute(name=inet-address,value="${jboss.bind.address.public:EXTERNAL_IP_ADDRESS}")
    /interface=unsecure:write-attribute(name=inet-address,value="${jboss.bind.address.unsecure:EXTERNAL_IP_ADDRESS}")

    重新加载服务器。

    重新载入
  2. 配置主机名。

    为一个受管域中的每个主机设置一个唯一的主机名。这个名称在所有从节点中需要是唯一的,从主机会使用它在集群中进行指代。因此,把您所使用的名称做一个记录。

    1. 启动 JBoss EAP 从主机,使用适当的 host.xml 配置文件。

      $ EAP_HOME/bin/domain.sh --host-config=host-slave.xml
    2. 使用以下管理 CLI 命令设置一个唯一的主机名。这个示例中使用 slave1 作为新的主机名。

      /host=EXISTING_HOST_NAME:write-attribute(name=name,value=slave1)

      如需了解更多与配置一个主机名相关的信息,请参阅配置主机名

  3. 配置每个主机来连接到域控制器。

    注意

    独立服务器不需要这个步骤。

    对于新创建的、需要加入到一个受管域的主机,需要把本地项删除,并添加指向域控制器的远程项主机属性。

    1. 启动 JBoss EAP 从主机,使用适当的 host.xml 配置文件。

      $ EAP_HOME/bin/domain.sh --host-config=host-slave.xml
    2. 使用以下管理 CLI 命令配置域控制器设置。

      /host=SLAVE_HOST_NAME:write-remote-domain-controller(host=DOMAIN_CONTROLLER_IP_ADDRESS,port=${jboss.domain.master.port:9999},security-realm="ManagementRealm")

      这会修改 host-slave.xml 文件的 XML:

      <domain-controller>
          <remote host="DOMAIN_CONTROLLER_IP_ADDRESS" port="${jboss.domain.master.port:9999}" security-realm="ManagementRealm"/>
      </domain-controller>

      如需了解更多相关信息,请参阅连接到域控制器

  4. 为每个从主机配置身份验证。

    每个从服务器都需要在域控制器或独立主服务器的 ManagementRealm 中创建一个用户名和密码。在域控制器或独立主服务器上为每个主机运行 EAP_HOME/bin/add-user.sh 命令。为每个主机添加一个管理用户,它的用户名需要和从服务器中的主机名相匹配。

    对最后一个问题("Is this new user going to be used for one AS process to connect to another AS process?")回答 yes,您会被提供一个秘密的值。

    add-user 脚本输出示例(已被剪辑)

    $ EAP_HOME/bin/add-user.sh
    
    What type of user do you wish to add?
     a) Management User (mgmt-users.properties)
     b) Application User (application-users.properties)
    (a): a
    
    Username : slave1
    Password : changeme
    Re-enter Password : changeme
    What groups do you want this user to belong to? (Please enter a comma separated list, or leave blank for none)[  ]:
    About to add user 'slave1' for realm 'ManagementRealm'
    Is this correct yes/no? yes
    Is this new user going to be used for one AS process to connect to another AS process?
    e.g. for a slave host controller connecting to the master or for a Remoting connection for server to server EJB calls.
    yes/no? yes
    To represent the user add the following to the server-identities definition <secret value="SECRET_VALUE" />

    复制这个输出中的使用 Base64 编码的秘密值(SECRET_VALUE),它可能需要在下一步中使用。

    如需了解更多相关信息,请参阅如何配置服务器安全指南中的为主域控制器添加一个用户一节。

  5. 修改从主机的安全域(security realm)来使用新的用户验证。

    您可以通过在服务器配置中设置秘密的值来指定密码。从 vault 中获得密码,或作为一个系统属性传递密码。

    • 使用管理 CLI 在服务器配置文件中指定 Base64 编码的密码值。

      使用以下管理 CLI 命令指定秘密值。使用前一步中的 add-user 输出中返回的值替换 SECRET_VALUE

      /host=SLAVE_HOST_NAME/core-service=management/security-realm=ManagementRealm/server-identity=secret:add(value="SECRET_VALUE")

      您需要重新加载服务器。--host 参数不适用于独立的服务器。

      reload --host=HOST_NAME

      如需了解更多相关信息,请参阅 JBoss EAP 的如何配置服务器安全指南中的 Configuring the Slave Controllers to Use the Credential 一节。

    • 配置主机来从 vault 获得密码。

      1. 使用 EAP_HOME/bin/vault.sh 脚本产生一个经过掩盖的密码。它会产生一个 VAULT::secret::password::VAULT_SECRET_VALUE 格式的字符串。例如:

        VAULT::secret::password::ODVmYmJjNGMtZDU2ZC00YmNlLWE4ODMtZjQ1NWNmNDU4ZDc1TElORV9CUkVBS3ZhdWx0.
        注意

        在 vault 中创建密码时,需要使用明文,而不是使用 Base64 编码的值。

      2. 使用以下管理 CLI 命令指定秘密值。使用在前一步中创建的已经过掩盖的秘密替换 VAULT_SECRET_VALUE

        /host=master/core-service=management/security-realm=ManagementRealm/server-identity=secret:add(value="${VAULT::secret::password::VAULT_SECRET_VALUE}")

        您需要重新加载服务器。--host 参数不适用于独立的服务器。

        reload --host=HOST_NAME

        如需了解更多相关信息,请参阅 JBoss EAP 的如何配置服务器安全指南中的 Password Vault 一节。

    • 使用一个系统属性指定密码。

      以下示例使用 server.identity.password 作为密码的系统属性名。

      1. 在服务器的配置文件中设置密码的系统属性名。

        使用以下管理 CLI 命令配置安全身份来使用系统属性。

        /host=SLAVE_HOST_NAME/core-service=management/security-realm=ManagementRealm/server-identity=secret:add(value="${server.identity.password}")

        您需要重新加载服务器。--host 参数不适用于独立的服务器。

        reload --host=master
      2. 在启动服务器时为系统属性设置密码。

        您可以使用命令行的一个参数或通过一个属性文件来设置 server.identity.password 系统属性。

        1. 使用一个命令行参数。

          启动服务器并传递 server.identity.password 属性。

          $ EAP_HOME/bin/domain.sh --host-config=host-slave.xml -Dserver.identity.password=changeme
          警告

          密码需要以明文的方式输入,它对运行 ps -ef 命令的任何用户都可见。

        2. 在属性文件中设置属性。

          创建一个属性文件,为它添加相关的“键/值”对。例如:

          server.identity.password=changeme
          警告

          密码以明文的形式存在,并对任何可以访问这个属性文件的用户可见。

          使用命令行参数启动服务器。

          $ EAP_HOME/bin/domain.sh --host-config=host-slave.xml --properties=PATH_TO_PROPERTIES_FILE
  6. 重启服务器

    从服务器将使用它的主机名作为用户名,以及加密的字符串作为密码,和主服务器进行验证。

到此,您的独立服务器或一个受管域中的服务器组中的服务器已被配置为 mod_cluster worker 节点。如果您需要部署一个集群的应用程序,它的会话会被复制到所有集群节点中以用于故障转移,它可以接收从外部 web 器或负载均衡器发来的请求。

22.6.4. 配置 mod_cluster fail_on_status 参数

fail_on_status 参数包括了一个 HTTP 状态代码列表,当集群中的一个 worker 节点返回了其中的状态代码,则代表这个节点出现故障,负载均衡器将会把请求发送到集群中的其它节点上。这个失败的 worker 节点会一直处于一个 NOTOK 状态,直到它向负载均衡器发送了一个 STATUS 信息。

注意

HP 的 HP-UX v11.3 hpws httpd B.2.2.15.15 不支持 fail_on_status 参数,所以它不能使用这个参数。

fail_on_status 参数需要在负载均衡器中的 httpd 配置文件中进行配置。fail_on_status 参数可以指定多个 HTTP 状态代码(以逗号分隔)。下面这个示例为 fail_on_status 设置了 HTTP 状态代码 203204

fail_on_status 配置示例

ProxyPass / balancer://MyBalancer stickysession=JSESSIONID|jsessionid nofailover=on failonstatus=203,204
ProxyPassReverse / balancer://MyBalancer
ProxyPreserveHost on

22.6.5. 迁移集群间的通讯

在用 JBoss EAP 创建新集群后,作为升级过程的一部分,您可以将之前集群的通讯迁移至新的集群。在这个任务里,您将看到,如何在最小断电或下线时间的情况下迁移这些通讯的策略。

  • 新的集群设立(我们将这个集群称为 ClusterNEW)。
  • 冗余的旧的集群设立(我们称这个集群之为 ClusterOLD)。
集群的升级过程 - 负载平衡组
  1. 用预备条件里描述的步骤设立新的集群。
  2. ClusterNEWClusterOLD 里,请确保配置选项 sticky-session 被设置为 true(它默认是 true)。启用这个选项表示对任何集群里的集群节点的所有新的请求都会继续去往各自的集群节点。

    /profile=full-ha/subsystem=modcluster/mod-cluster-config=configuration/:write-attribute(name=sticky-session,value=true)
  3. 设置 load-balancing-groupClusterOLD,假设 ClusterOLD 里的所有集群节点都是 ClusterOLD 负载平衡组里的成员。

    /profile=full-ha/subsystem=modcluster/mod-cluster-config=configuration/:write-attribute(name=load-balancing-group,value=ClusterOLD)
    <subsystem xmlns="urn:jboss:domain:modcluster:2.0">
      <mod-cluster-config load-balancing-group="ClusterOLD" advertise-socket="modcluster" connector="ajp">
        <dynamic-load-provider>
          <load-metric type="cpu"/>
        </dynamic-load-provider>
      </mod-cluster-config>
    </subsystem>
  4. 使用配置一个 mod_cluster Worker 节点里描述的步骤单独添加 ClusterNEW 里的节点至 mod_cluster 配置。此外,按照之前提及的过程并设置负载平衡组为 ClusterNEW

    此时,您可以在 mod_cluster-manager 控制台上看到和下面类似的输出:

                    mod_cluster/<version>
    
        LBGroup ClusterOLD: [Enable Nodes]   [Disable Nodes]   [Stop Nodes]
            Node node-1-jvmroute (ajp://node1.oldcluster.example:8009):
                [Enable Contexts]   [Disable Contexts]   [Stop Contexts]
                Balancer: qacluster, LBGroup: ClusterOLD, Flushpackets: Off, ..., Load: 100
                Virtual Host 1:
                    Contexts:
                        /my-deployed-application-context, Status: ENABLED Request: 0 [Disable]   [Stop]
    
            Node node-2-jvmroute (ajp://node2.oldcluster.example:8009):
                [Enable Contexts]   [Disable Contexts]   [Stop Contexts]
                Balancer: qacluster, LBGroup: ClusterOLD, Flushpackets: Off, ..., Load: 100
                Virtual Host 1:
                    Contexts:
                        /my-deployed-application-context, Status: ENABLED Request: 0 [Disable]   [Stop]
    
    
        LBGroup ClusterNEW: [Enable Nodes]   [Disable Nodes]   [Stop Nodes]
            Node node-3-jvmroute (ajp://node3.newcluster.example:8009):
                [Enable Contexts]   [Disable Contexts]   [Stop Contexts]
                Balancer: qacluster, LBGroup: ClusterNEW, Flushpackets: Off, ..., Load: 100
                Virtual Host 1:
                    Contexts:
                        /my-deployed-application-context, Status: ENABLED Request: 0 [Disable]   [Stop]
    
            Node node-4-jvmroute (ajp://node4.newcluster.example:8009):
                [Enable Contexts]   [Disable Contexts]   [Stop Contexts]
                Balancer: qacluster, LBGroup: ClusterNEW, Flushpackets: Off, ..., Load: 100
                Virtual Host 1:
                    Contexts:
                        /my-deployed-application-context, Status: ENABLED Request: 0 [Disable]   [Stop]
  5. ClusterOLD 组里有旧的活动会话,任何新的会话将在 ClusterOLDCLusterNEW 组里创建。之后,我们希望禁用整个 ClusterOLD 组,这样我们可以关闭它的集群节点而不会在当前活动客户的会话里导致任何错误。

    点击 mod_cluster-manager web 控制台里 LBGroup ClusterOLD 上的 Disable Nodes 链接。

    从此以后,只有属于已建立会话的请求会被路由至 ClusterOLD 负载平衡组的成员。任何新客户的会话将只在 ClusterNEW 组里创建。只要 ClusterOLD 组里没有活动会话,我们就可以安全地删除它的成员。

    注意

    使用 Stop Nodes 将让负载平衡器停止将任何请求立即路由至这个域。这将强制其他负载平衡组的失效切换,如果 ClusterNEWClusterOLD 间没有会话复制,这会导致会话数据丢失。

默认的 Load-Balancing 组

如果当前的 ClusterOLD 设置没有包含任何负载平衡组设置(您可以在 mod_cluster-manager 控制台上查看 LBGroup),您仍可以禁用 ClusterOLD 节点。此时,对每个 ClusterOLD 节点点击 Disable Contexts。这些节点的上下文将被禁用,一旦不存在活动的会话,它们将可以被行删除。新客户的会话将只在启用了上下文的节点上创建,如这个例子的 ClusterNEW 成员。

使用管理 CLI

除了使用 mod_cluster-manager web 控制台,您可以调整管理 CLI 来禁用特定的上下文。下面提及的操作被称作 stop-context,但它让集群节点发送 DISABLE-APP 命令至负载平衡器,这和点击 mod_cluster-manager 控制台上特定上下文的 Disable 链接有一样的效果(请注意虚拟主机别名,如 default-host,已从之前提及的 mod_cluster-manager 控制台输出示例删除)。

除了使用 mod_cluster-manager web 控制台,您可以调整管理 CLI 来禁用特定的上下文。使用的操作被称作 stop-context,但它让集群节点发送 DISABLE-APP 命令至负载平衡器,这和点击 mod_cluster-manager 控制台上特定上下文的 Disable 链接有一样的效果(请注意虚拟主机别名,如 default-host,已从之前提及的 mod_cluster-manager 控制台输出示例删除)。

/profile=full-ha/subsystem=modcluster/:stop-context(context=/my-deployed-application-context, virtualhost=default-host, waittime=50)

要停止特定的上下文,集群节点或整个负载平衡组会强制平衡器停止立即路由任何请求,从而强制失效切换至其他可用的上下文。要禁用特定的上下文,集群节点或整个负载平衡组需要告诉平衡器不应该在这个特定的上下文/节点/负载平衡组上创建新的会话。

22.7. Apache mod_jk HTTP 连接器

Apache mod_jk 是一个 HTTP 连接器,它为特定客户提供了所需的兼容性。

JBoss EAP 可以从 Apache HTTP 代理服务器接受工作负载。代理服务器从 Web 前端接受客户请求并将工作负荷传递给参与的 JBoss EAP 服务器。如果启用了粘性会话,相同的客户请求总会到达相同的 JBoss EAP 服务器,除非服务器是不可用的。

mod_jk 通过 AJP 1.3 协议来通讯。其他协议可以与 mod_clustermod_proxy 一起使用。详情请参考 HTTP 连接器概述

注意

mod_cluster 是一个比 mod_jk 更高级的负载平衡器,它也是我们推荐的 HTTP 连接器。mod_cluster 提供了 mod_jk 的所有功能以及其他功能。不象 JBoss EAP mod_cluster HTTP 连接器,Apache mod_jk HTTP 连接器不知道服务器或服务器组上的部署状态,也无法根据工作负载在发送的地点而进行调整。

详情请参考 Apache mod_jk documentation

22.7.1. 配置 Apache HTTP 服务器里的 mod_jk

在安装 JBoss Core Services Apache HTTP Server 或使用JBoss Web Server 时,mod_jk 模块(mod_jk.so)是已被包含。然而,默认情况下它不会被加载。使用下列步骤来加载和配置 Apache HTTP Server 里的 mod_jk。请注意,这些步骤假设您已进入 Apache HTTP Server 的 httpd/ 目录,这个目根根据平台的不同而不同。更多信息请参考《Apache HTTP Server 安装指南》里的 JBoss Core Services 安装说明。

注意

红帽客户也可以使用客户门户网站上的 Load Balancer 配置工具快速生成用于 mod_jk 和其他连接器的优化的配置模板。请注意,您必须先登录才能访问这个工具。

  1. 配置 mod_jk 模块。

    注意

    conf.d/mod_jk.conf.sample 提供了一个 mod_jk 配置文件示例。您可以使用这个示例而不是创建自己的配置文件,您需要删除它的 .sample 后缀并按需要修改其内容。

    创建一个名为 conf.d/mod_jk.conf 的文件。添加下列配置,请确保根据需要修改相关内容。

    # Load mod_jk module
    # Specify the filename of the mod_jk lib
    LoadModule jk_module modules/mod_jk.so
    
    # Where to find workers.properties
    JkWorkersFile conf.d/workers.properties
    
    # Where to put jk logs
    JkLogFile logs/mod_jk.log
    
    # Set the jk log level [debug/error/info]
    JkLogLevel info
    
    # Select the log format
    JkLogStampFormat  "[%a %b %d %H:%M:%S %Y]"
    
    # JkOptions indicates to send SSK KEY SIZE
    JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories
    
    # JkRequestLogFormat
    JkRequestLogFormat "%w %V %T"
    
    # Mount your applications
    JkMount /application/* loadbalancer
    
    # Add shared memory.
    # This directive is present with 1.2.10 and
    # later versions of mod_jk, and is needed for
    # for load balancing to work properly
    JkShmFile logs/jk.shm
    
    # Add jkstatus for managing runtime data
    <Location /jkstatus/>
        JkMount status
        Require ip 127.0.0.1
    </Location>
    注意

    JkMount 指令指定 Apache HTTP Server 必须转发哪个 URL 至 mod_jk 模块。根据指令的配置,mod_jk 发送接收的 URL 至正确的工作节点。要直接服务静态的内容且只对 Java 应用程序使用负载平衡器,URL 路径必须为 /application/*。要将 mod_jk 用作负载平衡器,请使用 /* 来转发所有的 URL 至 mod_jk。

    除了常用的 mod_jk 配置,这个文件还指定了加载 mod_jk.so 模块,并定义了在哪里找到 workers.properties 文件。

  2. 配置 mod_jk 工作节点。

    注意

    conf.d/workers.properties.sample 提供了一个工作节点配置文件示例。您可以使用这个示例而不是创建自己的配置文件,您需要删除它的 .sample 后缀并按需要修改其内容。

    创建一个名为 conf.d/workers.properties.sample 的文件。添加下列配置,请确保根据需要修改相关内容。

    # Define list of workers that will be used
    # for mapping requests
    worker.list=loadbalancer,status
    
    # Define Node1
    # modify the host as your host IP or DNS name.
    worker.node1.port=8009
    worker.node1.host=node1.mydomain.com
    worker.node1.type=ajp13
    worker.node1.ping_mode=A
    worker.node1.lbfactor=1
    
    # Define Node2
    # modify the host as your host IP or DNS name.
    worker.node2.port=8009
    worker.node2.host=node2.mydomain.com
    worker.node2.type=ajp13
    worker.node2.ping_mode=A
    worker.node2.lbfactor=1
    
    # Load-balancing behavior
    worker.loadbalancer.type=lb
    worker.loadbalancer.balance_workers=node1,node2
    worker.loadbalancer.sticky_session=1
    
    # Status worker for managing load balancer
    worker.status.type=status

    关于 mod_jk workers.properties 文件的语法和其他高级配置选项的细节,请参考 mod_jk 工作节点属性

  3. 您可根据需要指定 JKMountFile 指令。

    除了 mod-jk.conf 里的 JKMount 指令,您还可以指定转发一个包含多个 URL 模式的文件至 mod_jk。

    1. 创建 uriworkermap.properties 文件。

      注意

      conf.d/uriworkermap.properties.sample 提供了一个 URI 工作节点映射配置文件示例。您可以使用这个示例而不是创建自己的配置文件,您需要删除它的 .sample 后缀并按需要修改其内容。

      创建一个名为 conf.d/uriworkermap.properties 的文件。为每个匹配的 URL 模式添加一行,例如:

      # Simple worker configuration file
      /*=loadbalancer
    2. 更新配置使其指向 uriworkermap.properties 文件。

      conf.d/mod_jk.conf 里附加下列内容。

      # Use external file for mount points.
      # It will be checked for updates each 60 seconds.
      # The format of the file is: /url=worker
      # /examples/*=loadbalancer
      JkMountFile conf.d/uriworkermap.properties

关于配置 mod_jk 的更多细节,请参考《JBoss Web Server 的 HTTP 连接器和负载平衡指南》『配置 Apache HTTP Server 加载 mod_jk』章节。

22.7.2. 配置 JBoss EAP 与 mod_jk 通讯

JBoss EAP undertow 子系统需要指定一个 listener 来接受请求并发送回复至外部的 Web 服务器。既然 mod_jk 使用了 AJP 协议,您必须配置 AJP Listener。

如果您在使用其中一个默认的高可用性配置(hafull-ha),那么已经配置了 AJP Listener 。

相关说明请参考接受外部 web 服务器的请求

22.8. Apache mod_proxy HTTP 连接器

Apache mod_proxy 是一个支持 AJP、HTTP 和 HTTPS 协议连接的 HTTP 连接器。您可以在负载平衡或非负载平衡配置里配置 mod_proxy,它支持粘性会话的概念。

mod_proxy 模块要求 JBoss EAP 在 undertow 子系统里配置 HTTP、HTTPS 或 AJP listener,这取决于您计划使用的协议。

注意

mod_cluster 是一个比 mod_proxy 更高级的负载平衡器,它也是我们推荐的 HTTP 连接器。mod_cluster 提供了 mod_proxy 的所有功能以及其他功能。不象 JBoss EAP mod_cluster HTTP 连接器,Apache mod_proxy HTTP 连接器不知道服务器或服务器组上的部署状态,也无法根据工作负载在发送的地点而进行调整。

详情请参考 Apache mod_proxy 文档

22.8.1. 配置 Apache HTTP 里的 mod_proxy

在安装 JBoss Core Services Apache HTTP Server 或使用 JBoss Web Server 时,mod_proxy 模块已被包含,且被默认加载。

请参考下面的内容来配置基本的 load-balancingnon-load-balancing 代理。这些步骤假定您已经进入了 Apache HTTP Server 的 httpd/ 目录,这个目录根据平台的不同而可能不同。更多信息请参考 《Apache HTTP Server 安装指南》里的 JBoss Core Services 安装说明。这些步骤也假定您已经在 JBoss EAP undertow 子系统里配置了必要的 HTTP Listener。

注意

红帽客户也可以使用红帽客户门户网站中的 Load Balancer 配置工具快速生成用于 mod_proxy 和其他连接器的优化的配置模板。请注意,您必须先登录才能访问这个工具。

添加 Non-load-balancing 代理

conf/httpd.conf 文件里,把以下配置(根据您的具体设置替换相关的内容)添加到其他 <VirtualHost> 指令下面。

<VirtualHost *:80>
# Your domain name
ServerName YOUR_DOMAIN_NAME

ProxyPreserveHost On

# The IP and port of JBoss
# These represent the default values, if your httpd is on the same host
# as your JBoss managed domain or server

ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/

# The location of the HTML files, and access control information
DocumentRoot /var/www
<Directory /var/www>
Options -Indexes
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
添加 Load-balancing 代理
注意

默认的 Apache HTTP Server 配置禁用了 mod_proxy_balancer.so 模块,因为它和 mod_cluster 不兼容。为了完成这个任务,您将需要加载这个模块并禁用 mod_cluster 模块。

要将 mod_proxy 作为负载平衡器,并将工作负载发送到多个 JBoss EAP 实例,把以下配置(根据您的具体情况替换其中的 IP 地址)添加到您的 conf/httpd.conf 文件中。

<Proxy balancer://mycluster>

Order deny,allow
Allow from all

# Add each JBoss Enterprise Application Server by IP address and port.
# If the route values are unique like this, one node will not fail over to the other.
BalancerMember http://192.168.1.1:8080 route=node1
BalancerMember http://192.168.1.2:8180 route=node2
</Proxy>

<VirtualHost *:80>
 # Your domain name
 ServerName YOUR_DOMAIN_NAME

 ProxyPreserveHost On
 ProxyPass / balancer://mycluster/

 # The location of the HTML files, and access control information DocumentRoot /var/www
 <Directory /var/www>
  Options -Indexes
  Order allow,deny
  Allow from all
 </Directory>

</VirtualHost>

上面的例子都使用 HTTP 协议进行通讯。您可以通过加载适当的 mod_proxy 模块来使用 AJP 或 HTTPS 协议。详情请参考 Apache mod_proxy 文档

启用粘性会话

粘性会话(Sticky session)表示如果客户请求原本是去往特定的 JBoss EAP 工作节点,那所有将来的请求都送往相同的工作节点,除非它不可用。这一直是我们推荐的行为。

要启用 mod_proxy 的粘性会话,请将 stickysession 参数添加到 ProxyPass 语句里。

ProxyPass / balancer://mycluster stickysession=JSESSIONID

您可以在 ProxyPass 语句里指定其他参数,如 lbmethodnofailover。关于可用参数的更多信息,请参考 Apache mod_proxy 文档

22.8.2. 配置 JBoss EAP 与 mod_proxy 通讯

JBoss EAP undertow 子系统需要指定一个 listener 来接受来自外部 Web 服务器的请求,并向外部 Web 服务器发送回复。根据您所使用的协议,可能还需要配置 Listener。

JBoss EAP 的默认配置里配置了 HTTP Listener。如果您在使用其中一个默认的高可用性配置(hafull-ha),那么已经配置了 AJP Listener 。

相关说明请参考接受外部 web 服务器的请求

22.9. Microsoft ISAPI Connector

Internet Server API (ISAPI) 是用于写入 OLE 服务器扩展的一系列 API 及用于 Web 服务器(如 Microsoft 的 IIS)的过滤器。isapi_redirect.dll 是针对 IIS 调整的 mod_jk 的扩展。isapi_redirect.dll 让您可以将 JBoss EAP 配置为工作节点,而将 IIS 作为负载平衡器。

注意

关于受支持的 Windows Server 和 IIS 的配置,请参考 JBoss EAP 支持的配置

22.9.1. 配置 Microsoft IIS 使用 ISAPI Connector

从红帽客户门户网站下载 ISAPI connector:

  1. 打开浏览器并登录红帽客户门户网站 JBoss Software Downloads 页面
  2. Product 下拉菜单选择 Web Connectors
  3. Version 下拉菜单里选择最新的 JBoss Core Services 版本。
  4. 在列表里找到 Red Hat JBoss Core Services ISAPI Connector,然后点击 Download 链接。
  5. 解压归档并复制 sbin 目录的内容至您的服务器。下面的说明假定这些内容被复制到了 C:\connectors\ 目录。

要用 IIS Manager (IIS 7) 配置 IIS Redirector:

  1. 点击 StartRun 并输入 inetmgr 来打开 IIS 管理者。
  2. 在左侧的树型视图面板里,展开 IIS 7
  3. 双击 ISAPI and CGI Registrations 在新窗口里打开它。
  4. Actions 面板里,点击 AddAdd ISAPI or CGI Restriction 窗口将被打开。
  5. 指定下列值:

    • ISAPI or CGI Path: C:\connectors\isapi_redirect.dll
    • Descriptionjboss
    • Allow extension path to execute:勾选复选框。
  6. 点击 OK 关闭 Add ISAPI or CGI Restriction 窗口。
  7. 定义 JBoss Native 虚拟目录

    • 右击 Default Web Site 并点击 Add Virtual DirectoryAdd Virtual Directory 窗口将被打开。
    • 指定下列值来添加虚拟目录:

      • Alias: jboss
      • Physical Path: C:\connectors\
    • 点击 OK 保存修改并关闭 Add Virtual Directory 窗口。
  8. 定义 JBoss Native ISAPI 重定向过滤器

    • 在树型视图面板里,展开 SitesDefault Web Site
    • 双击 ISAPI FiltersISAPI Filters Features 视图将显示。
    • Actions 面板里,点击 'Add'。Add ISAPI Filter 窗口将显示。
    • Add ISAPI Filter 窗口里指定下列值:

      • Filter name: jboss
      • Executable: C:\connectors\isapi_redirect.dll
    • 点击 OK 保存修改并关闭 Add ISAPI Filters 窗口。
  9. 启用 ISAPI-dll 处理程序

    • 在树型视图面里双击 IIS 7IIS 7 Home Features View 窗口将显示。
    • 双击 Handler MappingsHandler Mappings Features View 窗口将显示。
    • Group by 组合框里,选择 StateHandler Mappings 会在 Enabled and Disabled Groups 中显示。
    • 找到 ISAPI-dll。如果它位于 Disabled 组,右击它并选择 Edit Feature Permissions
    • 启用下列权限:

      • Read
      • Script
      • Execute
    • 点击 OK 保存修改并关闭 Edit Feature Permissions 窗口。

现在已配置 Microsoft IIS 使用 ISAPI 连接器了。

22.9.2. 配置 ISAPI Connector 发送客户请求至 JBoss EAP

这个任务配置一组 JBoss EAP 服务器从 ISAP 连接器接受请求。它没有包含对负载平衡或高可用性失效切换的配置。

这个配置是在 IIS 服务器上完成的,它假定您已配置 JBoss EAP 从外部 Web 服务器接受请求。您也需要对 IIS 服务器的完整管理权限并配置 IIS 所有 ISAPI 连接器

创建属性文件并设立重定向
  1. 创建一个目录来存储日志、属性文件和锁文件。

    这个过程的剩余步骤假定您使用的是 C:\connectors\ 目录。如果您使用了不同的目录,请相应地修改说明。

  2. 创建 isapi_redirect.properties 文件。

    创建一个名为 C:\connectors\isapi_redirect.properties 的新文件。复制下列内容到这个文件里。

    # Configuration file for the ISAPI Connector
    # Extension uri definition
    extension_uri=/jboss/isapi_redirect.dll
    
    # Full path to the log file for the ISAPI Connector
    log_file=c:\connectors\isapi_redirect.log
    
    # Log level (debug, info, warn, error or trace)
    log_level=info
    
    # Full path to the workers.properties file
    worker_file=c:\connectors\workers.properties
    
    # Full path to the uriworkermap.properties file
    worker_mount_file=c:\connectors\uriworkermap.properties
    
    #Full path to the rewrite.properties file
    rewrite_rule_file=c:\connectors\rewrite.properties

    如果您不想使用 rewrite.properties 文件,请用 # 注释最后一行。

  3. 创建 uriworkermap.properties 文件

    uriworkermap.properties 文件包含部署的应用程序 URL 和工作节点处理程序间的映射。下面的例子展示了这个文件的语法。请将您的 uriworkermap.properties 文件放入 C:\connectors\

    # images and css files for path /status are provided by worker01
    /status=worker01
    /css/*=worker01
    
    # Path /web-console is provided by worker02
    # IIS (customized) error page is used for http errors with number greater or equal to 400
    # css files are provided by worker01
    /web-console/*=worker02;use_server_errors=400
    /web-console/css/*=worker01
    
    # Example of exclusion from mapping, logo.gif won't be displayed
    # /web-console/images/logo.gif=*
    
    # Requests to /app-01 or /app-01/something will be routed to worker01
    /app-01|/*=worker01
    
    # Requests to /app-02 or /app-02/something will be routed to worker02
    /app-02|/*=worker02
  4. 创建 workers.properties 文件。

    workers.properties 文件包含工作节点标签和服务器实例间的映射定义。这个文件遵循了用于 Apache mod_jk 工作节点属性配置的相同的文件的语法。

    下面是一个 workers.properties 文件示例。工作节点名称 worker01worker02 必须匹配 JBoss EAP undertow 子系统配置的 instance-id

    将这个文件放入 C:\connectors\ 目录。

    # An entry that lists all the workers defined
    worker.list=worker01, worker02
    
    # Entries that define the host and port associated with these workers
    
    # First JBoss EAP server definition, port 8009 is standard port for AJP in EAP
    worker.worker01.host=127.0.0.1
    worker.worker01.port=8009
    worker.worker01.type=ajp13
    
    # Second JBoss EAP server definition
    worker.worker02.host=127.0.0.100
    worker.worker02.port=8009
    worker.worker02.type=ajp13
  5. 创建 rewrite.properties 文件。

    rewrite.properties 文件包含用于特定应用程序的简单的 URL 重写规则。如下例所示,重写路径是用名-值对指定的。请将这个文件放入 C:\connectors\ 目录。

    #Simple example
    # Images are accessible under abc path
    /app-01/abc/=/app-01/images/
  6. net stopnet start 命令重启您的 IIS 服务器。

    C:\> net stop was /Y
    C:\> net start w3svc

我们配置了 IIS 服务器发送客户请求至特定的 JBoss EAP 服务器。

22.9.3. 配置 ISAPI Connector 在多个 JBoss EAP 服务器间平衡客户请求

这个配置在您指定的 JBoss EAP 服务器间平衡客户请求。这个配置是在 IIS 服务器上完成的,它假定您已配置 JBoss EAP 从外部 Web 服务器接受请求。您也需要对 IIS 服务器的完整管理权限并配置 IIS 所有 ISAPI 连接器

平衡多个服务器间的客户请求
  1. 创建一个目录来存储日志、属性文件和锁文件。

    这个过程的剩余步骤假定您使用的是 C:\connectors\ 目录。如果您使用了不同的目录,请相应地修改说明。

  2. 创建 isapi_redirect.properties 文件。

    创建一个名为 C:\connectors\isapi_redirect.properties 的新文件。复制下列内容到这个文件里。

    # Configuration file for the ISAPI Connector
    # Extension uri definition
    extension_uri=/jboss/isapi_redirect.dll
    
    # Full path to the log file for the ISAPI Connector
    log_file=c:\connectors\isapi_redirect.log
    
    # Log level (debug, info, warn, error or trace)
    log_level=info
    
    # Full path to the workers.properties file
    worker_file=c:\connectors\workers.properties
    
    # Full path to the uriworkermap.properties file
    worker_mount_file=c:\connectors\uriworkermap.properties
    
    #OPTIONAL: Full path to the rewrite.properties file
    rewrite_rule_file=c:\connectors\rewrite.properties

    如果您不想使用 rewrite.properties 文件,请用 # 注释最后一行。

  3. 创建 uriworkermap.properties 文件。

    uriworkermap.properties 文件包含部署的应用程序 URL 和工作节点处理程序间的映射。下面的例子展示了带有负载平衡配置的文件的语法。通配符(*)发送不同 URL 子目录的所有请求至负载平衡器调用的路由器。下一步骤将涵盖关于负载平衡器的配置。

    将您的 uriworkermap.properties 文件放入 C:\connectors\

    # images, css files, path /status and /web-console will be
    # provided by nodes defined in the load-balancer called "router"
    /css/*=router
    /images/*=router
    /status=router
    /web-console|/*=router
    
    # Example of exclusion from mapping, logo.gif won't be displayed
    # /web-console/images/logo.gif=*
    
    # Requests to /app-01 and /app-02 will be routed to nodes defined
    # in the load-balancer called "router"
    /app-01|/*=router
    /app-02|/*=router
    
    # mapping for management console, nodes in cluster can be enabled or disabled here
    /jkmanager|/*=status
  4. 创建 workers.properties 文件。

    workers.properties 文件包含工作节点标签和服务器实例间的映射定义。这个文件遵循了用于 Apache mod_jk 工作节点属性配置的相同的文件的语法。

    下面是一个 workers.properties 文件示例。负载平衡器在文件结尾进行配置,它由工作节点 worker01worker02 组成。这些工作节点名称必须匹配 JBoss EAP undertow 子系统配置的 instance-id

    将这个文件放入 C:\connectors\ 目录。

    # The advanced router LB worker
    worker.list=router,status
    
    # First EAP server definition, port 8009 is standard port for AJP in EAP
    #
    # lbfactor defines how much the worker will be used.
    # The higher the number, the more requests are served
    # lbfactor is useful when one machine is more powerful
    # ping_mode=A – all possible probes will be used to determine that
    # connections are still working
    
    worker.worker01.port=8009
    worker.worker01.host=127.0.0.1
    worker.worker01.type=ajp13
    worker.worker01.ping_mode=A
    worker.worker01.socket_timeout=10
    worker.worker01.lbfactor=3
    
    # Second EAP server definition
    worker.worker02.port=8009
    worker.worker02.host=127.0.0.100
    worker.worker02.type=ajp13
    worker.worker02.ping_mode=A
    worker.worker02.socket_timeout=10
    worker.worker02.lbfactor=1
    
    # Define the LB worker
    worker.router.type=lb
    worker.router.balance_workers=worker01,worker02
    
    # Define the status worker for jkmanager
    worker.status.type=status

  5. 创建 rewrite.properties 文件。

    rewrite.properties 文件包含用于特定应用程序的简单的 URL 重写规则。如下例所示,重写路径是用名-值对指定的。请将这个文件放入 C:\connectors\ 目录。

    #Simple example
    # Images are accessible under abc path
    /app-01/abc/=/app-01/images/
    Restart the IIS server.
    
    Restart your IIS server by using the net stop and net start commands.
    C:\> net stop was /Y
    C:\> net start w3svc

我们配置了 IIS 服务器发送客户请求至 workers.properties 文件里引用的 JBoss EAP 服务器,按 1:3 的比例将负载散布在服务器上。这个比例是从分配给每个服务器的负载平衡因子(lbfactor)衍生的。

22.10. Oracle NSAPI Connector

Netscape Server API (NSAPI) 是 Oracle iPlanet Web Server(之前称为 Netscape Web Server)提供的 API,用于实现服务器的扩展。这些扩展被称为服务器插件。NSAPI 连接器用在 nsapi_redirector.so 里,它是根据 Oracle iPlanet Web Server 调整的 mod_jk 的扩展。NSAP 连接器让您配置 JBoss EAP 实例为工作节点,并将 Oracle iPlanet Web Server 作为负载平衡器。

注意

关于受支持的 Solaris 和 Oracle iPlanet Web Server 的配置,请参考 JBoss EAP 支持的配置

22.10.1. 配置 Oracle iPlanet Web Server 使用 NSAPI Connector

先决条件

  • JBoss EAP 在将作为工作节点的每台服务器上安装和配置。

从红帽客户门户网站下载 NSAPI 连接器:

  1. 打开浏览器并登录红帽客户门户网站 JBoss Software Downloads 页面
  2. Product 下拉菜单选择 Web Connectors
  3. Version 下拉菜单里选择最新的 JBoss Core Services 版本。
  4. 在列表里找到 Red Hat JBoss Core Services NSAPI Connector,确保您选择了正确的平台和架构,然后点击 Download 链接。
  5. 解压位于 lib/lib64/ 目录里的 nsapi_redirector.so 文件到 IPLANET_CONFIG/lib/IPLANET_CONFIG/lib64/ 目录。

设置 NSAPI Connector:

注意

在这些说明里,IPLANET_CONFIG 指的是 Oracle iPlanet 配置目录,它通常是 /opt/oracle/webserver7/config/。如果您的 Oracle iPlanet 配置目录是不一样的,请相应地进行修改。

  1. 禁用 servlet 映射。

    打开 IPLANET_CONFIG/default.web.xml 文件并定位标题为 Built In Server Mappings 的部分。用 XML 注释字符(<!---->)来禁用对下列三个 Servlet 的映射。

    • default
    • invoker
    • jsp

      下面的配置示例展示了禁用的映射。

      <!-- ============== Built In Servlet Mappings =============== -->
      <!-- The servlet mappings for the built in servlets defined above. -->
      <!-- The mapping for the default servlet -->
      <!--servlet-mapping>
       <servlet-name>default</servlet-name>
       <url-pattern>/</url-pattern>
      </servlet-mapping-->
      <!-- The mapping for the invoker servlet -->
      <!--servlet-mapping>
       <servlet-name>invoker</servlet-name>
       <url-pattern>/servlet/*</url-pattern>
      </servlet-mapping-->
      <!-- The mapping for the JSP servlet -->
      <!--servlet-mapping>
       <servlet-name>jsp</servlet-name>
       <url-pattern>*.jsp</url-pattern>
      </servlet-mapping-->

      保存文件并退出。

  2. 配置 iPlanet Web Server 加载 NSAP Connector 模块。

    添加下列行至 IPLANET_CONFIG/magnus.conf 文件的结尾,根据您的配置修改文件路径。这些行定义 nsapi_redirector.so 模块及 workers.properties 文件的位置(这个文件列出了工作节点及它们的属性)

    Init fn="load-modules" funcs="jk_init,jk_service" shlib="/lib/nsapi_redirector.so" shlib_flags="(global|now)"
    
    Init fn="jk_init" worker_file="IPLANET_CONFIG/connectors/workers.properties" log_level="info" log_file="IPLANET_CONFIG/connectors/nsapi.log" shm_file="IPLANET_CONFIG/connectors/tmp/jk_shm"

    上面的配置适用于 32 位架构。如果您使用 64 位 Solaris,请将 lib/nsapi_redirector.so 改为 lib64/nsapi_redirector.so

    保存文件并退出。

  3. 配置 NSAPI Connector。

    您可以对 NSAPI Connector 进行基本的配置,没有负载平衡或相关配置。在配置完成前选择下列选项之一。

22.10.2. 配置 NSAPI Connector 发送客户请求至 JBoss EAP

这个任务配置 NSAP Connector 重定向客户请求至没有负载平衡失效切换的 JBoss EAP 服务器。重定向是对每个部署(每个 URL)进行的。

重要

在继续这个任务前,您必须已配置了 NSAPI Connector

设置基本的 HTTP Connector
  1. 定义 URL 路径重定向至 JBoss EAP 服务器。

    注意

    IPLANET_CONFIG/obj.conf 里,每行开头是不允许空格的,除非这一行是上一行的继续。

    编辑 IPLANET_CONFIG/obj.conf 文件。找到以 <Object name="default"> 开始的部分,然后按照下例展示的格式添加要匹配的每个 URL。字符串 jknsapi 指的是下一步里要定义的 HTTP Connector。这个例子展示了用于模式匹配的通配符用法。

    <Object name="default">
    [...]
    NameTrans fn="assign-name" from="/status" name="jknsapi"
    NameTrans fn="assign-name" from="/images(|/*)" name="jknsapi"
    NameTrans fn="assign-name" from="/css(|/*)" name="jknsapi"
    NameTrans fn="assign-name" from="/nc(|/*)" name="jknsapi"
    NameTrans fn="assign-name" from="/jmx-console(|/*)" name="jknsapi"
    </Object>
  2. 定义提供每个路径的工作节点。

    继续编辑 IPLANET_CONFIG/obj.conf 文件。直接在您已完成编辑的 </Object> 的结束标签后添加下列内容。

    <Object name="jknsapi">
    ObjectType fn=force-type type=text/plain
    Service fn="jk_service" worker="worker01" path="/status"
    Service fn="jk_service" worker="worker02" path="/nc(/*)"
    Service fn="jk_service" worker="worker01"
    </Object>

    上面的例子将到 URL 路径 /status 的请求重定向到工作节点 worker01,将到 /nc/ 下的所有 URL 路径的请求重定向到工作节点 worker02。第三行指定,所有与前面条件不匹配的、分配给 jknsapi 对象的 URL 都由 worker01 处理。

    保存文件并退出。

  3. 定义工作节点及其属性。

    IPLANET_CONFIG/connectors/ 目录里创建一个名为 workers.properties 的文件。粘贴下列内容到这个文件并按照需要进行修改。

    # An entry that lists all the workers defined
    worker.list=worker01, worker02
    
    # Entries that define the host and port associated with these workers
    worker.worker01.host=127.0.0.1
    worker.worker01.port=8009
    worker.worker01.type=ajp13
    
    worker.worker02.host=127.0.0.100
    worker.worker02.port=8009
    worker.worker02.type=ajp13

    workers.properties 文件使用和 Apache mod_jk 相同的语法。

    保存文件并退出。

  4. 重启 iPlanet Web Server

    执行下列命令来重启 iPlanet Web Server。

    IPLANET_CONFIG/../bin/stopserv
    IPLANET_CONFIG/../bin/startserv

现在,iPlanet Web Server 会把客户请求发送到您所配置的、部署在 JBoss EAP 上的 URL。

22.10.3. 配置 NSAPI Connector 在多个 JBoss EAP 服务器间平衡客户请求

这个任务配置 NSAPI Connector 发送客户请求至负载平衡配置里的JBoss EAP 服务器。

重要

在继续这个任务前,您必须已配置了 NSAPI Connector

配置连接器的负载平衡
  1. 定义 URL 路径重定向至 JBoss EAP 服务器。

    注意

    IPLANET_CONFIG/obj.conf 里,每行开头是不允许空格的,除非这一行是上一行的继续。

    编辑 IPLANET_CONFIG/obj.conf 文件。找到以 <Object name="default"> 开始的部分,然后按照下例展示的格式添加要匹配的每个 URL。字符串 jknsapi 指的是下一步里要定义的 HTTP Connector。这个例子展示了用于模式匹配的通配符用法。

    <Object name="default">
    [...]
    NameTrans fn="assign-name" from="/status" name="jknsapi"
    NameTrans fn="assign-name" from="/images(|/*)" name="jknsapi"
    NameTrans fn="assign-name" from="/css(|/*)" name="jknsapi"
    NameTrans fn="assign-name" from="/nc(|/*)" name="jknsapi"
    NameTrans fn="assign-name" from="/jmx-console(|/*)" name="jknsapi"
    NameTrans fn="assign-name" from="/jkmanager/*" name="jknsapi"
    </Object>
  2. 定义提供每个路径的工作节点。

    继续编辑 IPLANET_CONFIG/obj.conf 文件。直接在上一步骤里修改的部分(</Object>)后面添加下列内容并按照需要进行修改:

    <Object name="jknsapi">
    ObjectType fn=force-type type=text/plain
    Service fn="jk_service" worker="status" path="/jkmanager(/*)"
    Service fn="jk_service" worker="router"
    </Object>

    这个 jksnapi 对象定义了用于提供每个映射至 default 对象里的 name="jksnapi" 的路径的工作节点。除了匹配 /jkmanager/* 的 URL 的所有内容都将重定向至名为 router 的工作节点。

  3. 定义工作节点及其属性。

    IPLANET_CONFIG/connector/ 目录里创建一个名为 workers.properties 的文件。粘贴下列内容到这个文件并按照需要进行修改。

    # The advanced router LB worker
    # A list of each worker
    worker.list=router,status
    
    # First JBoss EAP server
    # (worker node) definition.
    # Port 8009 is the standard port for AJP
    #
    
    worker.worker01.port=8009
    worker.worker01.host=127.0.0.1
    worker.worker01.type=ajp13
    worker.worker01.ping_mode=A
    worker.worker01.socket_timeout=10
    worker.worker01.lbfactor=3
    
    # Second JBoss EAP server
    worker.worker02.port=8009
    worker.worker02.host=127.0.0.100
    worker.worker02.type=ajp13
    worker.worker02.ping_mode=A
    worker.worker02.socket_timeout=10
    worker.worker02.lbfactor=1
    
    # Define the load-balancer called "router"
    worker.router.type=lb
    worker.router.balance_workers=worker01,worker02
    
    # Define the status worker
    worker.status.type=status

    workers.properties 文件使用和 Apache mod_jk 相同的语法。

    保存文件并退出。

  4. 重启 iPlanet Web Server 7.0。

    IPLANET_CONFIG/../bin/stopserv
    IPLANET_CONFIG/../bin/startserv

iPlanet Web Server 重定向您配置的 URL 模式至负载平衡配置里的 JBoss EAP 服务器。