The EJB 3 container is the JBoss Enterprise Application Platform's implementation of the Java EE 5 specifications for EJB 3.0. It implements all the standard bean types described by the specification e.g. stateless session beans, stateful session beans, message driven beans, and entity beans. While these all share the same names as EJB 2.x components, they are now based on a POJO development model using annotations, or optionally deployment descriptors. There are various configuration parameters that will affect the throughput of your application depending on which of these beans you use. Each bean type will be discussed in this chapter, including configuration parameters that affect overall throughput and the inter-relationships between them.
4.1. Stateless Session Bean
With stateless session beans, our implementation uses a pooling strategy to offer a “method ready” instance for use by the application. There are two types of pools that can be configured for use with stateless session beans:
The ThreadLocalPool is a pool of instances in a thread local variable and is the default pool type. It's local to each execution thread within the platform that executes methods on a stateless session bean. The ThreadLocalPool is derived from an unlimited pool implementation, so there is no limit to the number of instances that can be in the pool. The actual number of instances is dependent on other parameters. For each thread that executes methods on a stateless session bean within your application, the pool size of the ThreadlocalPool is the number of unique stateless sessions. Since there is a pool on each thread, the actual number of instances is the number of stateless sessions beans in your deployments multiplied by the number of threads that execute methods on those beans. This approach has a configuration advantage because the size of the pool is changed dynamically with changes to the application - e.g. the adding or removing of stateless session beans over time.
StrictMaxPool is the other pool implementation, a single pool used across all execution threads, that contains instances of stateless session beans. It has a maximum size so if there are no available instances in the pool for a thread to execute, the calling thread will block and wait until there is an available instance. If a StrictMaxPool is used for stateless session beans and it's not sized correctly, this creates a bottleneck. In some circumstances this might be used deliberately to limit the rate of transactions but it's not recommended.
If there are no available instances in the pool at the time a call is made, the calling thread will be blocked but only for a certain amount of time (which can vary depending on the configuration). If that time period is exceeded, the error message below will be logged, confirming that the pool is too small. This situation may not be obvious but can result in significant performance degradation. When using the StrictMaxPool, correct sizing is critical and this is covered in the next section.
javax.ejb.EJBException: Failed to acquire the pool semaphore, strictTimeout=10000
It's recommended to set the size of the pool equal to the maximum number of concurrent requests. Confirming the maximum can best be done by monitoring statistics using the JMX console. In this example the maximum size of the pool is 8,000, which is quite large based on the other data that is shown. The CreateCount metric shows that the platform created 65 beans for the pool, and that 7,959 is the current available count. This means at that moment, there are 41 instances of the bean in use.
Figure 4.1. JMX Console - JMX MBean View
The statistics presented in the JMX console must be manually refreshed and, because of its implementation, are not guaranteed to be accurate but should be used as a guide only.
There is no absolute "best" pool implementation because much depends on the application and its deployment. The recommended method of deciding between the two is to test both with your application and infrastructure. For StrictMaxPool it's critical that the pool's usage be monitored to ensure that it's large enough, otherwise performance statistics will be skewed.
Stateless session beans are configured in the file
ejb3-interceptors-aop.xml, which is located in the directory:
JBOSS_EAP_DIST/jboss-as/server/<PROFILE>/deploy. The relevant sections are titled “Stateless Bean” and “JACC Stateless Bean”. Stateless Bean is a basic, stateless bean while JACC Stateless Bean provides for permission classes to satisfy the Java EE authorization model. Note that the
minimal configuration does not include the EJB 3 container.
Since for ThreadLocalPool there is no limit to the number of instances that can be in the pool, the maxSize and timeout parameters are irrelevant.
When an application uses a remote EJB3 interface the call is serialized and deserialized by default because this is a requirement of network communication. If the EJB is running in the same JVM as the client calling it, all communications are local so there's no need for serialization or deserialization. To avoid the CPU load involved and so improve the application's responsiveness, enable the system property org.jboss.ejb3.IsLocalInterceptor.passByRef to true, for example: add
-Dorg.jboss.ejb3.remoting.IsLocalInterceptor.passByRef=true to JAVA_OPTS in the server's
run.conf configuration file.