ONJava.com    
 Published on ONJava.com (http://www.onjava.com/)
 See this if you're having trouble printing code examples


Clustering with JBoss 3.0

by Bill Burke, Sacha Labourey
07/10/2002

Whenever an organization thinks about building and deploying a J2EE application, they think scalability and reliability. How can my Web site stay up 24/7? Will my infrastructure be able to handle the traffic? How can I ensure that I don't lose any transactions or data? How do I manage large server farms?

To answer these questions, many Java architects look to their application server's clustering features. This article looks at the kinds of features needed to develop robust J2EE applications and how JBoss 3.0, an open source J2EE application server, can be the solution of choice.

JBoss Features

The following is a clustering feature overview for JBoss 3.0:

For a more detailed feature matrix, see this PDF file.

Fail-over and Load-Balancing

HTTP and EJB

A good J2EE application needs to be scalable and reliable. HTTP session replication and EJB client fail-over are the first things people usually think about. Although JBoss does provide these features, you need to ask yourself the question, "Do I really need to cluster-enable my HTTP sessions and EJBs?"

For Web applications, a hardware- or software-based HTTP load-balancer usually sits in front of the application servers within a cluster. These load-balancers can be used to decrypt HTTPS requests quickly, distribute the load between nodes in the cluster, and detect server failures. The usual setup is to have a user session live entirely on one server that is picked by the load-balancer. This is called a "sticky" session.

HTTP session replication is expensive for a J2EE application server. If you can live with forcing a user to log in again after a server failure, then an HTTP load-balancer probably provides all of the fail-over and load-balancing functionality you need, as far as HTTP requests go. Also, since JBoss recommends running your servlet engine (Tomcat or Jetty) within the same VM for performance reasons, you really don't need EJB fail-over or replication either.

Some available HTTP load-balancers are:

JNDI

Now, you may not need HTTP-session or EJB clustering, but if you are storing things other than EJB Home references in your JNDI tree, then you may need clustered JNDI. JBoss has a cluster-wide JNDI tree that is replicated across the entire cluster. It requires no additional configuration and boots up with a cluster-enabled JBoss configuration. Remote JBoss JNDI clients can also implicitly use multicast to discover the JNDI tree.

Cluster Management

It should be easy to configure the J2EE nodes that make up your cluster. You shouldn't have to manage lists of servers or hire an expensive consultant to do the magic to get your cluster up and running. One of the primary goals of the first release of JBoss clustering was for it to run out-of-the-box with minimal (or no) additional configuration.

Auto Discovery

JBoss cluster nodes automatically discover each other when they boot up -- out-of-the-box and with no additional configuration. Nodes that join the cluster at a later time have their state automatically initialized and synchronized by the rest of the group. As EJBs are deployed, all nodes in the cluster update their lists of standby fail-over targets. This applies to client proxies as well. Clustering should be seamless to the client application and the application server. Auto-discovery is one of the things that make this possible.

Installation

As your cluster topology starts to grow beyond two nodes, management of installations and upgrades of your application can become a problem. Although NFS could be used to alleviate this, it could introduce a single point of failure into the system and is not viable in some large, geographically distributed applications.

To solve this problem, JBoss 3.0 introduces the concept of a net-boot through its JMX Microkernel-based architecture. With a small 40K JAR, you can boot up an entire cluster-enabled J2EE application just by supplying a URL on the command line. You can try a demo of this.

Deployment

Some organizations require 24/7 availability. A good part of this is the ability to deploy new applications and new versions, and to apply patches, without bringing down the application server for maintenance. Most application servers have the concept of hot-deployment at runtime for EJBs. JBoss 3.0 takes this concept to a much higher level.

With its JMX-based Microkernel architecture, JBoss 3.0 has the innate ability to hot-deploy, undeploy, and redeploy any type of component at runtime simply by copying the component to a deploy directory. This includes EJBs, EARs, WARs, JAR libraries, data sources, database pools, and new JMS topics or queues; basically anything. In fact, you could cycle an entire new version of the whole application server and all of its applications at runtime if you really wanted to.

JBoss farming takes this hot-deployment feature cluster-wide. Copying a deployable component to just one node's deployment directory causes it to be deployed (or re-deployed) across the entire cluster. Removing a component from just one node's deployment directory causes it to be undeployed across the entire cluster. This is a great way to easily patch your entire cluster with a new version.

Architectural Overview

This section provides a brief architectural overview on clustering in JBoss 3.0.

Proxies

JBoss clustering leverages smart proxies to implement load-balancing and fail-over for EJB remote clients. These proxies manage a list of available RMI connections to the EJB containers that implement the proxy's EJB within the cluster. Depending on the configured load-balance policy, the proxy picks what RMI connection it will use to service an invocation. The proxy will also fail over to one of these standby RMI connections on a communication failure. If the JBoss cluster detects an addition to itself, or a node failure, the list of available RMI connections for an EJB is updated. This list is piggybacked onto the invocation response to the client if a membership change has occurred.

Layered Architecture

JBoss clustering has a layered architecture. The lowest layer of the architecture is a communication layer that provides group membership and communication protocols. An abstraction framework has been written on top of the layer to facilitate a plug-in architecture for other possible third-party distribution methods. Two clustering services, the Replicant Manager and Distributed State Service, use the abstraction framework to implement some basic functionality that is core to EJB proxies, clusterable RMI servers, JNDI and state replication.

JavaGroups

JavaGroups is currently the communication layer for JBoss clustering. JavaGroups is a toolkit for reliable group communication and management. It provides some of these core feature that were invaluable in making clustering work:

Clustering Framework

JBoss uses an abstraction framework to isolate communication layers like JavaGroups. This was done so that other third-party group communication frameworks could be incorporated into JBoss seamlessly and easily. This framework also provides the tools and interfaces for you to write your own clusterable services and components to plug into the JBoss JMX backbone.

Clustering Services

Two services use the Clustering Framework to implement some core functionality that is used by other clusterable components (EJB, JNDI, RMI, etc.). The first is the Distributed State Service. This service manages data that is uniform across the cluster. An example is the replicated state of a Stateful Session Bean. Another service is the Replicant Manager. The Replicant Manager's job is to manage data that is possibly different across the cluster. An example is the list of RMI connections used by clustered EJB smart proxies.

Along with the abstraction framework, you can use these services to build more advanced clusterable components that fit your needs. Any type of serializable object can be registered to be replicated by these services. Custom management objects can also listen for change events for each of these individual replicated objects. This gives you very granular control of the state replicated in your cluster.

JMX Bus

Finally, all of these components are configurable and accessible through JMX.

Getting Started

Now that you've read about some of the nice clustering features of JBoss 3.0, let's take a look at how easy it is to use them.

Using Clustered EJBs

Since nodes in a JBoss cluster automatically discover the existence of one another, it is very easy to set up your EJBs to be cluster-enabled. Simply setting a clustering flag in the JBoss-specific bean deployment descriptor, jboss.xml, is enough to enable load-balancing, fail-over, and state replication for your beans.

Example 1. jboss.xml

<?xml version="1.0" encoding="UTF-8"?>
<jboss>
  <enterprise-beans>
  <session>
    <ejb-name>MyEJB</ejb-name>
    <jndi-name>MyEJB</jndi-name>
    <clustered>true</clustered>
  </session>
  <entity>
    <ejb-name>MyEntity</ejb-name>
    <jndi-name>MyEntity</jndi-name>
    <clustered>true</clustered>
  </entity>
</jboss>

Using Cluster-wide JNDI

Remote clients can connect to and use the cluster-wide JNDI tree simply by leaving the provider URL undefined. JBoss will use IP multicast to discover clustered JNDI.

Example 2. jndi.properties

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces

Using Farming

Farming is not enabled by default, so you'll have to set it up yourself. Simply create the XML file shown below and copy it to the JBoss deploy directory $JBOSS_HOME/server/all/deploy.

Example 3. farm-service.xml

<?xml version="1.0" encoding="UTF-8"?>
  
<server>
  <classpath codebase="lib" archives="jbossha.jar"/>
  <!--these depends tags no longer do anything
    <depends>jboss:service=Naming</depends>
    <depends>jboss.system:service=ServiceDeployer</depends>
    <depends>jboss:service=DefaultPartition</depends>
  -->
  <mbean code="org.jboss.ha.framework.server.FarmMemberService" 
     name="jboss:service=FarmMember,partition=DefaultPartition" >
    <attribute name="PartitionName">DefaultPartition</attribute>
    <attribute name="FarmDeployDirectory">./farm</attribute>
    <attribute name="ScannerName">jboss.deployment:type=DeploymentScanner,flavor=URL</attribute>
  </mbean>
</server>

After deploying farm-service.xml, you are ready to rumble. With the above configuration, just copy your farmed components into the $JBOSS_HOME/server/all/farm directory, and they will be hot-deployed across the cluster.

Starting JBoss

JBoss 3.0 comes with three different ready-to-use server configurations: minimal, default, and all. Clustering is only enabled in the all configuration. To run this configuration, you must execute JBoss as follows:

$ run.sh ñc all

Conclusion

JBoss clustering is designed to be simple to configure and simple to extend. It is one of the final pieces of the puzzle that makes JBoss a viable open source competitor to other enterprise J2EE offerings.

For more information on advanced JBoss clustering configurations and design, we offer for-pay documentation at the JBoss Web site.

Bill Burke, Sacha Labourey is a Fellow at the JBoss division of REd Hat Inc. A long time JBoss contributor and architect, his current project is RESTEasy, RESTful Web Services for Java.


Return to ONJava.com.

Copyright © 2009 O'Reilly Media, Inc.