Tuning the Middleware Services (JBoss AS 5) Part 1

Tuning the middleware services is a key step to ensure a positive experience for customers running Java EE applications. JBoss AS 5.x integrates all the Java EE 1.5 features and, while this topic is being written, release 6 of the application server has gone through the fifth milestone, including most of the new exciting features of Java EE 1.6.

This topic will cover the following topics:

• In the first part of this topic, we will cover Enterprise JavaBeans (EJB), which are a fundamental server side component of Java EE. We will discuss the performance of their main subtypes (Stateless Beans and Stateful Beans) and which factors can enhance or decrease their throughput.

• In the next part, we will learn about Java Messaging Service (JMS), which has been implemented by means of different providers in releases 5.x and 6.x of the application server. This section includes a sample tuning session of an application, which needs to improve the JMS throughput, using the new JBoss AS 6 provider (HornetQ).

The prerequisite of this topic is that the reader has already got some experience of the topics we are going to cover as we will introduce them with a very short recap.

Introduction to Enterprise Java Beans

Enterprise Java Bean technology hit the industry in 1999 and was quickly adopted by large companies. Unfortunately, problems were quick to appear and the reputation of EJBs began to suffer as a result. Some developers felt that the APIs of the EJB standard were far more complex than those developers were used to. An abundance of checked exceptions, required interfaces, and the implementation of the bean class as an abstract class were all unusual and counter-intuitive for many programmers.


This lead to a widespread perception that EJBs introduced complexity without delivering real benefits.

As a consequence, a counter-movement has grown up at grass-root level among programmers. The main products of this movement were the so-called ‘lightweight’ (that is, in comparison to EJB) technologies of Hibernate (for persistence and object-relational mapping) and Spring framework (which provided an alternate and far less verbose way to encode business logic). Despite lacking the support of big business, these technologies grew in popularity and were adopted more and more by businesses who had become disillusioned with EJBs.

The only alternative to save EJB technology was a deep change from the earlier, complex EJB specifications and a decisive step towards simpler paradigms delivered by frameworks like Spring and Hibernate.

Accordingly, the EJB 3.0 specification (JSR 220) was a radical departure from its predecessors, following this new paradigm. It shows a clear influence from Spring in its use of POJOs, and its support for dependency injection to simplify configuration and integration of heterogeneous systems. Gavin King, the creator of Hibernate, participated in the EJB 3.0 process and is an outspoken advocate of the technology. Many features, originally in Hibernate, were incorporated in the Java Persistence API such as the replacement for Entity Beans in EJB 3.0. The EJB 3.0 specification relies heavily on the use of annotations, a feature added to the Java language with its 5.0 release, to enable a much less verbose coding style.

In practical terms, EJB 3.0 is a completely new API, bearing little resemblance to the previous EJB specifications. In particular, the former distinction into three main types (Session Bean, Entity Bean, and Message Driven Bean) has been narrowed to just two main types:

• Session Beans: The basic business objects. They can be either "Stateful" or "Stateless" and can be invoked using the RMI-IIOP protocol.

• Message Driven Beans: (also known as MDBs) It supports asynchronous execution, but using a messaging paradigm.

The former Entity Bean component has been replaced by Entities, which is governed by the JPA specification.

In the next section, we will discuss Session Beans, while Message Driven Beans are covered in the last section which is about JBoss Messaging System.

Session Beans

The EJB specification defines two types of Session Beans:

Stateless Session Beans (SLSB) are business objects that do not have a state associated with them; they are typically used for on-off operations like fetching a list of elements from a legacy system.

Instances of stateless session beans are pooled. When a client accesses a SLSB, the EJB container checks if there are any available instances in the pool. If any, the instance is returned to the client and will be used exclusively from the client until its thread is completed.

If no instances are available, the container creates a new one which will be returned to the client. As for any middleware service, the number of clients that can be served is not unlimited so the EJB container can control the amount of instances to be created.

In JBoss AS 5.x and 6.x the stateless session bean pool is configured in the file, <server>/deploy/ejb3-interceptors-aop.xml. The following is the part of the configuration related to the pool:

tmp39-149_thumb

