EJBs can be configured to operate in a clustered environment, leveraging WebLogic's support for load balancing and failover. In a single-server configuration, the client uses WebLogic-specific stubs corresponding to the EJBHome and EJBObject interfaces. When you deploy EJBs to a WebLogic cluster or to multiple Managed Servers, WebLogic supplies specialized versions of the EJB home and EJB object stubs. Both of these stubs provide load-balancing and failover support, first at the level of looking up a home object, and second at the level of invoking an EJB method. As discussed in Chapter 4, any of the features of WebLogic's clustered EJB support come directly from the operation of RMI objects in a clustered environment.
A cluster-aware EJBHome stub knows about the EJBHome objects on all WebLogic servers in the cluster. Client calls to the home stub are load-balanced between the servers to which the EJB has been deployed. The cluster-aware stub also provides failover for lookup requests by automatically routing requests to another available server in the cluster, when the original server hosting an EJB becomes unreachable. WebLogic supports clustered home stubs for all the EJB types the home-is-clusterable element in the weblogic-ejb-jar.xml descriptor file determines whether the home object for an EJB is cluster-aware. If you specify true as the value of this setting, the EJB compiler ensures that the home stubs for the EJB are cluster-aware. By default, EJB home stubs are clusterable, which means an EJB can be deployed to a cluster.
The EJBObject stub provides similar functionality, but for method calls instead. These stubs can be made replica-aware, in which case they maintain a list of all copies of the EJBObject that reside on other servers within the cluster. A replica-aware EJBObject stub can distribute method calls across these available servers and automatically reroute method calls to an EJB instance on another available server. However, certain restrictions are imposed on the use of replica-aware stubs and failover, and we shall examine them shortly.
10.6.1 Failover and Replication
As mentioned earlier, WebLogic supports failover when you use a cluster-aware home object to look up an EJB object, and when you invoke an EJB method using a replica-aware EJB object. Clustered stubs are generated automatically during EJB compilation. In WebLogic 8.1, the appc compiler passes the EJB interfaces through to the RMI compiler, which then generates the cluster-aware stubs. The same process occurs in WebLogic 7.0 when using the ejbc compiler. A clustered stub essentially encapsulates logic that enables it to locate a home object or an EJB on any one of the available servers.
Whenever an EJB component is deployed to multiple Managed Servers, its EJB home object is bound to a cluster-wide naming service. Each server binds an instance of the home object under the same JNDI name. When a client asks the JNDI tree for the EJB's home object, it acquires a cluster-aware stub that can locate home objects on each server to which the EJB component is deployed. When a client invokes any of the create( ) or find( ) methods on the EJB's home object, the clustered home stub routes the request to one of the active members of the cluster. If one of the Managed Servers in the cluster becomes unreachable (perhaps because of an unexpected failure), the clustered home object is able to transparently redirect the request to another available server that hosts the same EJB.
Using a clustered home object, a client can obtain a replica-aware server-side EJBObject stub that can locate replicas on all available servers that host the EJB. The EJBObject stub can detect any attempts to invoke an EJB method on a failed replica, and can automatically reroute the method call to another available server.
WebLogic provides automatic failover when the failure occurs between method calls to the EJB i.e., after a method completes, or if the EJB container is unable to contact a server in the first place. By default, if a failure occurs during an EJB method call, WebLogic will not automatically fail over to another available server that hosts the same EJB component. Automatic failover during a method call can occur only if the particular EJB method is marked as idempotent. By marking the methods as such, you are guaranteeing that repeated calls to the same method with identical arguments have the same effect as a single method call. This guarantee is needed to ensure that database updates performed by an EJB method aren't duplicated when the same method is retried on another EJB on another server.
You can use the idempotent-methods setting to indicate which EJB methods may be considered idempotent by the EJB container. The following XML stanza marks all EJB methods for the Patient entity bean as idempotent:
PatientEJB ... ... PatientEJB Remote *
10.6.1.1 Stateless session beans
Stateless session EJBs support both cluster-aware home objects and replica-aware EJB objects. To enable cluster-aware home stubs to be generated, specify true for the home-is-clusterable element. To enable replica-aware EJB objects, specify true for the stateless-bean-is-clusterable element in the weblogic-ejb-jar.xml descriptor file. By default, an EJB method isn't considered idempotent. So, if you want method failover, you will need to include an XML stanza describing which methods are idempotent, as mentioned earlier. The following XML fragment illustrates how to enable these settings for the Registration EJB, assuming that it will be deployed to a WebLogic cluster:
 In WebLogic 7.0, you also can use the stateless-beans-are-idempotent element in the weblogic-ejb-jar.xml descriptor file to indicate that the methods of the EJB are idempotent. This element is deprecated in WebLogic 8.1 in favor of the idempotent-methods element.
