A cluster is a logical group of servers that work together to provide more reliability and scalability than a single server could. A cluster will appear to its client as a single server. Scalability is increased because a cluster's capacity is not constrained to a single server. Many application environments support the ability to add resources to a cluster dynamically, to increase capacity. A cluster can also provide high availability, because a service deployed on multiple servers insulates a caller from localized failures. Many application servers provide clusterable interfaces to:
Enterprise Java Beans (EJB)
Remote Method Invocation (RMI/IIOP)
Java Messaging Service (JMS)
JDBC Connections: connection pools and data sources
The typical Java Web service will be deployed on top of an application server. Many application servers themselves provide the ability to cluster instances of services across multiple machines. In this scenario, each instance of a service is referred to as a replica. Typically, the majority of newly developed Java-based services will use the EJB model. Many application servers generate a replica-aware stub. This process happens when an EJB is compiled using the EJB compiler.
Because EJBs use Remote Method Invocation (RMI) for their transport, the replica-aware stub appears as a normal RMI stub. The main difference is that the stub points to a collection of replicas. The stubs may use the Java Naming and Directory Interface (JNDI) to locate instances of objects, because a cluster stores its entire object collection in a replicated JNDI tree. Many stub implementations also contain a load-balancing algorithm that helps them determine the next object to bind to. This form of separation provides a transparent method for the caller to access objects in the cluster. When a stub fails in its operations, it will intercept any exceptions and retry the call using another replica. This provides transparent failover.
When designing a Web service, it is best to avoid making the service stateful. If your service uses a stateless session bean, a replica-aware stub can route the request to any server in the cluster. This is possible because a stateless bean holds zero state for the caller; the stub is free to select any server for which the bean has been deployed. If you must use a stateful bean, the stub may route the request to the original server and, optionally, to a secondary server, but this is application-server dependent.
Capacity planning of a cluster-based implementation also requires understanding the underlying network topology, including routers, switches, load balancers, firewalls, Web servers, and other network appliances. Basic Web service cluster architecture includes elements that handle availability and failover for the various tiers (Web tier, application tier, database tier and so on).
A simplistic implementation will most likely start with reducing failure between clients and the cluster itself, because this is usually where most failures occur. By separating logical tiers, it affords many application servers the ability to load-balance method calls to local EJBs. As previously discussed, in many implementations, a stub will usually bind to an EJB that is local over one that is remote. In a cluster, when a load to any individual server becomes unbalanced, it may sometimes be better to incur a remote method call than a local one, for performance purposes.
The network diagram in Figure 16.6 illustrates an ideal multi-tier cluster architecture. In this architecture, the Web tier may host static HTTP pages, Java Server Pages (JSP), or servlets. Its function is to serve as a client to clustered objects (EJBs) that reside on the application tier. Many application servers may also allow you to enable session replication, but this is not necessary in a well-planned Java Web services architecture.
The application tier holds instances of stateless session beans and other clusterable objects and handles the synchronization between servers in the cluster. Separating the Web and application tier provides the ability to load-balance on each method call but may eliminate optimization features of many EJB stub implementations.
This approach affords several advantages, including the potential to reduce hardware and software costs, improved server load balancing, higher availability, and better security. If a client must access a Web service exposed over HTTP, and the request is exclusively satisfied at this tier, you can reduce the number of servers running on the application tier and increase the number on the Web tier, producing better response times.
The above design also uses features built into many application servers, such as WebSphere, iPlanet, and others, to replicate state across members within a cluster. A multi-tier architecture creates fewer points of failure. If a server hosting a particular EJB fails, the servlet/JSP facilities are not affected. Introducing another level of separation also increases security. By providing separation, you can use firewall policies that allow access only to servlets/JSPs via HTTP.