Chapter 22. Configuring high availability
Chapter 22. Configuring high availability 22.1. Introduction to high availability JBoss EAP provides the following high availability services to guarantee the availability of deployed Jakarta EE applications. Load balancing This allows a service to handle a large number of requests by spreading the workload across multiple servers. A client can have timely responses from the service even in the event of a high volume of requests. Failover This allows a client to have uninterrupted access to a service even in the event of hardware or network failures. If the service fails, another cluster member takes over the client's requests so that it can continue processing. Clustering is a term that encompasses all of these capabilities. Members of a cluster can be configured to share workloads, referred to as load balancing, and pick up client processing in the event of a failure of another cluster member, referred to as failover. Note It is important to keep in mind that the JBoss EAP operating mode chosen, either standalone server or managed domain , pertains to how you want to manage your servers. High availability services can be configured in JBoss EAP regardless of its operating mode. JBoss EAP supports high availability at several different levels using various components. Some of those components of the runtime and your applications that can be made highly-available are: Instances of the application server Web applications, when used in conjunction with the internal JWS, Apache HTTP Server, Microsoft IIS, or Oracle iPlanet Web Server Stateful and stateless session Jakarta Enterprise Beans Single sign-on (SSO) mechanisms HTTP sessions Java Message Service services and message-driven beans (MDBs) Singleton MSC services Singleton deployments Clustering is made available to JBoss EAP by the jgroups , infinispan , and modcluster subsystems. The ha and full-ha profiles have these systems enabled. In JBoss EAP, these services start up and shut down on demand, but they will only start up if an application configured as distributable is deployed on the servers. See the JBoss EAP Development Guide for how to mark an application as distributable . 22.2. Cluster communication with JGroups 22.2.1. About JGroups JGroups is a toolkit for reliable messaging and can be used to create clusters whose nodes can send messages to each other. The jgroups subsystem provides group communication support for high availability services in JBoss EAP. It allows you to configure named channels and protocol stacks as well as view runtime statistics for channels. The jgroups subsystem is available when using a configuration that provides high availability capabilities, such as the ha or full-ha profile in a managed domain, or the standalone-ha.xml or standalone-full-ha.xml configuration file for a standalone server. JBoss EAP is preconfigured with two JGroups stacks: udp The nodes in the cluster use User Datagram Protocol (UDP) multicasting to communicate with each other. This is the default stack. tcp The nodes in the cluster use Transmission Control Protocol (TCP) to communicate with each other. Note TCP has more overhead and is often considered slower than UDP because it handles error checking, packet ordering, and congestion control itself. JGroups handles these features for UDP, whereas TCP guarantees them itself. TCP is a good choice when using JGroups on unreliable or high congestion networks, or when multicast is not available. You can use the preconfigured stacks or define your own to suit your system's specific requirements. For additional information on the available protocols and their attributes, see the following sections. JGroups Subsystem Attributes JGroups Protocols 22.2.2. Switch the default JGroups channel to use TCP By default, cluster nodes communicate using the udp protocol stack configured for the ee JGroups channel. <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> 22.2.2.1. Configuring TCP with multicast Some networks only allow TCP to be used. Procedure Use the following management CLI command to switch the ee channel to use the preconfigured tcp stack: This default tcp stack uses the MPING protocol, which uses IP multicast to discover the initial cluster membership. 22.2.2.2. Configuring TCP without multicast You can change the default protocol stack to use TCP without multicast when multicast is not preferable or allowed by security policies. Procedure To configure TCP-based clustering without multicast, perform the following steps: To switch the ee channel to use the pre-configured tcp stack in the JGroups subsystem, run the following command: Set the name of the cluster node: In the standalone configuration mode, perform one of the following steps: Run the following command: Specify a unique name to the system property jboss.node.name when starting the instance. In the domain mode, the cluster servers are listed in the host-*.xml file in the server's tag. The default configuration specifies the following server names, which you can edit if needed. Choose one of the following protocols for discovering other cluster members: TCPGOSSIP : This protocol uses an external gossip router service to discover the members of a cluster. This requires configuration and management of additional processes but allows the individual EAP instances to not list each other cluster member. This protocol is advantageous if the cluster members change frequently. For more details, see TCPPING . TCPPING : This protocol defines a static cluster membership list and requires each node to list all the potential cluster members. This protocol is preferred when cluster member addresses are known and do not change frequently. For more details, see TCPGOSSIP . 22.2.3. Configure TCPPING This procedure creates a new JGroups stack that uses the TCPPING protocol to define a static cluster membership list. A base script is provided that creates a tcpping stack and sets the default ee channel to use this new stack. The management CLI commands in this script must be customized for your environment and will be processed as a batch. Procedure Copy the following script into a text editor and save it to the local file system. Note that the order of protocols defined is important. You can also insert a protocol at a particular index by passing an add-index value to the add command. The index is zero-based, so the following management CLI command adds the UNICAST3 protocol as the seventh protocol. Modify the script for your environment. If you are running in a managed domain, you must specify which profile to update by preceding the /subsystem=jgroups commands with /profile= PROFILE_NAME . Adjust the following properties as appropriate for your environment: socket-bindings : A comma-separated list of the host and port combinations that are considered well-known and will be available to look up the initial membership. See Configuring Socket Bindings for more information on defining socket bindings. initial_hosts : A comma-separated list of the host and port combinations, using the syntax HOST [ PORT ] , that are considered well-known and will be available to look up the initial membership, for example, host1[1000],host2[2000] . port_range : This property is used to extend the initial_hosts port range by the specified value. For example, if you set the initial_hosts to host1[1000],host2[2000] , and the port_range to 1 , the initial_hosts setting expands to host1[1000],host1[1001],host2[2000],host2[2001] . This property only works with the initial_hosts property. Run the script by passing the script file to the management CLI. The TCPPING stack is now available and TCP is used for network communication. 22.2.3.1. Configuring TCPPING in standalone mode This procedure helps you to configure the TCP stack and nodes for a clustered application in the standalone mode. Procedure Change the default stack from udp to tcp in the JGroups subsystem: Configure the TCP stack to use the TCPPING protocol in place of the default MPING protocol. In the following code, the initial_hosts property correlates to a listing of all nodes within the cluster and 7600 denotes the default jgroups-tcp port that can vary based on your configuration and environment. <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> Note The port number 7600 set in initial_hosts must be same as the port number defined in the jgroups-tcp socket-binding definition. If you use the port-offset feature for socket-binding, you need to specify the same value after offset in initial_hosts . Set the IP address of the private interface, which is used by the JGroups component. The IP address should correlate to one of the IP addresses specified in initial_hosts : <interface name="private"> <inet-address value="USD{jboss.bind.address.private:192.168.1.5}"/> </interface> Repeat the above steps for configuring other nodes within the cluster. When the nodes are configured, start each node and deploy a clustered application. Verification You can check logs to verify whether the nodes are up and running: 22.2.3.2. Configuring TCPPING in domain mode This procedure helps you to configure the TCP stack and nodes for a clustered application in the domain mode. Procedure If the same profile is used for multiple clusters, set the system property value to initial_hosts : <protocol type="TCPPING"> <property name="initial_hosts">USD{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> Set the IP address of the private interface within the XML configuration of the host controller. The IP address of the private interface should correlate to one of the IP addresses listed in initial_hosts . <interfaces> .... <interface name="private"> <inet-address value="USD{jboss.bind.address.private:192.168.1.5}"/> </interface> </interfaces> Verification You can check logs to verify whether the nodes are up and running: 22.2.4. Configure TCPGOSSIP This procedure creates a new JGroups stack that uses the TCPGOSSIP protocol to use an external gossip router to discover the members of a cluster. A base script is provided that creates a tcpgossip stack and sets the default ee channel to use this new stack. The management CLI commands in this script must be customized for your environment and will be processed as a batch. Procedure Copy the following script into a text editor and save it to the local file system. Note that the order of protocols defined is important. You can also insert a protocol at a particular index by passing an add-index value to the add command. The index is zero-based, so the following management CLI command adds the UNICAST3 protocol as the seventh protocol. Modify the script for your environment. If you are running in a managed domain, you must specify which profile to update by preceding the /subsystem=jgroups commands with /profile= PROFILE_NAME . Adjust the following properties as appropriate for your environment: socket-bindings : A comma-separated list of the host and port combinations that are considered well-known and will be available to look up the initial membership. See Configuring Socket Bindings for more information on defining socket bindings. initial_hosts : A comma-separated list of the host and port combinations, using the syntax HOST [ PORT ] , that are considered well-known and will be available to look up the initial membership, for example, host1[1000],host2[2000] . port_range : This property is used to extend the initial_hosts port range by the specified value. For example, if you set the initial_hosts to host1[1000],host2[2000] , and the port_range to 1 , the initial_hosts setting expands to host1[1000],host1[1001],host2[2000],host2[2001] . This property only works with the initial_hosts property. reconnect_interval : The interval in milliseconds by which a disconnected stub attempts to reconnect to the gossip router. sock_conn_timeout : The maximum time for socket creation. The default is 1000 milliseconds. sock_read_timeout : The maximum time in milliseconds to block on a read. A value of 0 will block indefinitely. Run the script by passing the script file to the management CLI. The TCPGOSSIP stack is now available and TCP is used for network communication. This stack is configured for use with a gossip router so that JGroups cluster members can find other cluster members. 22.2.5. Configure JDBC_PING You can use the JDBC_PING protocol to manage and discover membership in a cluster. JDBC_PING uses a database, specified in a data-source, to list the members of the cluster. Procedure Create a data-source to connect to the database you want to use to manage cluster membership. Copy the following script into a text editor and save it to the local file system. Note The order of the defined protocols is important. You can also insert a protocol at a particular index by passing an add-index value to the add command. The index is zero-based, so the following management CLI command adds the UNICAST3 protocol as the seventh protocol. Modify the script for your environment. If you are running in a managed domain, you must specify which profile to update by preceding the /subsystem=jgroups commands with /profile= PROFILE_NAME . Replace ' ExampleDS ' with the name of the data-source you defined in Step 1. Run the script by passing the script file to the management CLI. The JDBC_PING stack is now available and TCP is used for network communication. Additional resources For more information about JDBC_PING, see JDBC_PING . For more information about creating data-sources, see About JBoss EAP datasources 22.2.6. Binding JGroups to a network interface By default, JGroups only binds to the private network interface, which points to localhost in the default configuration. For security reasons, JGroups will not bind to the network interface defined by the -b argument specified during JBoss EAP startup, as clustering traffic should not be exposed on a public network interface. See the Network and Port Configuration chapter in this guide for information about how to configure network interfaces. Important For security reasons, JGroups should only be bound to a non-public network interface. For performance reasons, we also recommend that the network interface for JGroups traffic should be part of a dedicated Virtual Local Area Network (VLAN). 22.2.7. Securing a cluster There are several concerns to address in order to run a cluster securely: Preventing unauthorized nodes from joining the cluster. This is addressed by requiring authentication . Preventing non-members from communicating with cluster members. This is addressed by encrypting messages . 22.2.7.1. Configuring authentication JGroups authentication is performed by the AUTH protocol. The purpose is to ensure that only authenticated nodes can join a cluster. In the applicable server configuration file, add the AUTH protocol with the appropriate property settings. The AUTH protocol should be configured immediately before the pbcast.GMS protocol. The following examples demonstrate using AUTH with different forms of authorization tokens. AUTH with a simple token ... <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"/> ... AUTH with a digest algorithm token This format can be used with any digest algorithm, for example MD5 or SHA-2. The default digest algorithm in JBoss EAP 8.0 is SHA-256, the strongest digest algorithm required to be supported by the JVM. Many JVMs will additionally implement 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"/> ... AUTH with an X509 token This example creates a new keystore in the elytron subsystem, and references it in the JGroups AUTH configuration. Create the keystore: Add the keystore to the elytron subsystem using the management CLI: In the JGroups stack definition, configure AUTH to use the keystore: ... <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"/> ... 22.2.7.2. Configuring encryption To encrypt messages, JGroups uses a secret key that is shared by the members of a cluster. The sender encrypts the message using the shared secret key, and the receiver decrypts the message using the same secret key. With symmetric encryption , which is configured using the SYM_ENCRYPT protocol, nodes use a shared keystore to retrieve the secret key. With asymmetric encryption , which is configured using the ASYM_ENCRYPT protocol, nodes retrieve the secret key from the coordinator of the cluster after being authenticated using AUTH . Using symmetric encryption In order to use SYM_ENCRYPT , you must set up a keystore that will be referenced in the JGroups configuration for each node. Create a keystore. In the following command, replace VERSION with the appropriate JGroups JAR version and PASSWORD with a keystore password. This will generate a defaultStore.keystore file that will be referenced in the JGroups configuration. Once the keystore has been generated it is defined in the SYM_PROTOCOL using one of two methods. Specify the keystore directly in the configuration . Reference the keystore using the Elytron subsystem . Note Configuring AUTH is optional when using SYM_ENCRYPT . Using symmetric encryption by directly referencing the keystore Configure the SYM_ENCRYPT protocol in the jgroups subsystem. In the applicable server configuration file, add the SYM_ENCRYPT protocol with the appropriate property settings. This protocol will reference the previously created keystore. The SYM_ENCRYPT protocol should be configured immediately before the pbcast.NAKACK2 protocol. <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> Using symmetric encryption with elytron Using the management CLI, create a keystore in the elytron subsystem that references the defaultStore.keystore created in using symmetric encryption . Add the SYM_ENCRYPT protocol in the jgroups subsystem with the appropriate property settings. The SYM_ENCRYPT protocol should be configured immediately before the pbcast.NAKACK2 protocol, as seen in the following configuration. <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> Note The above example uses a clear text password; however, a credential store may also be defined to define the password outside of the configuration file. For more information on configuring this store, see the Credential store section in the How to Configure Server Security guide. Using asymmetric encryption In order to use ASYM_ENCRYPT the AUTH protocol must be defined. See the Configuring authentication section for instructions on configuring the AUTH protocol in the jgroups subsystem. The ASYM_ENCRYPT is configured using one of two methods. Generate a secret key and reference it directly in the configuration . Create a keystore and reference it using the Elytron subsystem . Using asymmetric encryption by generating a secret key Configure the ASYM_ENCRYPT protocol in the jgroups subsystem. In the applicable server configuration file, add the ASYM_ENCRYPT protocol with the appropriate property settings. The ASYM_ENCRYPT protocol should be configured immediately before the pbcast.NAKACK2 protocol, as seen in the following configuration. <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> Using asymmetric encryption with elytron Create a keystore to contain the key pair. The following command creates a keystore with the mykey entry. Using the management CLI, create a keystore in the elytron subsystem that references the defaultStore.keystore . Add the ASYM_ENCRYPT protocol in the jgroups subsystem with the appropriate property settings. The ASYM_ENCRYPT protocol should be configured immediately before the pbcast.NAKACK2 protocol, as seen in the following configuration. <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> Note The above example uses a clear text password; however, a credential store may also be defined to define the password outside of the configuration file. For more information on configuring this store, see the Credential store section in the How to Configure Server Security guide. 22.2.8. Configure JGroups thread pools The jgroups subsystem contains the default , internal , oob , and timer thread pools. These pools can be configured for any JGroups stack and do not affect bean or other pools configured on local nodes. The JGroup thread pools are used to support cluster communication. The following table lists the attributes you can configure for each thread pool and the default value for each. Thread pool name Description keepalive-time max-threads min-threads queue-length default This pool is used to handle incoming messages that are not marked as out-of-band. 60000L 300 20 100 internal This pool is used to handle internal processes needed for EAP maintenance. 60000L 4 2 100 oob This pool is used to handle incoming out-of-band messages. 60000L 300 20 0 timer This pool is used to handle time-bound scheduler messages. 5000L 4 2 500 Use the following syntax to configure a JGroups thread pool using the management CLI. The following is an example of the management CLI command to set the max-threads value to 500 in the default thread pool for the udp stack. 22.2.9. Configure JGroups send and receive buffers Resolving buffer size warnings By default, JGroups is configured with certain send and receive buffer values; however, your operating system may limit the available buffer sizes and JBoss EAP may not be able to use its configured buffer values. In this situation you will see warnings in the JBoss EAP logs similar to the following: To resolve this, consult your operating system documentation for instructions on how to increase the buffer size. For Red Hat Enterprise Linux systems, edit /etc/sysctl.conf as the root user to configure maximum values for buffer sizes that will survive system restarts. For example: After modifying /etc/sysctl.conf , run sysctl -p for the changes to take effect. Configuring JGroups buffer sizes You can configure the JGroups buffer sizes that JBoss EAP uses by setting the following transport properties on the UDP and TCP JGroups stacks. UDP stack ucast_recv_buf_size ucast_send_buf_size mcast_recv_buf_size mcast_send_buf_size TCP stack recv_buf_size send_buf_size JGroups buffer sizes can be configured using the management console or the management CLI. Use the following syntax to set a JGroups buffer size property using the management CLI. The following is an example management CLI command to set the recv_buf_size property to 20000000 on the tcp stack. JGroups buffer sizes can also be configured using the management console by navigating to the JGroups subsystem from the Configuration tab, clicking View , selecting the Stack tab, choosing the appropriate stack, clicking Transport , and editing the Properties field. 22.2.10. Tuning the JGroups subsystem For tips on monitoring and optimizing performance for the jgroups subsystem, see the JGroups Subsystem Tuning section of the Performance tuning for JBoss EAP . 22.2.11. JGroups troubleshooting 22.2.11.1. Nodes do not form a cluster Make sure your machine is set up correctly for IP multicast. There are two test programs that ship with JBoss EAP that can be used to test IP multicast: McastReceiverTest and McastSenderTest . In a terminal, start McastReceiverTest . Then in another terminal window, start McastSenderTest . If you want to bind to a specific network interface card (NIC), use -bind_addr YOUR_BIND_ADDRESS , where YOUR_BIND_ADDRESS is the IP address of the NIC to which you want to bind. Use this parameter in both the sender and the receiver. When you type in the McastSenderTest terminal window, you should see the output in the McastReceiverTest window. If you do not, try the following steps. Increase the time-to-live for multicast packets by adding -ttl VALUE to the sender command. The default used by this test program is 32 and the VALUE must be no greater than 255 . If the machines have multiple interfaces, verify that you are using the correct interface. Contact a system administrator to make sure that multicast will work on the interface you have chosen. Once you know multicast is working properly on each machine in your cluster, you can repeat the above test to test the network, putting the sender on one machine and the receiver on another. 22.2.11.2. Causes of missing heartbeats in failure detection Sometimes a cluster member is suspected by failure detection (FD) because a heartbeat acknowledgment has not been received for some time T , which is defined by timeout and max_tries . For an example cluster of nodes A, B, C, and D, where A pings B, B pings C, C pings D, and D pings A, C can be suspected for any of the following reasons: B or C are running at 100% CPU for more than T seconds. So even if C sends a heartbeat acknowledgment to B, B may not be able to process it because it is at 100% CPU usage. B or C are garbage collecting, which results in the same situation as above. A combination of the two cases above. The network loses packets. This usually happens when there is a lot of traffic on the network, and the switch starts dropping packets, usually broadcasts first, then IP multicasts, and TCP packets last. B or C are processing a callback. For example, if C received a remote method call over its channel that takes T + 1 seconds to process, during this time C will not process any other messages, including heartbeats. Therefore, B will not receive the heartbeat acknowledgment and will suspect C. 22.3. Infinispan 22.3.1. About Infinispan Infinispan is a Java data grid platform that provides a Jakarta Persistence 2.2 -compatible cache interface for managing cached data. For more information about Infinispan functionality and configuration options see the Infinispan documentation . The infinispan subsystem provides caching support for JBoss EAP. It allows you to configure and view runtime metrics for named cache containers and caches. When using a configuration that provides high availability capabilities, such as the ha or full-ha profile in a managed domain, or the standalone-ha.xml or standalone-full-ha.xml configuration file for a standalone server, the infinispan subsystem provides caching, state replication, and state distribution support. In non-high-availability configurations, the infinispan subsystem provides local caching support. Important Infinispan is a public module in the JBoss EAP 8.0. You can use the infinispan subsystem for applications to create and use new cache-containers or caches. Also, the usage of the Infinispan APIs is supported by applications. 22.3.2. Cache containers A cache container is a repository for the caches used by a subsystem. Each cache container defines a default cache to be used. JBoss EAP 8.0 defines the following default Infinispan cache containers: server for singleton caching web for web session clustering ejb for stateful session bean clustering hibernate for entity caching Example: Default Infinispan Configuration <subsystem xmlns="{InfinispanSubsystemNamespace}"> <cache-container name="server" aliases="singleton cluster" default-cache="default" module="org.wildfly.clustering.server"> <transport lock-timeout="60000"/> <replicated-cache name="default"> <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"> <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"> <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"> <object-memory size="1000"/> <expiration max-idle="100000"/> </local-cache> <invalidation-cache name="entity"> <transaction mode="NON_XA"/> <object-memory size="1000"/> <expiration max-idle="100000"/> </invalidation-cache> <replicated-cache name="timestamps" mode="ASYNC"/> </cache-container> </subsystem> Note the default cache defined in each cache container. For example, the web cache container defines the dist distributed cache as the default. The dist cache will therefore be used when clustering web sessions. See Configure cache containers for information on changing the default cache and adding additional caches. 22.3.2.1. Configure cache containers Cache containers and cache attributes can be configured using the management console or management CLI. Warning You should avoid changing cache or cache container names, as other components in the configuration may reference them. 22.3.2.1.1. Configure caches using the management console Once you navigate to the Infinispan subsystem from the Configuration tab in the management console, you can configure caches and cache containers. In a managed domain, make sure to select the appropriate profile to configure. Add a cache container. Click the Add ( + ) button to the Cache Container heading, choose Add Cache Container , and enter the settings for the new cache container. Update cache container settings. Choose the appropriate cache container and click View . Configure the cache container settings as necessary. Update cache container transport settings. Choose the appropriate cache container and click View . Select the Transport tab and configure the cache container transport settings as necessary. Configure caches. Choose the appropriate cache container and click View . From the appropriate cache tab, for example, Replicated Cache , you can add, update, and remove caches. 22.3.2.1.2. Configure caches using the management CLI You can configure caches and cache containers using the management CLI. In a managed domain, you must specify the profile to update by preceding these commands with /profile= PROFILE_NAME . Add a cache container. Add a replicated cache. Set the default cache for a cache container. Configure batching for a replicated cache. This results in the following server configuration: <cache-container name="web" default-cache="concurrent" module="org.wildfly.clustering.web.infinispan"> ... <distributed-cache name="concurrent"> <file-store/> </distributed-cache> </cache-container> 22.3.2.1.3. Change the default Jakarta Enterprise Beans cache container You can use cache containers in the ejb3 subsystem as described below: To support passivation of Jakarta Enterprise Beans session beans, you can use the ejb cache container defined in the infinispan subsystem to store the sessions. For remote Jakarta Enterprise Beans clients connecting to a clustered deployment on a server, you must provide the cluster topology information to these clients, so that they can fail over to other nodes in the cluster if the node they are interacting with fails. 22.3.2.1.4. Inject resources from Infinispan subsystem into Jakarta EE applications You can inject Infinispan resources, such as a cache, from the Infinispan subsystem into your application using the @Resource annotation. The following example shows the usage of the @Resource annotation to inject a cache into Jakarta EE application: In the above example, foo is the name of the cache container and bar is the name of the cache to inject. EAP manages the lifecycle of the injected resources, which means your application does not require to manage those resources, such as caches or a cache manager. Note When you manually create any resources, your application manages those resources, not EAP. The following examples show how to inject different resources from the Infinispan subsystem into your application. Example of injecting a default cache To inject the default cache of the cache container from the Infinispan subsystem into your application, use the following command: Example of injecting an embedded cache manager To inject an embedded cache manager to allow your application to create new cache configurations and caches, use the following command: Example of injecting a cache configuration Any cache configurations defined within the Infinispan subsystem are not always installed or available unless your application explicitly depends on those cache configurations. To inject a cache configuration from the Infinispan subsystem into your application, use the @Resource annotation. The following example uses the @Resource annotation to inject the cache configuration of the foo container: The following example uses the @Resource annotation to inject the default cache configuration of the foo container: 22.3.2.1.5. Eviction feature in Hibernate cache container The eviction feature for the hibernate cache container removes cache entries from memory. This feature helps reduce the memory load on the subsystem. The size attribute sets the maximum number of cache entries that will be stored before eviction of cache entries begins. Example: Eviction Feature <cache-container name="hibernate" default-cache="local-query" module="org.hibernate.infinispan"> <transport lock-timeout="60000"/> <local-cache name="local-query"> <object-memory size="1000"/> <expiration max-idle="100000"/> Note that eviction only occurs within the memory. A cache store holds cache entries that are evicted to prevent permanent loss of information. For more information about the eviction feature, see the Eviction and Data Container section in the Infinispan User Guide. 22.3.2.1.6. Expiration feature in Hibernate cache container The expiration feature for the hibernate cache container is a clustered operation; thus, when using a clustered cache, an expired cache entry is removed from all cluster members. For more information, see the Expiration section in the Infinispan User Guide. 22.3.3. Clustering modes Clustering can be configured in two different ways in JBoss EAP using Infinispan. The best method for your application will depend on your requirements. There is a trade-off between availability, consistency, reliability and scalability with each mode. Before choosing a clustering mode, you must identify what are the most important features of your network, and balance those requirements. Cache modes Replication Replication mode automatically detects and adds new instances on the cluster. Changes made to these instances will be replicated to all nodes on the cluster. Replication mode typically works best in small clusters because of the amount of information that has to be replicated over the network. Infinispan can be configured to use UDP multicast, which alleviates network traffic congestion to a degree. Distribution Distribution mode allows Infinispan to scale the cluster linearly. Distribution mode uses a consistent hash algorithm to determine where in a cluster a new node should be placed. The number of copies, or owners, of information to be kept is configurable. There is a trade-off between the number of copies kept, durability of the data, and performance. The more copies that are kept, the more impact on performance, but the less likely you are to lose data in a server failure. The hash algorithm also works to reduce network traffic by locating entries without multicasting or storing metadata. You should consider using distribution mode as a caching strategy when the cluster size exceeds 6-8 nodes. With distribution mode, data is distributed to only a subset of nodes within the cluster, as opposed to all nodes. 22.3.3.1. Configure the Cache Mode You can change the default cache using the management CLI. Note This section shows instructions specific to configuring the web session cache, which defaults to distribution mode. The steps and management CLI commands can easily be adjusted to apply to other cache containers. Change to replication cache mode The default JBoss EAP 8.0 configuration for the web session cache does not include a repl replication cache. This cache must first be added. Note The below management CLI commands are for a standalone server. When running in a managed domain, you must specify which profile to update by preceding the /subsystem=infinispan commands with /profile= PROFILE_NAME . Add the repl replication cache and set it as the default cache. Reload the server. Change to distribution cache mode The default JBoss EAP 8.0 configuration for the web session cache already includes a dist distribution cache. Note The below management CLI commands are for a standalone server. When running in a managed domain, you must specify which profile to update by preceding the /subsystem=infinispan commands with /profile= PROFILE_NAME . Change the default cache to the dist distribution cache. Set the number of owners for the distribution cache. The following command sets 5 owners. The default is 2 . Reload the server. 22.3.3.2. Cache strategy performance When using a SYNC caching strategy, the cost of replication is easy to measure and directly seen in response times since the request does not complete until the replication completes. Although it seems that the ASYNC caching strategy should result in lower response times than the SYNC caching strategy, this is only true under the right conditions. The ASYNC caching strategy is more difficult to measure, but it can provide better performance than the SYNC strategy when the duration between requests is long enough for the cache operation to complete. This is because the cost of replication is not immediately seen in response times. If requests for the same session are made too quickly, the cost of replication for the request is shifted to the front of the subsequent request since it must wait for the replication from the request to complete. For rapidly fired requests where a subsequent request is sent immediately after a response is received, the ASYNC caching strategy will perform worse than the SYNC caching strategy. Consequently, there is a threshold for the period of time between requests for the same session where the SYNC caching strategy will actually perform better than the ASYNC caching strategy. In real world usage, requests for the same session are not normally received in rapid succession. Instead, there is typically a period of time in the order of a few seconds or more between the requests. In this case, the ASYNC caching strategy is a sensible default and provides the fastest response times. 22.3.4. State transfer State transfer is both a basic data grid and clustered cache function. Without state transfer, data would be lost as nodes are added to or removed from the cluster. State transfer adjusts the cache's internal state in response to a change in the cache membership. This change automatically occurs when a node joins or leaves the cluster, when two or more cluster partitions merge, or after any combination of these events. The initial state transfer for a newly started cache is the most expensive, as the new cache must receive the maximum amount of state, based on the cache's mode as discussed below. The timeout attribute can be used to control how long the newly started cache waits to receive its state. If the timeout attribute is a positive number, then the cache will wait to receive all of its initial state before being made available to service requests. If the state transfer does not complete in the specified time, the default being 240000 milliseconds, then the cache will throw an error and cancel the startup. If timeout is set to 0 , then the cache is immediately available, and it will receive its initial state during background operations. Until the initial state transfer is complete, any requests for cache entries that the cache has not yet received will need to be fetched from a remote node. The timeout attribute can be set to 0 with the following command. /subsystem=infinispan/cache-container=server/ CACHE_TYPE = CACHE /component=state-transfer:write-attribute(name=timeout,value=0) The state transfer behavior is determined by the cache's mode. In replication mode a new node joining the cache receives the entire cache state from the existing nodes. When a node leaves the cluster there is no state transfer. In distribution mode the new node receives only a part of the state from the existing nodes, and the existing nodes remove some of their state in order to keep owners copies of each key in the cache, as determined through consistent hashing. When a node leaves the cluster, a distribution cache needs to make additional copies of the keys that were stored on that node, so that owners of each key continue to exist. In invalidation mode the initial state transfer is similar to replication mode, the only difference being that the nodes are not guaranteed to have the same state. When a node leaves the cluster there is no state transfer. A state transfer transfers both in-memory and persistent state by default, but both can be disabled in the configuration. When state transfer is disabled, a ClusterLoader must be configured, otherwise a node will become the owner or backup owner of a key without the data being loaded into its cache. In addition, if state transfer is disabled in distribution mode then a key will occasionally have less than owners copies in the cache. 22.3.5. Configure Infinispan thread pools The infinispan subsystem contains the async-operations , expiration , listener , persistence , remote-command , state-transfer , and transport thread pools. These pools can be configured for any Infinispan cache container. The following table lists the attributes you can configure for each thread pool in the infinispan subsystem and the default value for each. Thread Pool Name keepalive-time max-threads min-threads queue-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 Use the following syntax to configure an Infinispan thread pool using the management CLI. The following is an example of the management CLI command to set the max-threads value to 10 in the persistence thread pool for the server cache container. 22.3.6. Infinispan statistics Runtime statistics about Infinispan caches and cache containers can be enabled for monitoring purposes. Statistics collection is not enabled by default for performance reasons. Statistics collection can be enabled for each cache container, cache, or both. The statistics option for each cache overrides the option for the cache container. Enabling or disabling statistics collection for a cache container will cause all caches in that container to inherit the setting, unless they explicitly specify their own. 22.3.6.1. Enable Infinispan statistics Warning Enabling Infinispan statistics may have a negative impact on the performance of the infinispan subsystem. Statistics should be enabled only when required. You can enable or disable the collection of Infinispan statistics using the management console or the management CLI. From the management console, navigate to the Infinispan subsystem from the Configuration tab, select the appropriate cache or cache container, and edit the Statistics Enabled attribute. Use the below commands to enable statistics using the management CLI. Enable statistics collection for a cache container. A server reload will be required. Enable statistics collection for a cache. A server reload will be required. Note You can use the following command to undefine the statistics-enabled attribute of a cache so that it will inherit the settings of its cache container's statistics-enabled attribute. 22.3.7. Infinispan partition handling An Infinispan cluster is built out of several nodes where data is stored. To prevent data loss if multiple nodes fail, Infinispan copies the same data over multiple nodes. This level of data redundancy is configured using the owners attribute. As long as fewer than the configured number of nodes crash simultaneously, Infinispan will have a copy of the data available. However, there are potential catastrophic situations that could occur when too many nodes disappear from the cluster: Split brain This splits the cluster in two or more partitions, or sub-clusters, that operate independently. In these circumstances, multiple clients reading and writing from different partitions see different versions of the same cache entry, which for many applications is problematic. Note There are ways to alleviate the possibility for the split brain to happen, such as redundant networks or IP bonding ; however, these only reduce the window of time for the problem to occur. Multiple nodes crash in sequence If multiple nodes, specifically the number of owners, crash in rapid sequence and Infinispan does not have the time to properly rebalance its state between crashes, the result is partial data loss. The goal is to avoid situations in which incorrect data is returned to the user as a result of either split brain or multiple nodes crashing in rapid sequence. 22.3.7.1. Split brain In a split brain situation, each network partition will install its own JGroups view, removing the nodes from the other partitions. We do not have a direct way to determine whether the cluster has been split into two or more partitions, since the partitions are unaware of each other. Instead, we assume the cluster has split when one or more nodes disappear from the JGroups cluster without sending an explicit leave message. With partition handling disabled, each such partition would continue to function as an independent cluster. Each partition may only see a part of the data, and each partition could write conflicting updates in the cache. With partition handling enabled, if we detect a split, each partition does not start a rebalance immediately, but first checks whether it should enter degraded mode instead: If at least one segment has lost all its owners, meaning that at least the number of owners specified has left since the last rebalance ended, the partition enters degraded mode. If the partition does not contain a simple majority of the nodes (floor(numNodes/2) + 1) in the latest stable topology , the partition also enters degraded mode. Otherwise, the partition keeps functioning normally and starts a rebalance. The stable topology is updated every time a rebalance operation ends and the coordinator determines that another rebalance is not necessary. These rules ensure that at most, one partition stays in available mode, and the other partitions enter degraded mode. When a partition is in degraded mode, it only allows access to the keys that are wholly owned: Requests (reads and writes) for entries that have all the copies on nodes within this partition are honored. Requests for entries that are partially or totally owned by nodes that have disappeared are rejected with an AvailabilityException . This guarantees that partitions cannot write different values for the same key (cache is consistent), and also that one partition can not read keys that have been updated in the other partitions (no stale data). Note Two partitions could start up isolated, and as long as they do not merge, they can read and write inconsistent data. In the future, we may allow custom availability strategies (e.g. check that a certain node is part of the cluster, or check that an external machine is accessible) that could handle that situation as well. 22.3.7.2. Configuring partition handling Partition handling is disabled by default. When you enable partition handling, there are two configurable attributes: Attribute Values when-split "DENY_READ_WRITES", "ALLOW_READS", "ALLOW_READ_WRITES" merge-policy "NONE", "PREFERRED_ALWAYS", "PREFERRED_NON_NULL", "REMOVE_ALL" Configure when-split to determines the read and write behavior of the cache when a network partition is detected. Configure merge-policy to determine the conflict resolution policy strategy when merging two of more network partitions. Example CLI command: 22.3.7.3. Configuring remote cache containers You must configure a remote cache for every server group in a managed domain. You can enable a collection of metrics for a given remote-cache-container and associated runtime caches with the statistics-enabled attribute. 22.3.7.3.1. Creating a remote cache container Each server group in a managed domain requires a unique remote cache. The caches can belong to the same data grid. Therefore, users must configure a remote cache for every server group by defining a socket binding for the server group and associating the socket binding with a remote cache container. Procedure Define a socket-binding , repeating the command as necessary for each remote Red Hat Data Grid instance in the cluster. Define a remote-cache-container that references the newly created socket bindings. 22.3.7.3.2. Enabling statistics for a remote cache container The statistics-enabled attribute enables a collection of metrics for a given remote-cache-container and associated runtime caches. For a remote-cache-container called "foo", enable statistics using the following operation: For a remote-cache-container "foo", the following metrics are visible at runtime: For descriptions of these metrics, execute a read-resource-description operation for the remote-cache-container : The following metrics are specific to the remote cache used by the selected deployment: For descriptions of these metrics, execute a read-resource-description operation for the remote cache: Some of these metrics are computed values (example, average-*), while others are tallied, such as hits and misses. The tallied metrics can be reset by the following operation: 22.3.8. Externalize HTTP sessions to Red Hat Data Grid Note You need a Red Hat Data Grid subscription to use this functionality. Red Hat Data Grid can be used as an external cache container for application-specific data in JBoss EAP, such as HTTP sessions. This allows scaling of the data layer independent of the application, and enables different JBoss EAP clusters, which may reside in various domains, to access data from the same Red Hat Data Grid cluster. Additionally, other applications can interface with the caches presented by Red Hat Data Grid. The following example shows how to externalize HTTP sessions. It applies to both standalone instances of JBoss EAP as well as managed domains. Create a remote-cache-container . For more information, see Configuring remote cache containers . Configure the HotRod store. The HotRod store uses one dedicated remote cache for each cache created by the JBoss EAP server. Typically, one invalidation cache is used on the JBoss EAP server, as shown in the CLI script below. Note The remote caches need to be configured manually on the Red Hat Data Grid servers. The recommended configuration for these caches is a transactional distribution mode cache with pessimistic locking. Cache names must correspond to the deployment file names, such as test.war . Once the remote cache container has been configured, a hotrod store can be configured to replace any existing store. The following CLI script demonstrates a typical use case for offloading sessions in conjunction with the invalidation cache. The script configures a new invalidation cache. Session data is then maintained in the cache for performance and written to the store for resilience. A HotRod client can be injected directly into Jakarta EE applications using the @Resource annotation. In the example below, the @Resource annotation looks up the configuration properties in the class path, in the hotrod-client.properties file. @Resource(lookup = "java:jboss/infinispan/remote-container/web-sessions") private org.infinispan.client.hotrod.RemoteCacheContainer client; Example: hotrod-client.properties file Securing a remote cache container It is possible to secure the communication to the remote Red Hat Data Grid instance using SSL. This is accomplished by configuring the remote-cache-container on the JBoss EAP instance and adjusting the hotrod connector on the Red Hat Data Grid instance to use an active security realm. Create a client-ssl-context in JBoss EAP. For additional information on creating a client-ssl-context , including generating the other elytron components, see Using a client-ssl-context in How to Configure Server Security for JBoss EAP. Configure the remote cache container to use the client SSL context. Secure the remote Red Hat Data Grid instance, repeating as necessary for each instance. Copy the keystore used in the client-ssl-context to the remote Red Hat Data Grid instance. Configure the ApplicationRealm to use this keystore. Adjust the hotrod connector to point to this security realm. Reload the remote Red Hat Data Grid instance. 22.3.9. Externalize HTTP sessions to Red Hat Data Grid using a remote store Note You need a Red Hat Data Grid subscription to use this functionality. The instructions here represent an older way of externalizing sessions. JBoss EAP 7.2 introduced a custom optimized cache store based on the HotRod protocol that integrates with the elytron subsystem. It is recommended to use the new hotrod store, as described in Externalize HTTP sessions to Red Hat Data Grid . Note For each distributable application, an entirely new cache must be created. It can be created in an existing cache container, for example, web . To externalize HTTP sessions: Define the location of the remote Red Hat Data Grid server by adding the networking information to the socket-binding-group . Example: Adding remote socket bindings Resulting XML <socket-binding-group name="standard-sockets" ... > ... <outbound-socket-binding name="remote-rhdg-server1"> <remote-destination host="RHDGHostName1" port="11222"/> </outbound-socket-binding> <outbound-socket-binding name="remote-rhdg-server2"> <remote-destination host="RHDGHostName2" port="11222"/> </outbound-socket-binding> </socket-binding-group> Note You will need a remote socket binding configured for each Red Hat Data Grid server. Ensure the remote cache containers are defined in JBoss EAP's infinispan subsystem; in the example below the cache attribute in the remote-store element defines the cache name on the remote Red Hat Data Grid server. If you are running in a managed domain, precede these commands with /profile= PROFILE_NAME . Example: Adding a remote cache container Resulting XML <subsystem xmlns="{InfinispanSubsystemNamespace}"> ... <cache-container name="web" default-cache="dist" module="org.wildfly.clustering.web.infinispan" statistics-enabled="true"> <transport lock-timeout="60000"/> <invalidation-cache name="rhdg" mode="SYNC"> <locking isolation="REPEATABLE_READ"/> <transaction mode="BATCH"/> <remote-store cache="default" socket-timeout="60000" remote-servers="remote-rhdg-server1 remote-rhdg-server2" passivation="false" purge="false" shared="true"/> </invalidation-cache> ... </cache-container> </subsystem> 22.4. Configuring JBoss EAP as a front-end load balancer You can configure JBoss EAP and the undertow subsystem to act as a front-end load balancer to proxy requests to back-end JBoss EAP servers. Since Undertow makes use of asynchronous IO, the IO thread that is responsible for the connection is the only thread that is involved in the request. That same thread is also used for the connection made to the back-end server. You can use the following protocols: HTTP over plain text ( http ), supporting HTTP/1 and HTTP/2 ( h2c ) HTTP over secured connection ( https ), supporting HTTP/1 and HTTP/2 ( h2 ) AJP ( ajp ) You can either define a static load balancer and specify the back-end hosts in your configuration, or use the mod_cluster front end to dynamically update the hosts. 22.4.1. Configure undertow as a load balancer using mod_cluster You can use the built-in mod_cluster front-end load balancer to load balance other JBoss EAP instances. This procedure assumes that you are running in a managed domain and already have the following configured: A JBoss EAP server that will act as the load balancer. This server uses the load-balancer profile, which is bound to the load-balancer-sockets socket binding group. Note The load-balancer profile is already preconfigured with the socket binding, mod-cluster Undertow filter, and reference in the default host to the filter in order to use this server as a front-end load balancer. * Two JBoss EAP servers, which will act as the back-end servers. ** These servers are running in a cluster and use the ha profile, which is bound to the ha-sockets socket binding group. * The distributable application to be load balanced deployed to the back-end servers. Configure the mod_cluster front-end load balancer The below steps load balance servers in a managed domain, but they can be adjusted to apply to a set of standalone servers. Be sure to update the management CLI command values to suit your environment. Procedure Set the mod_cluster advertise security key. Adding the advertise security key allows the load balancer and servers to authenticate during discovery. Use the following management CLI command to set the mod_cluster advertise security key. Update the mod_cluster load balancer's security key. Use the following management CLI command to set the security key for the mod_cluster filter. Important It is recommended that the management and advertise socket bindings used by mod_cluster only be exposed to the internal network, not a public IP address. The load balancer JBoss EAP server can now load balance the two back-end JBoss EAP servers. Multiple mod_cluster configurations The mod_cluster subsystem supports multiple named proxy configurations which allows to register non-default undertow servers with the reverse proxies. Moreover, this allows single application server node to register with different groups of proxy servers. The following example adds an ajp-listener , a server, and a host to the undertow server. It also adds a new mod_cluster configuration that registers the host using the advertise mechanism. 22.4.2. Enabling ranked session affinity in your load balancer You must enable ranked session affinity in your load balancer to have session affinity with multiple, ordered routes in the distributable-web subsystem. For more information about the distributable-web subsystem and the different affinity options, see The distributable-web subsystem for distributable web session configurations in the Development Guide for JBoss EAP. The default delimiter that separates the node routes is . . If you want a different value, you can configure the delimiter attribute of the affinity resource. Procedure Enable ranked session affinity for a load balancer: Optional: Configure the delimiter attribute of the affinity resource: 22.4.3. Configure undertow as a static load balancer To configure a static load balancer with Undertow, you need to configure a proxy handler in the undertow subsystem. To configure a proxy handler in Undertow, you need to do the following on your JBoss EAP instance that will serve as your static load balancer: Add a reverse proxy handler Define the outbound socket bindings for each remote host Add each remote host to the reverse proxy handler Add the reverse proxy location The following example shows how to configure a JBoss EAP instance to be a static load balancer. The JBoss EAP instance is located at lb.example.com and will load balance between two additional servers: server1.example.com and server2.example.com . The load balancer will reverse-proxy to the location /app and will use the AJP protocol. Procedure To add a reverse proxy handler: To define the outbound socket bindings for each remote host: To add each remote host to the reverse proxy handler: To add the reverse proxy location: When accessing lb.example.com:8080/app , you will now see the content proxied from server1.example.com and server2.example.com . 22.5. Using an external web server as a proxy server JBoss EAP can accept requests from an external web server using the supported HTTP, HTTPS, or AJP protocol, depending on the external web server configuration. See Overview of HTTP Connectors for details on the supported HTTP connectors for each web server. Once you have decided which web server and HTTP connector to use, see the appropriate section for information on configuring your connector: See the mod_cluster , mod_jk , or mod_proxy section for Apache HTTP Server . See the ISAPI connector section for Microsoft IIS. See the NSAPI connector section for Oracle iPlanet Web Server. For the most current information about supported configurations for HTTP connectors, see JBoss EAP supported configurations . You also will need to make sure that JBoss EAP is configured to accept requests from external web servers . 22.5.1. Overview of HTTP connectors JBoss EAP has the ability to use load-balancing and clustering mechanisms built into external web servers, such as Apache HTTP Server, Microsoft IIS, and Oracle iPlanet as well as through Undertow. JBoss EAP communicates with the web servers using a connector. These connectors are configured within the undertow subsystem of JBoss EAP. The web servers include software modules which control the way that HTTP requests are routed to JBoss EAP nodes. Each of these modules varies in how it works and how it is configured. The modules are configured to balance work loads across multiple JBoss EAP nodes, to move work loads to alternate servers in case of a failure event, or both. JBoss EAP supports several different connectors. The one you choose depends on the web server in use and the functionality you need. See the tables below for comparisons of the supported configurations and features of the various HTTP connectors that are compatible with JBoss EAP. For more information about using JBoss EAP 8.0 as a multi-platform load balancer, see Configure Undertow as a load balancer using mod_cluster . For the most current information about supported configurations for HTTP connectors, see JBoss EAP supported configurations . Table 22.1. HTTP connector supported configurations Connector Web Server Supported Operating Systems Supported Protocols mod_cluster Red Hat JBoss Core Services Apache HTTP Server, {JWSProductName} Apache HTTP Server, JBoss EAP (Undertow) Red Hat Enterprise Linux, Microsoft Windows Server HTTP, HTTPS, AJP, WebSocket mod_jk Red Hat JBoss Core Services Apache HTTP Server, {JWSProductName} Apache HTTP Server Red Hat Enterprise Linux, Microsoft Windows Server AJP mod_proxy Red Hat JBoss Core Services Apache HTTP Server, {JWSProductName} Apache HTTP Server Red Hat Enterprise Linux, Microsoft Windows Server HTTP, HTTPS, AJP ISAPI connector Microsoft IIS Microsoft Windows Server AJP NSAPI connector Oracle iPlanet Web Server AJP Table 22.2. HTTP connector features Connector Supports Sticky Sessions Adapts to Deployment Status mod_cluster Yes Yes. Detects deployment and undeployment of applications and dynamically decides whether to direct client requests to a server based on whether the application is deployed on that server. mod_jk Yes No. Directs client requests to the container as long as the container is available, regardless of application status. mod_proxy Yes No. Directs client requests to the container as long as the container is available, regardless of application status. ISAPI connector Yes No. Directs client requests to the container as long as the container is available, regardless of application status. NSAPI connector Yes No. Directs client requests to the container as long as the container is available, regardless of application status. 22.5.2. Apache HTTP Server A standalone Apache HTTP Server bundle is now available as a separate download with Red Hat JBoss Core Services. This simplifies installation and configuration, and allows for a more consistent update experience. 22.5.2.1. Installing Apache HTTP Server For information on installing Apache HTTP Server, see the JBoss Core Services Apache HTTP Server Installation Guide . 22.5.3. Accepting requests from external web servers JBoss EAP does not require any special configuration to begin accepting requests from a proxy server as long as the correct protocol handler, for example AJP, HTTP, or HTTPS, is configured. If the proxy server uses mod_jk, mod_proxy, ISAPI, or NSAPI, it sends requests to JBoss EAP and JBoss EAP simply provides a response. With mod_cluster, you must also configure your network to allow JBoss EAP to send information, such as its current load, application lifecycle events, and health status, to the proxy server to help it determine where to route requests. For more information about configuring a mod_cluster proxy server, see The mod_cluster HTTP Connector . Update JBoss EAP configuration In the following procedure, substitute the protocols and ports in the examples with the ones you need to configure. Procedure Configure the instance-id attribute of Undertow. The external web server identifies the JBoss EAP instance in its connector configuration using the instance-id . Use the following management CLI command to set the instance-id attribute in Undertow. In the above example, the external web server identifies the current JBoss EAP instance as node1 . Add the necessary listeners to Undertow. In order for an external web server to be able to connect to JBoss EAP, Undertow needs a listener. Each protocol needs its own listener, which is tied to a socket binding. Note Depending on your desired protocol and port configuration, this step may not be necessary. An HTTP listener is configured in all default JBoss EAP configurations, and an AJP listener is configured if you are using the ha or full-ha profile. You can check whether the required listeners are already configured by reading the default server configuration: To add a listener to Undertow, it must have a socket binding. The socket binding is added to the socket binding group used by your server or server group. The following management CLI command adds an ajp socket binding, bound to port 8009 , to the standard-sockets socket binding group. The following management CLI command adds an ajp listener to Undertow, using the ajp socket binding. 22.6. The mod_cluster HTTP Connector The mod_cluster connector is an Apache HTTP Server-based load balancer. It uses a communication channel to forward requests from the Apache HTTP Server to one of a set of application server nodes. The mod_cluster connector has several advantages over other connectors. The mod_cluster Management Protocol (MCMP) is an additional connection between the JBoss EAP servers and the Apache HTTP Server with the mod_cluster module enabled. It is used by the JBoss EAP servers to transmit server-side load-balance factors and lifecycle events back to the Apache HTTP Server via a custom set of HTTP methods. Dynamic configuration of Apache HTTP Server with mod_cluster allows JBoss EAP servers to join the load-balancing arrangement without manual configuration. JBoss EAP performs the load-balancing factor calculations, rather than relying on the Apache HTTP Server with mod_cluster. This makes load-balancing metrics more accurate than other connectors. The mod_cluster connector gives fine-grained application lifecycle control. Each JBoss EAP server forwards web application context lifecycle events to the Apache HTTP Server, informing it to start or stop routing requests for a given context. This prevents end users from seeing HTTP errors due to unavailable resources. AJP, HTTP or HTTPS transports can be used. For more details on the specific configuration options of the modcluster subsystem, see the ModCluster Subsystem Attributes . 22.6.1. Configure mod_cluster in Apache HTTP Server The mod_cluster modules are already included when installing JBoss Core Services Apache HTTP Server or using JWS and are loaded by default. Note Apache HTTP Server is no longer distributed with JWS as of version 3.1.0. See the steps below to configure the mod_cluster module to suit your environment. Note Red Hat customers can also use the Load Balancer Configuration Tool on the Red Hat Customer Portal to quickly generate optimal configuration templates for mod_cluster and other connectors. Note that you must be logged in to access this tool. Configure mod_cluster Apache HTTP Server already contains a mod_cluster configuration file, mod_cluster.conf , that loads the mod_cluster modules and provides basic configuration. The IP address, port, and other settings in this file, shown below, can be configured to suit your needs. The Apache HTTP Server server is configured as a load balancer and can work with the modcluster subsystem running on JBoss EAP. You must configure a mod_cluster worker node to make JBoss EAP aware of mod_cluster. If you want to disable advertising for mod_cluster and configure a static proxy list instead, see Disable Advertisement for mod_cluster . For more information on the available mod_cluster configuration options in Apache HTTP Server, see the Apache HTTP Server mod_cluster Directives For more details on configuring mod_cluster, see the Configure Load Balancing Using Apache HTTP Server and mod_cluster section of the JWS HTTP Connectors and Load Balancing Guide . 22.6.2. Disable advertising for mod_cluster By default, the modcluster subsystem's balancer uses multicast UDP to advertise its availability to the background workers. You can disable advertising and to use a proxy list instead using the following procedure. Note The management CLI commands in the following procedure assume that you are using the full-ha profile in a managed domain. If you are using a profile other than full-ha , use the appropriate profile name in the command. If you are running a standalone server, remove the /profile=full-ha completely. Modify the Apache HTTP Server configuration. Edit the httpd.conf Apache HTTP Server configuration file. Make the following updates to the virtual host that listens for MCPM requests, using the EnableMCPMReceive directive. Add the directive to disable server advertisement. Set the ServerAdvertise directive to Off to disable server advertisement. Disable the advertise frequency. If your configuration specifies the AdvertiseFrequency parameter, comment it out using a # character. Enable the ability to receive MCPM messages. Ensure that the EnableMCPMReceive directive exists, to allow the web server to receive MCPM messages from the worker nodes. Disable advertising in the JBoss EAP modcluster subsystem. Use the following management CLI command to disable advertising. Important Be sure to continue to the step to provide the list of proxies. Advertising will not be disabled if the list of proxies is empty. Provide a list of proxies in the JBoss EAP modcluster subsystem. It is necessary to provide a list of proxies because the modcluster subsystem will not be able to automatically discover proxies if advertising is disabled. First, define the outbound socket bindings in the appropriate socket binding group. , add the proxies to the mod_cluster configuration. The Apache HTTP Server balancer no longer advertises its presence to worker nodes and UDP multicast is no longer used. 22.6.3. Configure a mod_cluster worker node A mod_cluster worker node consists of a JBoss EAP server. This server can be a standalone server or part of a server group in a managed domain. A separate process runs within JBoss EAP, which manages all of the worker nodes of the cluster. This is called the primary in a managed domain or the master in a standalone server. Worker nodes in a managed domain share an identical configuration across a server group. Worker nodes running as standalone servers are configured individually. The configuration steps are otherwise identical. A standalone server must be started with the standalone-ha or standalone-full-ha profile. A server group in a managed domain must use the ha or full-ha profile, and the ha-sockets or full-ha-sockets socket binding group. JBoss EAP ships with a cluster-enabled server group called other-server-group which meets these requirements. Configure a worker node The management CLI commands in this procedure assume that you are using a managed domain with the full-ha profile. If you are running a standalone server, remove the /profile=full-ha portion of the commands. Procedure Configure the network interfaces. By default, the network interfaces all default to 127.0.0.1 . Every physical host that hosts either a standalone server or one or more servers in a server group needs its interfaces to be configured to use its public IP address, which the other servers can see. Use the following management CLI commands to modify the external IP addresses for the management , public , and unsecure interfaces as appropriate for your environment. Be sure to replace EXTERNAL_IP_ADDRESS in the command with the actual external IP address of the host. Reload the server. Configure host names. Set a unique host name for each host that participates in a managed domain. This name must be unique across secondaries and will be used for the secondary to identify to the cluster, so make a note of the name you use. Start the JBoss EAP secondary host, using the appropriate host.xml configuration file. Use the following management CLI command to set a unique host name. This example uses secondary1 as the new host name. For more information on configuring a host name, see Configure the name of a host . Configure each host to connect to the domain controller. Note This step does not apply for a standalone server. + For newly configured hosts that need to join a managed domain, you must remove the local element and add the remote element host attribute that points to the domain controller. + .. Start the JBoss EAP secondary host, using the appropriate host.xml configuration file. + Use the following management CLI command to configure the domain controller settings. This modifies the XML in the host-secondary.xml file as follows: <domain-controller> <remote host=" DOMAIN_CONTROLLER_IP_ADDRESS " port="USD{jboss.domain.primary.port:9990}" security-realm="ManagementRealm"/> </domain-controller> For more information, see Host Controller Configuration . Configure authentication for each secondary host. Each secondary server needs a username and password created in the domain controller's primary or standalone's master ManagementRealm. On the domain controller primary or standalone master, run the EAP_HOME /bin/add-user.sh command for each host. Add a management user for each host with the username that matches the host name of the secondary. Be sure to answer yes to the last question, that asks "Is this new user going to be used for one AS process to connect to another AS process?", so that you are provided with a secret value. Example: add-user.sh Script Output (trimmed) Copy the Base64-encoded secret value provided from this output, SECRET_VALUE , which may be used in the step. For more information, see the Adding a user to the primary domain controller section of the JBoss EAP How To Configure Server Security guide. Modify the secondary host's security realm to use the new authentication. You can specify the password by setting the secret value in the server configuration, getting the password from a credential store or vault, or passing the password as a system property. Specify the Base64-encoded password value in the server configuration file using the Management CLI. Use the following management CLI command to specify the secret value. Be sure to replace the SECRET_VALUE with the secret value returned from the add-user output from the step. You will need to reload the server. The --host argument is not applicable for a standalone server. For more information, see the Configuring the secondary controllers to use the credential section of the JBoss EAP How To Configure Server Security guide. Configure the host to get the password from a credential store. If you have stored the secret value in a credential store, you can use the following command to set the server secret to be a value from a credential store: You will need to reload the server. The --host argument is not applicable for a standalone server. For more information, see the Credential store section of the JBoss EAP How To Configure Server Security guide. Configure the host to get the password from a vault. Use the EAP_HOME /bin/vault.sh script to generate a masked password. It will generate a string in the format VAULT::secret::password:: VAULT_SECRET_VALUE , for example: Note When creating a password in the vault, it must be specified in plain text, not Base64-encoded. Use the following management CLI command to specify the secret value. Be sure to replace the VAULT_SECRET_VALUE with the masked password generated in the step. You will need to reload the server. The --host argument is not applicable for a standalone server. For more information, see the Password vault section of the JBoss EAP How To Configure Server Security guide. Specify the password as a system property. The following examples use server.identity.password as the system property name for the password. Specify the system property for the password in the server configuration file. Use the following managemente CLI command to configure the secret identity to use the system property. You will need to reload the server. The --host argument is not applicable for a standalone server. Set the password for the system property when starting the server. You can set the server.identity.password system property by passing it as a command line argument or in a properties file. Pass in as a plain text command line argument. Start the server and pass in the server.identity.password property. Warning The password must be entered in plain text and will be visible to anyone who issues a ps -ef command. Set the property in a properties file. Create a properties file and add the key/value pair to a properties file, for example: Warning The password is in plain text and will be visible to anyone who has access to this properties file. + Start the server with the command line arguments. + Restart the server. The secondary will now authenticate to the primary using its host name as the username and the encrypted string as its password. Your standalone server, or servers within a server group of a managed domain, are now configured as mod_cluster worker nodes. If you deploy a clustered application, its sessions are replicated to all cluster nodes for failover, and it can accept requests from an external web server or load balancer. Each node of the cluster discovers the other nodes using automatic discovery, by default. 22.6.4. Configure the mod_cluster fail_on_status Parameter The fail_on_status parameter lists those HTTP status codes which, when returned by a worker node in a cluster, will mark that node as having failed. The load balancer will then send future requests to another worker node in the cluster. The failed worker node will remain in a NOTOK state until it sends the load balancer a STATUS message. The fail_on_status parameter must be configured in the httpd configuration file of your load balancer. Multiple HTTP status codes for fail_on_status can be specified as a comma-separated list. The following example specifies the HTTP status codes 203 and 204 for fail_on_status .  Example: Configuring fail_on_status 22.6.5. Migrate traffic between clusters After creating a new cluster using JBoss EAP, you can migrate traffic from the cluster to the new one as part of an upgrade process. In this task, you will see the strategy that can be used to migrate this traffic with minimal outage or downtime. A new cluster setup. We will call this cluster ClusterNEW . An old cluster setup that is being made redundant. We will call this cluster ClusterOLD . Upgrade process for clusters - load-balancing groups Set up your new cluster using the steps described in the prerequisites. In both ClusterNEW and ClusterOLD , ensure that the configuration option sticky-session is set to the default setting of true . Enabling this option means that all new requests made to a cluster node in any of the clusters will continue to go to the respective cluster node. Set the load-balancing-group to ClusterOLD , assuming that all the cluster nodes in ClusterOLD are members of the ClusterOLD load-balancing group. Add the nodes in ClusterNEW to the mod_cluster configuration individually using the process described in the Configure a mod_cluster Worker Node section. Additionally, use the aforementioned procedure and set their load-balancing group to ClusterNEW . At this point, you can see an output similar to the undermentioned shortened example on the mod_cluster-manager console: Any old active sessions are within the ClusterOLD group, and any new sessions are created either within the ClusterOLD or CLusterNEW group. , we want to disable the whole ClusterOLD group, so that its cluster nodes may be removed without causing any error to currently active client's sessions. Click on the Disable Nodes link for LBGroup ClusterOLD on the mod_cluster-manager web console. From this point on, only requests belonging to already established sessions will be routed to members of the ClusterOLD load-balancing group. Any new client's sessions will be created in the ClusterNEW group only. As soon as there are no active sessions within ClusterOLD group, we can safely remove its members. Note Using Stop Nodes would command the load balancer to stop routing any requests to this domain immediately. This will force a failover to another load-balancing group which will cause session data loss to clients, provided there is no session replication between ClusterNEW and ClusterOLD . Default load-balancing group In case the current ClusterOLD setup does not contain any load-balancing group settings, found from LBGroup: on the mod_cluster-manager console, one can still take advantage of disabling the ClusterOLD nodes. In this case, click on Disable Contexts for each of the ClusterOLD nodes. Contexts of these nodes will be disabled, and once there are no active sessions present they will be ready for removal. New clients' sessions will be created only on nodes with enabled contexts, presumably ClusterNEW members in this example. Using the management CLI In addition to using the mod_cluster-manager web console, you can use the JBoss EAP management CLI to stop or disable a particular context. Stop a context Stopping a context with waittime set to 0 , meaning no timeout, instructs the balancer to stop routing any request to it immediately, which forces failover to another available context. If you set a timeout value using the waittime argument, no new sessions are created on this context, but existing sessions will continue to be directed to this node until they complete or the specified timeout has elapsed. The waittime argument defaults to 10 seconds. Disable a context Disabling a context tells the balancer that no new sessions should be created on this context. 22.7. Apache mod_jk HTTP connector Apache mod_jk is an HTTP connector that is provided for customers who need it for compatibility purposes. JBoss EAP can accept workloads from an Apache HTTP proxy server. The proxy server accepts client requests from the web front end, and passes the work to participating JBoss EAP servers. If sticky sessions are enabled, the same client request always goes to the same JBoss EAP server, unless the server is unavailable. mod_jk communicates over the AJP 1.3 protocol. Other protocols can be used with mod_cluster or mod_proxy . See the Overview of HTTP Connectors for more information. Note mod_cluster is a more advanced load balancer than mod_jk and is the recommended HTTP connector. mod_cluster provides all of the functionality of mod_jk, plus additional features. Unlike the JBoss EAP mod_cluster HTTP connector, an Apache mod_jk HTTP connector does not know the status of deployments on servers or server groups, and cannot adapt where it sends its work accordingly. See the Apache mod_jk documentation for more information. 22.7.1. Configure mod_jk in Apache HTTP Server The mod_jk module, mod_jk.so , is already included when installing JBoss Core Services Apache HTTP Server or using JWS; however, it is not loaded by default. Note Apache HTTP Server is no longer distributed with JWS as of version 3.1.0. Use the following steps to load and configure mod_jk in Apache HTTP Server. Note that these steps assume that you have already navigated to the httpd/ directory for Apache HTTP Server, which will vary depending on your platform. For more information, see the installation instructions for your platform in the JBoss Core Services Apache HTTP Server Installation Guide . Note Red Hat customers can also use the Load balancer configuration tool on the Red Hat Customer Portal to quickly generate optimal configuration templates for mod_jk and other connectors. Note that you must be logged in to access this tool. Procedure Configure the mod_jk module. Note A sample mod_jk configuration file is provided at conf.d/mod_jk.conf.sample . You can use this sample instead of creating your own file by removing the .sample extension and modifying its contents as needed. Create a new file called conf.d/mod_jk.conf . Add the following configuration to the file, making sure to modify the contents to suite your needs. Note The JkMount directive specifies which URLs Apache HTTP Server must forward to the mod_jk module. Based on the directive's configuration, mod_jk sends the received URL to the correct workers. To serve static content directly and only use the load balancer for Java applications, the URL path must be /application/* . To use mod_jk as a load balancer, use the value /* , to forward all URLs to mod_jk. Aside from general mod_jk configuration, this file specifies to load the mod_jk.so module, and defines where to find the workers.properties file. Configure the mod_jk worker nodes. Note A sample workers configuration file is provided at conf.d/workers.properties.sample . You can use this sample instead of creating your own file by removing the .sample extension and modifying its contents as needed. Create a new file called conf.d/workers.properties . Add the following configuration to the file, making sure to modify the contents to suite your needs. For details on the syntax of the mod_jk workers.properties file and other advanced configuration options, see mod_jk Worker Properties . Optionally, specify a JKMountFile directive. In addition to the JKMount directive in the mod-jk.conf , you can specify a file which contains multiple URL patterns to be forwarded to mod_jk. Create a uriworkermap.properties file. Note A sample URI worker map configuration file is provided at conf.d/uriworkermap.properties.sample . You can use this sample instead of creating your own file by removing the .sample extension and modifying its contents as needed. Create a new file called conf.d/uriworkermap.properties . Add a line for each URL pattern to be matched, for example: Update the configuration to point to uriworkermap.properties file. Append the following to conf.d/mod_jk.conf . For more information about configuring mod_jk, see the Configuring Apache HTTP Server to load mod_jk section of the JWS HTTP connectors and load balancing guide . 22.7.2. Configure JBoss EAP to communicate with mod_jk The mod_jk HTTP connector has a single component, the mod_jk.so module loaded by the web server. This module receives client requests and forwards them to the container, in this case JBoss EAP. JBoss EAP must also be configured to accept these requests and send replies back to the web server. The JBoss EAP undertow subsystem needs to specify a listener in order to accept requests from and send replies back to an external web server. Since mod_jk uses the AJP protocol, an AJP listener must be configured. If you are using one of the default high availability configurations, ha or full-ha , an AJP listener is already configured. For instructions, see Accepting requests From external web servers . 22.8. Apache mod_proxy HTTP connector Apache mod_proxy is an HTTP connector that supports connections over AJP, HTTP, and HTTPS protocols. mod_proxy can be configured in load-balanced or non-load-balanced configurations, and it supports the notion of sticky sessions. The mod_proxy module requires JBoss EAP to have the HTTP, HTTPS or AJP listener configured in the undertow subsystem, depending on which protocol you plan to use. Note mod_cluster is a more advanced load balancer than mod_proxy and is the recommended HTTP connector. mod_cluster provides all of the functionality of mod_proxy, plus additional features. Unlike the JBoss EAP mod_cluster HTTP connector, an Apache mod_proxy HTTP connector does not know the status of deployments on servers or server groups, and cannot adapt where it sends its work accordingly. See the Apache mod_proxy documentation for more information. 22.8.1. Configure mod_proxy in Apache HTTP Server The mod_proxy modules are already included when installing JBoss Core Services Apache HTTP Server or using JWS and are loaded by default. Note Apache HTTP Server is no longer distributed with JWS as of version 3.1.0. See the appropriate section below to configure a basic load-balancing or non-load-balancing proxy. These steps assume that you have already navigated to the httpd/ directory for Apache HTTP Server, which will vary depending on your platform. For more information, see the installation instructions for your platform in the JBoss Core Services Apache HTTP Server Installation Guide . These steps also assume that the necessary HTTP listener has already been configured in the JBoss EAP undertow subsystem. Note Red Hat customers can also use the Load Balancer Configuration Tool on the Red Hat Customer Portal to quickly generate optimal configuration templates for mod_proxy and other connectors. Note that you must be logged in to access this tool. Add a non-load-balancing proxy Add the following configuration to your conf/httpd.conf file, directly beneath any other <VirtualHost> directives you may have. Replace the values with ones appropriate to your setup. Add a load-balancing proxy Note The default Apache HTTP Server configuration has the mod_proxy_balancer.so module disabled, as it is incompatible with mod_cluster. In order to complete this task, you will need to load this module and disable the mod_cluster modules. To use mod_proxy as a load balancer, and send work to multiple JBoss EAP instances, add the following configuration to your conf/httpd.conf file. The example IP addresses are fictional. Replace them with the appropriate values for your environment. The examples above all communicate using the HTTP protocol. You can use AJP or HTTPS protocols instead, if you load the appropriate mod_proxy modules. See the Apache mod_proxy documentation for more details. Enable sticky sessions A sticky session means that if a client request originally goes to a specific JBoss EAP worker, all future requests will be sent to the same worker, unless it becomes unavailable. This is almost always the recommended behavior. To enable sticky sessions for mod_proxy, add the stickysession parameter to the ProxyPass statement. You can specify additional parameters to the ProxyPass statement, such as lbmethod and nofailover . See the Apache mod_proxy documentation for more information on the available parameters. 22.8.2. Configure JBoss EAP to communicate with mod_proxy The JBoss EAP undertow subsystem needs to specify a listener in order to accept requests from and send replies back to an external web server. Depending on the protocol that you will be using, you may need to configure a listener. An HTTP listener is configured in the JBoss EAP default configuration. If you are using one of the default high availability configurations, ha or full-ha , an AJP listener is also preconfigured. For instructions, see Accepting requests from external web servers . 22.9. Microsoft ISAPI connector The Internet Server API (ISAPI) is a set of APIs used to write OLE Server extensions and filters for web servers such as Microsoft's Internet Information Services (IIS). isapi_redirect.dll is an extension of mod_jk adjusted to IIS. isapi_redirect.dll enables you to configure JBoss EAP instances as worker nodes with IIS as a load balancer. Note See JBoss EAP supported configurations for information on the supported configurations of Windows Server and IIS. 22.9.1. Configure Microsoft IIS to use the ISAPI connector Download the ISAPI connector from the Red Hat Customer Portal: Open a browser and log in to the Red Hat Customer Portal JBoss Software Downloads page . Select Web Connectors in the Product drop-down menu. Select the latest JBoss Core Services version from the Version drop-down menu. Find the Red Hat JBoss Core Services ISAPI Connector in the list, and click the Download link. Extract the archive and copy the contents of the sbin directory to a location on your server. The instructions below assume that the contents were copied to C:\connectors\ . To configure the IIS Redirector Using the IIS Manager (IIS 7): Open the IIS manager by clicking Start Run , and typing inetmgr . In the tree view pane at the left, expand IIS 7 . Double-click ISAPI and CGI Registrations to open it in a new window. In the Actions pane, click Add . The Add ISAPI or CGI Restriction window opens. Specify the following values: ISAPI or CGI Path : C:\connectors\isapi_redirect.dll Description : jboss Allow extension path to execute : select the check box. Click OK to close the Add ISAPI or CGI Restriction window. Define a JBoss Native virtual directory Right-click Default Web Site , and click Add Virtual Directory . The Add Virtual Directory window opens. Specify the following values to add a virtual directory: Alias : jboss Physical Path : C:\connectors\ Click OK to save the values and close the Add Virtual Directory window. Define a JBoss Native ISAPI Redirect Filter In the tree view pane, expand Sites Default Web Site . Double-click ISAPI Filters . The ISAPI Filters Features view appears. In the Actions pane, click Add. The Add ISAPI Filter window appears. Specify the following values in the Add ISAPI Filter window: Filter name : jboss Executable : C:\connectors\isapi_redirect.dll Click OK to save the values and close the Add ISAPI Filters window. Enable the ISAPI-dll handler Double-click the IIS 7 item in the tree view pane. The IIS 7 Home Features View opens. Double-click Handler Mappings . The Handler Mappings Features View appears. In the Group by combo box, select State . The Handler Mappings are displayed in Enabled and Disabled Groups . Find ISAPI-dll . If it is in the Disabled group, right-click it and select Edit Feature Permissions . Enable the following permissions: Read Script Execute Click OK to save the values, and close the Edit Feature Permissions window. Microsoft IIS is now configured to use the ISAPI connector. 22.9.2. Configure the ISAPI connector to send client requests to JBoss EAP This task configures a group of JBoss EAP servers to accept requests from the ISAPI connector. It does not include configuration for load-balancing or high-availability failover. This configuration is done on the IIS server, and assumes that you already have JBoss EAP configured to accept requests from an external web server . You also need full administrator access to the IIS server and to have configured IIS to use the ISAPI connector . Create property files and set up redirection Create a directory to store logs, property files, and lock files. The rest of this procedure assumes that you are using the directory C:\connectors\ for this purpose. If you use a different directory, modify the instructions accordingly. Create the isapi_redirect.properties file. Create a new file called C:\connectors\isapi_redirect.properties . Copy the following contents into the file. If you do not want to use a rewrite.properties file, comment out the last line by placing a # character at the beginning of the line. Create the uriworkermap.properties file The uriworkermap.properties file contains mappings between deployed application URLs and which worker handles requests to them. The following example file shows the syntax of the file. Place your uriworkermap.properties file into C:\connectors\ . Create the workers.properties file. The workers.properties file contains mapping definitions between worker labels and server instances. This file follows the syntax of the same file used for Apache mod_jk worker properties configuration. The following is an example of a workers.properties file. The worker names, worker01 and worker02 , must match the instance-id configured in the JBoss EAP undertow subsystem . Place this file into the C:\connectors\ directory. Create the rewrite.properties file. The rewrite.properties file contains simple URL rewriting rules for specific applications. The rewritten path is specified using name-value pairs, as shown in the example below. Place this file into the C:\connectors\ directory. Restart your IIS server by using the net stop and net start commands. The IIS server is configured to send client requests to the specific JBoss EAP servers you have configured, on an application-specific basis. 22.9.3. Configure the ISAPI connector to balance client requests across multiple JBoss EAP servers This configuration balances client requests across the JBoss EAP servers you specify. This configuration is done on the IIS server, and assumes that you already have JBoss EAP configured to accept requests from an external web server . You also need full administrator access to the IIS server and to have configured IIS to use the ISAPI connector . Balance client requests across multiple servers Create a directory to store logs, property files, and lock files. The rest of this procedure assumes that you are using the directory C:\connectors\ for this purpose. If you use a different directory, modify the instructions accordingly. Create the isapi_redirect.properties file. Create a new file called C:\connectors\isapi_redirect.properties . Copy the following contents into the file. If you do not want to use a rewrite.properties file, comment out the last line by placing a # character at the beginning of the line. Create the uriworkermap.properties file. The uriworkermap.properties file contains mappings between deployed application URLs and which worker handles requests to them. The following example file shows the syntax of the file, with a load-balanced configuration. The wildcard ( * ) character sends all requests for various URL sub-directories to the load balancer called router. The configuration of the load balancer is covered in the step. Place your uriworkermap.properties file into C:\connectors\ . Create the workers.properties file. The workers.properties file contains mapping definitions between worker labels and server instances. This file follows the syntax of the same file used for Apache mod_jk worker properties configuration. The following is an example of a workers.properties file. The load balancer is configured near the end of the file, to comprise workers worker01 and worker02 . These worker names must match the instance-id configured in the JBoss EAP undertow subsystem . Place this file into the C:\connectors\ directory.  Create the rewrite.properties file. The rewrite.properties file contains simple URL rewriting rules for specific applications. The rewritten path is specified using name-value pairs, as shown in the example below. Place this file into the C:\connectors\ directory. The IIS server is configured to send client requests to the JBoss EAP servers referenced in the workers.properties file, spreading the load across the servers in a 1:3 ratio. This ratio is derived from the load-balancing factor, lbfactor , assigned to each server. 22.10. Oracle NSAPI connector The Netscape Server API (NSAPI) is an API provided by Oracle iPlanet Web Server, formerly Netscape Web Server, for implementing extensions to the server. These extensions are known as server plugins. The NSAPI connector is used in nsapi_redirector.so , which is an extension of mod_jk adjusted to Oracle iPlanet Web Server. The NSAPI connector enables you to configure JBoss EAP instances as worker nodes with Oracle iPlanet Web Server as a load balancer. Note See the JBoss EAP supported configurations for information on the supported configurations of Oracle iPlanet Web Server. 22.10.1. Configure Oracle iPlanet web server to use the NSAPI connector Prerequisites JBoss EAP is installed and configured on each server that will serve as a worker. Download the NSAPI connector from the Red Hat Customer Portal: Open a browser and log in to the Red Hat Customer Portal JBoss Software Downloads page . Select Web Connectors in the Product drop-down menu. Select the latest JBoss Core Services version from the Version drop-down menu. Find the Red Hat JBoss Core Services NSAPI Connector in the list, ensuring that you select the correct platform and architecture for your system, and click the Download link. Extract the nsapi_redirector.so file, which is located in either the lib/ or the lib64/ directory, into either the IPLANET_CONFIG /lib/ or the IPLANET_CONFIG /lib64/ directory. Set up the NSAPI Connector: Note In these instructions, IPLANET_CONFIG refers to the Oracle iPlanet configuration directory, which is usually /opt/oracle/webserver7/config/ . If your Oracle iPlanet configuration directory is different, modify the instructions accordingly. Disable servlet mappings. Open the IPLANET_CONFIG /default.web.xml file and locate the section with the heading Built In Server Mappings . Disable the mappings to the following three servlets, by wrapping them in XML comment characters ( <!-- and --> ). default invoker jsp The following example configuration shows the disabled mappings. <!-- ============== 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 Jakarta Server Pages servlet --> <!--servlet-mapping> <servlet-name>jsp</servlet-name> <url-pattern>*.jsp</url-pattern> </servlet-mapping--> Save and exit the file. Configure the iPlanet Web Server to load the NSAPI connector module. Add the following lines to the end of the IPLANET_CONFIG /magnus.conf file, modifying file paths to suit your configuration. These lines define the location of the nsapi_redirector.so module, as well as the workers.properties file, which lists the workers and their properties. The configuration above is for a 32-bit architecture. Save and exit the file. Configure the NSAPI connector. You can configure the NSAPI connector for a basic configuration, with no load balancing, or a load-balancing configuration. Choose one of the following options, after which your configuration will be complete. Configure the NSAPI Connector to Send Client Requests to JBoss EAP Configure the NSAPI Connector to Balance Client Requests Across Multiple JBoss EAP Servers 22.10.2. Configure the NSAPI Connector to Send Client Requests to JBoss EAP This task configures the NSAPI connector to redirect client requests to JBoss EAP servers with no load balancing or failover. The redirection is done on a per-deployment, and therefore per-URL, basis. Important You must have already configured the NSAPI connector before continuing with this task. Set Up the Basic HTTP Connector Define the URL paths to redirect to the JBoss EAP servers. Note In IPLANET_CONFIG /obj.conf , spaces are not allowed at the beginning of a line, except when the line is a continuation of the line. Edit the IPLANET_CONFIG /obj.conf file. Locate the section which starts with <Object name="default"> , and add each URL pattern to match, in the format shown by the example file below. The string jknsapi refers to the HTTP connector which will be defined in the step. The example shows the use of wildcards for pattern matching. Define the worker which serves each path. Continue editing the IPLANET_CONFIG /obj.conf file. Add the following directly after the closing tag of the section you have just finished editing: </Object> . The example above redirects requests to the URL path /status to the worker called worker01 , and all URL paths beneath /nc/ to the worker called worker02 . The third line indicates that all URLs assigned to the jknsapi object which are not matched by the lines are served to worker01 . Save and exit the file. Define the workers and their attributes. Create a file called workers.properties in the IPLANET_CONFIG /connectors/ directory. Paste the following contents into the file, and modify them to suit your environment. The workers.properties file uses the same syntax as Apache mod_jk. Save and exit the file. Restart the iPlanet Web Server Issue the following command to restart the iPlanet Web Server. iPlanet Web Server now sends client requests to the URLs you have configured to deployments on JBoss EAP. 22.10.3. Configure the NSAPI Connector to Balance Client Requests Across Multiple JBoss EAP Servers This task configures the NSAPI connector to send client requests to JBoss EAP servers in a load-balancing configuration. Important You must have already configured the NSAPI connector before continuing with this task. Configure the Connector for Load Balancing Define the URL paths to redirect to the JBoss EAP servers. Note In IPLANET_CONFIG /obj.conf , spaces are not allowed at the beginning of a line, except when the line is a continuation of the line. Edit the IPLANET_CONFIG /obj.conf file. Locate the section which starts with <Object name="default"> , and add each URL pattern to match, in the format shown by the example file below. The string jknsapi refers to the HTTP connector that will be defined in the step. The example shows the use of wildcards for pattern matching. Define the worker that serves each path. Continue editing the IPLANET_CONFIG /obj.conf file. Directly after the closing tag for the section you modified in the step, </Object> , add the following new section and modify it to your needs: This jksnapi object defines the worker nodes used to serve each path that was mapped to the name="jksnapi" mapping in the default object. Everything except for URLs matching /jkmanager/* is redirected to the worker called router . Define the workers and their attributes. Create a file called workers.properties in IPLANET_CONFIG /connector/ . Paste the following contents into the file, and modify them to suit your environment. The workers.properties file uses the same syntax as Apache mod_jk. Save and exit the file. Restart the iPlanet Web Server 7.0. The iPlanet Web Server redirects the URL patterns you have configured to your JBoss EAP servers in a load-balancing configuration.
<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> /subsystem=jgroups/channel=ee:write-attribute(name=stack,value=tcp) <channel name="ee" stack="tcp" cluster="ejb"/> <server xmlns="urn:jboss:domain:8.0" name="node_1"> <servers> <server name="server-one" group="main-server-group"/> <server name="server-two" group="other-server-group"> <socket-bindings port-offset="150"/> </server> </servers> 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 /subsystem=jgroups/stack=tcpping/protocol=UNICAST3:add(add-index=6) EAP_HOME /bin/jboss-cli.sh --connect --file= /path/to/SCRIPT_NAME <channel name="ee" stack="tcp" cluster="ejb"/> <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> <interface name="private"> <inet-address value="USD{jboss.bind.address.private:192.168.1.5}"/> </interface> INFO [org.infinispan.remoting.transport.jgroups.JGroupsTransport] (thread-2,ee,node_1) ISPN000094: Received new cluster view for channel server: [node_1|1] (2) [node_1, node_2] INFO [org.infinispan.remoting.transport.jgroups.JGroupsTransport] (thread-2,ee,node_1) ISPN000094: Received new cluster view for channel web: [node_1|1] (2) [node_1, node_2] <protocol type="TCPPING"> <property name="initial_hosts">USD{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> <interfaces> . <interface name="private"> <inet-address value="USD{jboss.bind.address.private:192.168.1.5}"/> </interface> </interfaces> INFO [org.infinispan.remoting.transport.jgroups.JGroupsTransport] (thread-2,ee,node_1) ISPN000094: Received new cluster view for channel server: [node_1|1] (2) [node_1, node_2] INFO [org.infinispan.remoting.transport.jgroups.JGroupsTransport] (thread-2,ee,node_1) ISPN000094: Received new cluster view for channel web: [node_1|1] (2) [node_1, node_2] 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 /subsystem=jgroups/stack=tcpgossip/protocol=UNICAST3:add(add-index=6) EAP_HOME /bin/jboss-cli.sh --connect --file= /path/to/SCRIPT_NAME 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 /subsystem=jgroups/stack=JDBC_PING/protocol=UNICAST3:add(add-index=6) EAP_HOME /bin/jboss-cli.sh --connect --file= /path/to/SCRIPT_NAME <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"/> <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"/> keytool -genkeypair -alias jgroups_key -keypass my_password -storepass my_password -storetype jks -keystore jgroups.keystore -keyalg RSA /subsystem=elytron/key-store=jgroups-token-store:add(type=jks,path=/path/to/jgroups.keystore,credential-reference={clear-text=my_password}, required=true) <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"/> 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 <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> /subsystem=elytron/key-store=jgroups-keystore:add(path=/path/to/defaultStore.keystore,credential-reference={clear-text= PASSWORD },type=JCEKS) <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> <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> keytool -genkeypair -alias mykey -keyalg RSA -keysize 1024 -keystore defaultKeystore.keystore -dname "CN=localhost" -keypass secret -storepass secret /subsystem=elytron/key-store=jgroups-keystore:add(path=/path/to/defaultStore.keystore,credential-reference={clear-text= PASSWORD },type=JCEKS) <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> /subsystem=jgroups/stack= STACK_TYPE /transport= TRANSPORT_TYPE /thread-pool= THREAD_POOL_NAME :write-attribute(name= ATTRIBUTE_NAME , value= ATTRIBUTE_VALUE ) /subsystem=jgroups/stack=udp/transport=UDP/thread-pool=default:write-attribute(name="max-threads", value="500") 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) 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 /subsystem=jgroups/stack= STACK_NAME /transport= TRANSPORT /property= PROPERTY_NAME :add(value= BUFFER_SIZE ) /subsystem=jgroups/stack=tcp/transport= TRANSPORT /property=recv_buf_size:add(value=20000000) java -cp EAP_HOME /bin/client/jboss-client.jar org.jgroups.tests.McastReceiverTest -mcast_addr 230.11.11.11 -port 5555 java -cp EAP_HOME /bin/client/jboss-client.jar org.jgroups.tests.McastSenderTest -mcast_addr 230.11.11.11 -port 5555 <subsystem xmlns="{InfinispanSubsystemNamespace}"> <cache-container name="server" aliases="singleton cluster" default-cache="default" module="org.wildfly.clustering.server"> <transport lock-timeout="60000"/> <replicated-cache name="default"> <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"> <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"> <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"> <object-memory size="1000"/> <expiration max-idle="100000"/> </local-cache> <invalidation-cache name="entity"> <transaction mode="NON_XA"/> <object-memory size="1000"/> <expiration max-idle="100000"/> </invalidation-cache> <replicated-cache name="timestamps" mode="ASYNC"/> </cache-container> </subsystem> /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) <cache-container name="web" default-cache="concurrent" module="org.wildfly.clustering.web.infinispan"> <distributed-cache name="concurrent"> <file-store/> </distributed-cache> </cache-container> @Resource(lookup = "java:jboss/infinispan/cache/foo/bar") private org.infinispan.Cache<Integer, Object> cache; @Resource(lookup = "java:jboss/infinispan/cache/foo/default") @Resource(lookup = "java:jboss/infinispan/container/foo") private org.infinispan.manager.EmbeddedCacheManager manager; @Resource(lookup = "java:jboss/infinispan/configuration/foo/bar") private org.infinispan.config.Configuration config; @Resource(lookup = "java:jboss/infinispan/configuration/foo/default") private org.infinispan.config.Configuration config; <cache-container name="hibernate" default-cache="local-query" module="org.hibernate.infinispan"> <transport lock-timeout="60000"/> <local-cache name="local-query"> <object-memory size="1000"/> <expiration max-idle="100000"/> batch /subsystem=infinispan/cache-container=web/replicated-cache=repl:add() /subsystem=infinispan/cache-container=web/replicated-cache=repl/component=transaction:add(mode=BATCH) /subsystem=infinispan/cache-container=web/replicated-cache=repl/component=locking:add(isolation=REPEATABLE_READ) /subsystem=infinispan/cache-container=web/replicated-cache=repl/store=file:add /subsystem=infinispan/cache-container=web:write-attribute(name=default-cache,value=repl) run-batch reload /subsystem=infinispan/cache-container=web:write-attribute(name=default-cache,value=dist) /subsystem=infinispan/cache-container=web/distributed-cache=dist:write-attribute(name=owners,value=5) reload /subsystem=infinispan/cache-container=server/ CACHE_TYPE = CACHE /component=state-transfer:write-attribute(name=timeout,value=0) /subsystem=infinispan/cache-container= CACHE_CONTAINER_NAME /thread-pool= THREAD_POOL_NAME :write-attribute(name= ATTRIBUTE_NAME , value= ATTRIBUTE_VALUE ) /subsystem=infinispan/cache-container=server/thread-pool=persistence:write-attribute(name="max-threads", value="10") /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) /subsystem=infinispan/cache-container= CACHE_CONTAINER / CACHE_TYPE = CACHE :undefine-attribute(name=statistics-enabled) /subsystem=infinispan/cache-container=web/distributed-cache=dist/component=partition-handling:write-attribute(name=when-split, value=DENY_READ_WRITES) /socket-binding-group=standard-sockets/remote-destination-outbound-socket-binding= SOCKET_BINDING :add(host= HOSTNAME ,port= PORT ) batch /subsystem=infinispan/remote-cache-container= CACHE_CONTAINER :add(default-remote-cluster=data-grid-cluster) /subsystem=infinispan/remote-cache-container= CACHE_CONTAINER /remote-cluster=data-grid-cluster:add(socket-bindings=[ SOCKET_BINDING , SOCKET_BINDING_2 ,...]) run-batch /subsystem=infinispan/remote-cache-container=foo:write-attribute(name=statistics-enabled, value=true) /subsystem=infinispan/remote-cache-container=foo:read-attribute(name=connections) /subsystem=infinispan/remote-cache-container=foo:read-attribute(name=active-connections) /subsystem=infinispan/remote-cache-container=foo:read-attribute(name=idle-connections) /subsystem=infinispan/remote-cache-container=foo:read-resource-description /subsystem=infinispan/remote-cache-container=foo/remote-cache=bar.war:read-resource(include-runtime=true, recursive=true) { "average-read-time" : 1, "average-remove-time" : 0, "average-write-time" : 2, "hits" : 9, "misses" : 0, "near-cache-hits" : 7, "near-cache-invalidations" : 8, "near-cache-misses" : 9, "near-cache-size" : 1, "removes" : 0, "time-since-reset" : 82344, "writes" : 8 } /subsystem=infinispan/remote-cache-container=foo/remote-cache=bar.war:read-resource-description /subsystem=infinispan/remote-cache-container=foo/remote-cache=bar.war:reset-statistics() batch /subsystem=infinispan/cache-container=web/invalidation-cache= CACHE_NAME :add() /subsystem=infinispan/cache-container=web/invalidation-cache= CACHE_NAME /store=hotrod:add(remote-cache-container= CACHE_CONTAINER ,fetch-state=false,purge=false,passivation=false,shared=true) /subsystem=infinispan/cache-container=web/invalidation-cache= CACHE_NAME /component=transaction:add(mode=BATCH) /subsystem=infinispan/cache-container=web/invalidation-cache= CACHE_NAME /component=locking:add(isolation=REPEATABLE_READ) /subsystem=infinispan/cache-container=web:write-attribute(name=default-cache,value= CACHE_NAME ) run-batch @Resource(lookup = "java:jboss/infinispan/remote-container/web-sessions") private org.infinispan.client.hotrod.RemoteCacheContainer client; infinispan.client.hotrod.transport_factory = org.infinispan.client.hotrod.impl.transport.tcp.TcpTransportFactory infinispan.client.hotrod.server_list = 127.0.0.1:11222 infinispan.client.hotrod.marshaller = org.infinispan.commons.marshall.jboss.GenericJBossMarshaller infinispan.client.hotrod.async_executor_factory = org.infinispan.client.hotrod.impl.async.DefaultAsyncExecutorFactory infinispan.client.hotrod.default_executor_factory.pool_size = 1 infinispan.client.hotrod.default_executor_factory.queue_size = 10000 infinispan.client.hotrod.hash_function_impl.1 = org.infinispan.client.hotrod.impl.consistenthash.ConsistentHashV1 infinispan.client.hotrod.tcp_no_delay = true infinispan.client.hotrod.ping_on_startup = true infinispan.client.hotrod.request_balancing_strategy = org.infinispan.client.hotrod.impl.transport.tcp.RoundRobinBalancingStrategy infinispan.client.hotrod.key_size_estimate = 64 infinispan.client.hotrod.value_size_estimate = 512 infinispan.client.hotrod.force_return_values = false ## below is connection pooling config maxActive=-1 maxTotal = -1 maxIdle = -1 whenExhaustedAction = 1 timeBetweenEvictionRunsMillis=120000 minEvictableIdleTimeMillis=300000 testWhileIdle = true minIdle = 1 /subsystem=elytron/client-ssl-context= CLIENT_SSL_CONTEXT :add(key-manager= KEY_MANAGER ,trust-manager= TRUST_MANAGER ) /subsystem=infinispan/remote-cache-container= CACHE_CONTAINER /component=security:write-attribute(name=ssl-context,value= CLIENT_SSL_CONTEXT ) /core-service=management/security-realm=ApplicationRealm/server-identity=ssl:add(keystore-path=" KEYSTORE_NAME ",keystore-relative-to="jboss.server.config.dir",keystore-password=" KEYSTORE_PASSWORD ") /subsystem=datagrid-infinispan-endpoint/hotrod-connector=hotrod-connector/encryption=ENCRYPTION:add(require-ssl-client-auth=false,security-realm="ApplicationRealm") reload /socket-binding-group=standard-sockets/remote-destination-outbound-socket-binding=remote-rhdg-server1:add(host=RHDGHostName1, port=11222) /socket-binding-group=standard-sockets/remote-destination-outbound-socket-binding=remote-rhdg-server2:add(host=RHDGHostName2, port=11222) <socket-binding-group name="standard-sockets" ... > <outbound-socket-binding name="remote-rhdg-server1"> <remote-destination host="RHDGHostName1" port="11222"/> </outbound-socket-binding> <outbound-socket-binding name="remote-rhdg-server2"> <remote-destination host="RHDGHostName2" port="11222"/> </outbound-socket-binding> </socket-binding-group> /subsystem=infinispan/cache-container=web/invalidation-cache=rhdg:add(mode=SYNC) /subsystem=infinispan/cache-container=web/invalidation-cache=rhdg/component=locking:write-attribute(name=isolation,value=REPEATABLE_READ) /subsystem=infinispan/cache-container=web/invalidation-cache=rhdg/component=transaction:write-attribute(name=mode,value=BATCH) /subsystem=infinispan/cache-container=web/invalidation-cache=rhdg/store=remote:add(remote-servers=["remote-rhdg-server1","remote-rhdg-server2"], cache=default, socket-timeout=60000, passivation=false, purge=false, shared=true) <subsystem xmlns="{InfinispanSubsystemNamespace}"> <cache-container name="web" default-cache="dist" module="org.wildfly.clustering.web.infinispan" statistics-enabled="true"> <transport lock-timeout="60000"/> <invalidation-cache name="rhdg" mode="SYNC"> <locking isolation="REPEATABLE_READ"/> <transaction mode="BATCH"/> <remote-store cache="default" socket-timeout="60000" remote-servers="remote-rhdg-server1 remote-rhdg-server2" passivation="false" purge="false" shared="true"/> </invalidation-cache> </cache-container> </subsystem> /profile=ha/subsystem=modcluster/proxy=default:write-attribute(name=advertise-security-key, value=mypassword) /profile=load-balancer/subsystem=undertow/configuration=filter/mod-cluster=load-balancer:write-attribute(name=security-key,value=mypassword) /socket-binding-group=standard-sockets/socket-binding=ajp-other:add(port=8010) /subsystem=undertow/server=other-server:add /subsystem=undertow/server=other-server/ajp-listener=ajp-other:add(socket-binding=ajp-other) /subsystem=undertow/server=other-server/host=other-host:add(default-web-module=root-other.war) /subsystem=undertow/server=other-server/host=other-host /location=other:add(handler=welcome-content) /subsystem=undertow/server=other-server/host=other-host:write-attribute(name=alias,value=[localhost])) /socket-binding-group=standard-sockets/socket-binding=modcluster-other:add(multicast-address=224.0.1.106,multicast-port=23364) /subsystem=modcluster/proxy=other:add(advertise-socket=modcluster-other,balancer=other-balancer,connector=ajp-other) reload /subsystem=undertow/configuration=filter/mod-cluster=load-balancer/affinity=ranked:add /subsystem=undertow/configuration=filter/mod-cluster=load-balancer/affinity=ranked:write-attribute(name=delimiter,value=':') /subsystem=undertow/configuration=handler/reverse-proxy=my-handler:add /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) /subsystem=undertow/configuration=handler/reverse-proxy=my-handler/host=host1:add(outbound-socket-binding=remote-host1, scheme=ajp, instance-id=myroute1, path=/test) /subsystem=undertow/configuration=handler/reverse-proxy=my-handler/host=host2:add(outbound-socket-binding=remote-host2, scheme=ajp, instance-id=myroute2, path=/test) /subsystem=undertow/server=default-server/host=default-host/location=\/test:add(handler=my-handler) /subsystem=undertow:write-attribute(name=instance-id,value=node1) /subsystem=undertow/server=default-server:read-resource /socket-binding-group=standard-sockets/socket-binding=ajp:add(port=8009) /subsystem=undertow/server=default-server/ajp-listener=ajp:add(socket-binding=ajp) 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> ServerAdvertise Off AdvertiseFrequency 5 EnableMCPMReceive /profile=full-ha/subsystem=modcluster/proxy=default:write-attribute(name=advertise,value=false) /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) /profile=full-ha/subsystem=modcluster/proxy=default:list-add(name=proxies,value=proxy1) /profile=full-ha/subsystem=modcluster/proxy=default:list-add(name=proxies,value=proxy2) /interface=management:write-attribute(name=inet-address,value="USD{jboss.bind.address.management: EXTERNAL_IP_ADDRESS }") /interface=public:write-attribute(name=inet-address,value="USD{jboss.bind.address.public: EXTERNAL_IP_ADDRESS }") /interface=unsecure:write-attribute(name=inet-address,value="USD{jboss.bind.address.unsecure: EXTERNAL_IP_ADDRESS }") reload EAP_HOME /bin/domain.sh --host-config=host-secondary.xml /host= EXISTING_HOST_NAME :write-attribute(name=name,value=secondary1) EAP_HOME /bin/domain.sh --host-config=host-secondary.xml /host= SECONDARY_HOST_NAME :write-remote-domain-controller(host= DOMAIN_CONTROLLER_IP_ADDRESS ,port=USD{jboss.domain.primary.port:9990},security-realm="ManagementRealm") <domain-controller> <remote host=" DOMAIN_CONTROLLER_IP_ADDRESS " port="USD{jboss.domain.primary.port:9990}" security-realm="ManagementRealm"/> </domain-controller> 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 : secondary1 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 'secondary1' 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 secondary host controller connecting to the primary or for a Remoting connection for server to server {JEB} calls. yes/no? yes To represent the user add the following to the server-identities definition <secret value=" SECRET_VALUE " /> /host= SECONDARY_HOST_NAME /core-service=management/security-realm=ManagementRealm/server-identity=secret:add(value=" SECRET_VALUE ") reload --host= HOST_NAME /host= SECONDARY_HOST_NAME /core-service=management/security-realm=ManagementRealm/server-identity=secret:add(credential-reference={store= STORE_NAME ,alias= ALIAS } reload --host= HOST_NAME VAULT::secret::password::ODVmYmJjNGMtZDU2ZC00YmNlLWE4ODMtZjQ1NWNmNDU4ZDc1TElORV9CUkVBS3ZhdWx0. /host=primary/core-service=management/security-realm=ManagementRealm/server-identity=secret:add(value="USD{VAULT::secret::password:: VAULT_SECRET_VALUE }") reload --host= HOST_NAME /host= SECONDARY_HOST_NAME /core-service=management/security-realm=ManagementRealm/server-identity=secret:add(value="USD{server.identity.password}") reload --host=primary EAP_HOME /bin/domain.sh --host-config=host-secondary.xml -Dserver.identity.password=changeme server.identity.password=changeme EAP_HOME /bin/domain.sh --host-config=host-secondary.xml --properties= PATH_TO_PROPERTIES_FILE ProxyPass / balancer://MyBalancer stickysession=JSESSIONID|jsessionid nofailover=on failonstatus=203,204 ProxyPassReverse / balancer://MyBalancer ProxyPreserveHost on /profile=full-ha/subsystem=modcluster/proxy=default:write-attribute(name=sticky-session,value=true) /profile=full-ha/subsystem=modcluster/proxy=default:write-attribute(name=load-balancing-group,value=ClusterOLD) 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] /host=primary/server=server-one/subsystem=modcluster:stop-context(context=/my-deployed-application-context, virtualhost=default-host, waittime=0) /host=primary/server=server-one/subsystem=modcluster:disable-context(context=/my-deployed-application-context, virtualhost=default-host) 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> 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 Simple worker configuration file /*=loadbalancer 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 <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> <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> ProxyPass / balancer://mycluster stickysession=JSESSIONID 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 images and css files for path /status are provided by worker01 /status=worker01 /images/*=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 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 #Simple example Images are accessible under abc path /app-01/abc/=/app-01/images/ C:\> net stop was /Y C:\> net start w3svc 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 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 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 #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 <!-- ============== 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 Jakarta Server Pages servlet --> <!--servlet-mapping> <servlet-name>jsp</servlet-name> <url-pattern>*.jsp</url-pattern> </servlet-mapping--> 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" <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> <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> 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 IPLANET_CONFIG /../bin/stopserv IPLANET_CONFIG /../bin/startserv <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> <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> 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 IPLANET_CONFIG /../bin/stopserv IPLANET_CONFIG /../bin/startserv