RegistrationEJB 15 5 true true org.foo.bar.RegistrationHome ... RegistrationEJB Remote *
10.6.1.2 Stateful session beans
Clustered stateful session EJBs also use cluster-aware home stubs. Failover for stateful session EJBs is rather different, though, and is based on in-memory replication. The EJB container transparently replicates the state of the EJB to another clustered WebLogic instance. In-memory replication for stateful session beans works along the same lines as HTTP session-state replication. When replicating HTTP session state, WebLogic uses the session-tracking cookie to keep track of the primary and secondary servers. In the case of stateful session EJBs, it is the replica-aware EJBObject stub that keeps track of the primary and secondary servers needed for replicating the state of the EJB.
As the EJBObject stub is replica-aware, it maintains a list of all available servers that host the EJB component. The primary server hosts the actual EJB instance (and its state) with which a client interacts. When a client obtains an EJB object, the target server automatically chooses a secondary server to host the replicated state of the stateful session EJB instance. Now, the EJBObject stub will keep track of the primary server that the client first connected to, and of the secondary server that is used for replicating the EJB's state. WebLogic keeps the replica on the secondary server in sync with any changes that the client makes to the EJB's state. If the EJB instance is involved in a transaction, its state is replicated once the transaction is committed.
Typically, WebLogic replicates the EJB's state to another member of the cluster, or chooses the secondary server from a replication group (if it exists). Whenever possible, WebLogic chooses a server that isn't collocated on the same machine that hosts the primary server. Chapter 14 covers replication groups in more detail.
If the primary server fails, the EJB stub automatically redirects the next method call to the replica hosted on the secondary server. The secondary server creates a new EJB instance using the replicated session data, and processing continues. The secondary server now becomes the primary server for the EJB instance, and a new server is chosen to replicate the EJB's state. The replica-aware EJBObject stub then will update its list of available servers that host the EJB, as well as the locations of the primary and secondary servers for the client.
In order to enable in-memory state replication for clustered stateful session EJBs, you need to do the following:
In general, a client is guaranteed to have access to the last committed state of the stateful session EJB, even if the primary server fails. However, under certain rare conditions, a client will be unable to access the last committed state:
These are exceptional circumstances that shouldn't dissuade you from using stateful session beans in a clustered environment. The fact that WebLogic supports failover for stateful session beans is crucial in a production environment.
10.6.1.3 Entity beans
Clustered entity EJBs also support cluster-aware home stubs once you set the home-is-clusterable element in the weblogic-ejb-jar.xml descriptor. The clustering behavior is somewhat different, depending on whether the entity bean is a read-only or read-write bean.
For read-only entity beans, the home object returns a replica-aware stub that load-balances on every method call. However, it doesn't automatically fail over to a replica when a server becomes unavailable. For read-write entity beans, load balancing and failover occur only at the EJBHome level. The cluster-aware home object returns an EJBObject stub pinned to that server. Multiple instances of the entity bean may exist, each within its own server within the cluster. Because of this, each EJB instance needs to do the following:
Thus, read-write entity beans deployed to multiple servers behave in the same way as EJBs deployed to a single-server configuration.
10.6.2 Load Balancing
WebLogic supports several algorithms for load-balancing requests to clustered EJB objects: round-robin, weight-based, and random. WebLogic 8.1 supports additional affinity-based load-balancing algorithms, which attempt to minimize the number of connections clients make to a cluster. By default, WebLogic uses a round-robin policy for load balancing. You can use the Administration Console to change the default load-balancing scheme between replicas of an EJB home. Alternatively, you can declare a home-load-algorithm setting in the weblogic-ejb-jar.xml descriptor file. This setting can take one of the following values: RoundRobin, WeightBased, Random, RoundRobinAffinity, WeightBasedAffinity, or RandomAffinity. You even can implement a custom CallRouter class, which allows you to override the load-balancing behavior for EJB method calls. For stateless session EJBs instead, you must declare the stateless-bean-load-algorithm element, which accepts the same values.
Detailed explanations of the load-balancing algorithms are given in Chapter 14. The chapter also provides situations in which load balancing is avoided. For example, if two EJBs are deployed on the same server, and one makes a call on the other, no load balancing will occur. Instead, WebLogic will use its collocation optimization to avoid network calls, and simply call the local instance.
Managing the Web Server
Using JNDI and RMI
Using CMP and EJB QL
Packaging and Deployment
Performance, Monitoring, and Tuning
Logging and Internationalization