The preceding XML fragment translated in human terms, means that if you have not defined any pool annotation for your EJB (!class(@org.jboss.ejb3. annotation.Pool), then the default configuration will be used, which includes the ThreadlocalPool strategy, allowing a maximum size of 3 0 instances in the pool. If no instances are available, the EJB container will keep waiting for the timeout specified (in milliseconds) after which the request will be cancelled. We will discuss pool strategies in the next section of this topic.

Stateful Session Beans (SFSB) are business objects having a state that is, they keep track of which calling client they are dealing with throughout a session and thus access to the bean instance is strictly limited to only one client at a time.

A typical scenario for a SFSB is a web store checkout process, which might be handled by a stateful session bean that would use its state to keep track of items the customer is purchasing.

Stateful session beans remain in the EJB container until they are explicitly removed, either by the client, or by the container when they timeout. Meanwhile, the EJB container might need to passivate inactive stateful session beans to disk. This requires overhead and constitutes a performance hit to the application. If the passivated stateful bean is subsequently required by the application, the container activates it by restoring it from disk.

By explicitly removing SFSBs when finished, applications will decrease the need for passivation and minimize container overhead and improve performance. Also, by explicitly removing SFSBs, you do not need to rely on timeout values.

The configuration for stateful beans is a bit more complex as it’s split into two parts:

• Non-clustered cache configuration: used for single node applications.

• Clustered cache configuration: used for applications, deployed in a cluster of JBoss instances.

Here’s the core section of it:

tmp39-150_thumb

 

 

 

 

tmp39-151_thumb

The maxsize parameter is the maximum number of stateful beans allowed in the cache. idleTimeoutSeconds defines the maximum length of time in seconds a stateful session EJB should remain in cache. After this time has elapsed, JBoss removes the bean instance from the cache and starts to passivate it.

removalTimeoutSeconds defines how long (in seconds) the bean remains active before it is completely removed. The default 0 represents infinity, so by default SFSB are not removed from the container.

How to configure the optimal size for stateless pool?

As stated earlier, stateless bean instances are held in a pool whose configuration is contained in ejb3-interceptors-aop.xml. The optimal pool configuration is based on two factors:

1. The maximum and minimum pool size.

2. The locking strategy used by the pool to ensure thread safety of instances.

Finding out the optimal pool size, can be determined with a benchmark which simulates the production load. Once that you have completed your benchmark, you need to monitor the highest peak of request to your EJB.

The information we need is stored in the MBean dedicated to your deployment unit: as a matter of fact, every time you deploy a component like an EJB, an MBean is added in the jboss.j2ee domain. This MBean contains the required statistics for the component.

Supposing you have deployed your EJB in a jar archive named ejb3.jar, which is a part of the Application.ear archive, you will find in the jboss.j2ee domain the following MBean entry in your JMX console:

tmp39-152

By clicking on the MBean, you can access to the EJB statistics which are contained in the invokeStats attribute.

From the preceding statistics, you understand that your EJB has serviced requests with helloWorld method scoring a minimum response time of 245 ms. and a maximum response time of 459 ms. The total time spent calling this method was about 8.4 seconds for 25 total requests. (five of these are running concurrently).

The concurrentcalls attribute is a live value captured from the application server: in order to determine what was the peak of concurrentCalls that have been dispatched to your EJB, you need to poll the MBeans during the benchmark. One of the simplest ways to purse this task is by means of the twiddle command line utility located in the JBOSS_HOME/bin of your distribution.

The twiddle shell can be conveniently inserted in any batch script, which keeps polling at fixed intervals. Here’s how to access to this information from a Windows platform:

tmp39-153_thumb

What you need to adapt in your script is just the host name where JBoss AS is running (-s option) and, of course, the full MBean name.

Moving to the initial pool size, we have to report that, although the Minimumsize element appears in the conf/standardjboss.xml file, the EJB container does not honor this parameter. So at present there is no way to set up an initial pool size for stateless beans. If you really need to initialize some EJB at startup (supposing you have a costly startup for your EJB) you can opt for any startup strategy such as a Startup Servlet or an MBean service.

The other strategic element, which can be configured in your pool, is the locking strategy used. The default value uses ThreadLocal variables to avoid synchronization issues.

SLSBs can be however configured to use an alternative pooling mechanism named StrictMaxPool that will only allow a fixed number of concurrent requests to run at one time. If there are more requests running than the pool’s strict size, those requests will block until an instance becomes available.

Here’s the key configuration, which needs to be changed:

tmp39-155_thumb

You can also opt for a granular configuration by setting a different locking strategy at EJBs level. See this wiki for information: http://www.jboss.org/ejb3/docs/ reference/build/reference/en/html/session-bean-config.html.

A sample benchmark reveals that, in some circumstances, the ThreadlocalPool outperforms the strictMaxPool implementation by about 20%.

tmp39-156

The difference tends to be higher when the EJBs are carrying out heavy-duty tasks, which are locking the instance to the client. In such scenarios, the strictMaxPool policy will be particularly restrictive and should thus be avoided.

On the other hand, consider that the ThreadlocalPool implementation tends to make the pool as large as the thread pool that services the EJB. This can be counterproductive in a scenario where you have resources which are starving. For example, you might need to have an exact control of your EJBs if they are strictly dependant on an external resource like a JMS queue. That’s why the default policy for MDBs, which are in the pool, is the StrictMaxPool.

Next post:

Previous post: