Tuning JBoss AS 7 EJB connection pool

The creation and destruction of beans can be an expensive operation, especially if they acquire external resources. To reduce this cost, The EJB container creates pool of beans which, therefore, don't need to be re-initialized every time they are needed.
The Stateless EJB pool and MDB pool are used to provide stateless business services to their client, acquiring beans from the pool when they are requested and releasing the bean to the pool as soon as they are finished.
A typical EJB pool configuration looks like the following:

<pools>
  <bean-instance-pools>
   <strict-max-pool name="slsb-strict-max-pool" max-pool-size="20" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
   <strict-max-pool name="mdb-strict-max-pool" max-pool-size="20" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
  </bean-instance-pools>
</pools>

At the time of writing in AS 7, there is only support for strict-max-pool as a bean instance pool.
A strict max pool allows you to configure a maximum upper limit for the pool. At runtime, when all the bean instances from the pool are in use and a new bean invocation request comes in, the pool blocks the request till the next bean instance is available or till a timeout (set in instance-acquisition-timeout) is reached.

 Monitoring the EJB pools will be soon available through the CLI, which will have a set of minimal operations to check the pool metrics. Setting up a self-made solution to monitor the current pool size is, however, not too complicated: you can use the handy EJB3 Interceptor API to monitor the EJB which have been taken from the pool and those which have been released.

In the following Interceptor, we are simply setting a single EJB Singleton field before contacting the EJB, and after that, it has completed its job and hence returned to the pool.

package com.packtpub.chapter12;
import javax.ejb.EJB;
import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;

public class EJBInterceptor {
    @EJB
    EJBCounter singleton;

    @AroundInvoke
    public Object defaultMethod(InvocationContext context) throws
    Exception{
        // Take a bean from the pool
        singleton.getFromPool();

        // Invoke the EJB method
        Object result = context.proceed();

        // Return the bean to the pool
        singleton.returnToPool();

        // Prints out the current pool size
        singleton.dumpPoolSize();
        return result;
    }
}

The EJBCounter is a singleton EJB which merely contains the counter variable, holding the EJB max-pool-size.

package com.packtpub.chapter12;

import javax.ejb.Singleton;
@Singleton

public class EJBCounter {
    private int count=20;

    public void getFromPool() {
        count--;
    }
    public void returnToPool() {
        count++;
    }
    public void dumpPoolSize() {
        System.out.println("Current pool size is "+count);
    }
}


You can further refine this approach by adding a @PostContruct annotation which loads this variable from an external source such as the DB or a property file.
Another viable option is launching a CLI script which collects the value from the max-pool-size attribute. Here's an example:

 /subsystem=ejb3/strict-max-bean-instance-pool=slsb-strict-max-pool:read-attribute(name="max-pool-size")
{
"outcome" => "success",
"result" => 20
}

The interceptors can be then applied to the stateless EJB which are used by your application either by means of a simple annotation or by declaring them into the ejb-jar.xml configuration file. For example, here's how to intercept all EJB invocations via the @Interceptors annotation:

import javax.ejb.Stateless;
import javax.interceptor.Interceptors;

@Stateless
@Interceptors(EJBInterceptor.class)
public class EJBTest {
. . .
}

Turning off the EJB pool

Although this might sound weird to you, there can be some scenarios where you don't want your EJB resources to be managed by a pool but created on demand. For example, if your EJB does not need a costly initialization (like acquiring an external resources), it can be advantageous, in terms of performance, to avoid using the EJB 3 pool. (the JBoss 5 Performance tuning book, for example, shows a case where a so-called heavy Stateful EJB can even outperform the Stateless counterpart. This is mostly due to the fact that handling the stateless pool is not a trivial task in terms of performance).
Switching off the EJB pool just requires to comment/evict the bean-instance-pool-ref element which refers to the EJB pool:

<stateless>
 <!--
 <bean-instance-pool-ref pool-name="slsb-strict-max-pool"/>
 -->
</stateless>


Of course, it is strongly recommended to run a consistent test bed to demonstrate that your application can benefit from such a change, which will take away any check on the number of EJB instances.

0
0
0
s2smodern