Site hosted by Angelfire.com: Build your free website today!
 
 

12 Tips for Better EJB Performance
Good EJB design and coding practices result in thriving high-performance apps
Krishna Kothapalli and Raghava Kothapalli

Enterprise JavaBeans (EJBs), the widely adopted server-side component architecture for the Java 2 Enterprise Edition (J2EE) platform, enable rapid development of mission-critical applications that are versatile, reusable, and portable across middleware. At the same time, they protect IT investment and prevent vendor lock-in. Performance is the key aspect of any EJB application's success.

To develop high-performance enterprise applications, we should be aware of the good design and coding practices for performance improvement. The ideal scenario would be to understand "best practices" before development begins. In the post-development phase, the focus shifts to performance tuning of the entire application including Web server, application server, and database server. The strategy here is to identify and rectify the weakest link in the chain. Let's improve that scenario by discussing some general techniques that help in the design and implementation of a high-performance EJB-based enterprise application.

EJB Development
Our first eight EJB performance tips are for use during the design and development stage of your application. The objective here is to identify and fix problems before they get out of control.

1. Design coarse-grained EJB remote interfaces Because every method call to an EJB by remote and home interface is a remote call, the overhead of an intercomponent call will likely be prohibitive for most fine-grained object interactions. To avoid such overheads, an EJB should represent an independent business object that has independent identity and lifecycle. A dependent object should never be modeled as an EJB. Instead, it should be implemented as a Java class and included as part of an EJB. For example, a purchase order may be implemented as an EJB, but individual line items on a purchase order may be implemented as helper classes, not as an EJB.

2. Design coarse-grained EJB remote interface methods Each client call to an EJB is a remote call and involves checks such as access control, transaction, and activation/passivation. So each call to an EJB is many times slower than a remote call and magnitude times slower than a local method call. Reducing the number of calls improves the performance. One technique in designing coarse-grained methods is to increase the amount of data passed back and forth in a method call and combine multiple methods into fewer methods. For example, Listing 1 shows an interface that is not a remote preferred interface because the client needs to make multiple calls to fetch the Person's data. The code in Listing 2 improves performance because the number of calls is reduced by using fewer coarse-grained methods (yet these methods pass more data) in a method call.

3. Reduce the number of JNDI lookups Depending on the implementation of the naming and directory service of the application server, the JNDI lookups may take longer. Some application servers use separate processes on different machines for implementing directory information. Caching of the home handles improves the performance in such situations (see Listing 3). A facade is an object that provides a single interface to multiple objects. A server-side facade simplifies the process and makes it so that the client doesn't have to understand each of the server-side EJBs (see Figure 1). All of the client calls to the server are routed through the ServerFacade object. As you can see in Listing 3, ServerFacade is a session EJB that caches the home handles to all the needed EJBs. The client could also cache the ServerFacade home handle using a singleton object on the client side.

 
Figure 1. No Place Like Home

4. Use session bean wrapper for returning multiple data rows from an entity bean Typically each entity bean in your application represents a logical row in the database. An entity bean's home interface defines one or more finder methods—one for each way to find an entity object or collection of entity objects within the home. A client invokes a finder method on the entity bean and retrieves a collection of entity objects. The client then loops through the collection of entity objects and retrieves the data. If the client is remote, this results in a remote call per row, which is too costly. Instead of this, a session EJB object (on the server side) can be used to pack all the rows returned as a result of calling a finder method on an entity home object. Listing 4 shows a session object that returns the vector/collection of data rows to the client in a single call. This approach is useful in cases where data is static on the GUI—such as in list boxes and spreadsheets. This approach could be extended to support data modification on the client side.

5. Use session beans for database batch operations Entity beans are well suited for database operations involving one logical row at a time, but they incur a lot of performance overhead for database batch operations. For example, an entity beans finder method that returns 1,000 rows performs 1,001 select operations on the database, which reduces performance drastically. Using session beans for database batch operations (see Listing 5) improves performance because it reduces the number of calls to the database.

6. Whenever possible, use container-managed persistence (CMP) rather than bean-managed persistence (BMP) In BMP, the bean provider codes database access calls using JDBC, SQLJ, and so on in bean methods. In CMP, the container provider tools generate database access calls at the enterprise bean's deployment time. The bean provider must specify, in the deployment descriptor, the list of instance fields for which container provider tools must generate access calls. CMP has the advantage that the bean class can be independent of the data source. Another advantage is that application vendors generate optimized code for CMP to improve database access performance.

7. Use entity beans appropriately Entity beans are suitable for specific scenarios. They are appropriate to use when few rows need to be selected from the database and accessed by multiple clients simultaneously. For example, a person's record (Person) can be cached during his or her login session and accessed by multiple EJBs such as SecurityBean, BankAccountBean, and so on. Therefore, Person can be modeled as an entity bean. Entity beans are also appropriate to use when rows need to be updated frequently by multiple transactions.

Because of performance overhead, entity beans are not suitable when many rows need to be selected, inserted, or updated from the database such as in batch processing. Consider using a session bean in such scenarios. Alternatively, you may design coarse-grained database access operations in an entity bean.

8. Use the right isolation level Isolation level refers to the degree to which multiple interleaved transactions are prevented from interfering with each other. TRANSACTION_SERIALIZABLE is the highest isolation level. This makes the process very slow because all transactions (even simple reads) must wait in line to execute. Methods that use this isolation level obtain exclusive write locks on data, which prevent other transactions from reading, updating, or inserting data until the transaction is complete. In isolation level TRANSACTION_REPEATABLE_READ, transactions cannot change data that is being read by a different transaction. Write locks are used that prevent other transactions from changing the data. Methods that use isolation level TRANSACTION_READ_COMMITED cannot read uncommitted data. A write lock cannot be obtained on data that is already being changed by another transaction, so reading uncommitted data is not possible. TRANSACTION_READ_UNCOM- MITED is the lowest transaction level. Bean methods with this isolation level can read uncommitted changes, but they are not aware when new records are added.

A higher transaction level is costly in terms of performance. A lower isolation level typically allows greater concurrency at the expense of more complicated logic to handle potential data inconsistencies. A useful guideline is to use the highest isolation level provided by enterprise information systems that gives acceptable performance.

Post Design and Development
In the post-development phase of an enterprise application, we need to look at the issues related to performance tuning of the entire system. The remaining four tips refer to this phase of the project.

9. Simulate production environment to tune The strategy here is to look at the entire system, including the Web server, application server, and database server. You may want to consider performing these tasks:

  • Use entire application
  • Use vendor recommended versions and patches
  • Simulate production data set
  • Use production resources (machines, for example)
  • Simulate the user load using stress-testing tools.

10. Use tools to identify performance bottlenecks In this step, we subject the system to stress and monitor the CPU, memory, I/O, and network of all the machines. After identifying the bottleneck area, we drill down and look at the problem in detail. Table 1 lists some of the testing tools available for different aspects of your program.

11. Tune system parameters Many parameters in your application are tunable. In your operating system, for example, you can tune TCP/IP parameters, file limits, process limits, and IPC limits. In your application server, you can tune connection pool parameters, EJB pool sizes, thread count, number of JVMs, and JVM heap size. In your database server, you can tune the number of connections and processes, shared pool sizes, buffer sizes, indexes, and SQL query hints. And in your Web server, you can tune connection keep-alive parameters, thread/process count, and connection backlog.

 
Figure 2. A Cluster of Clusters

12. Use clustering to meet higher loads or consider upgrading the hardware Sometimes we reach a point where further tuning the system/code is more expensive than adding new hardware. In such cases, clustering provides an advantage. Most application servers provide the clustering feature. An EJB cluster is basically a group of EJB servers on multiple machines that work together to increase the horsepower of the system. Typically, each application server in the cluster contains the same EJBs. Servers in a cluster provide load balancing using different algorithms such as round robin, random, sticky bit, server load, and so on. Clustering can be done at multiple layers as shown in Figure 2.

These 12 tips should help you on your way to designing and implementing high-performance EJB-based enterprise applications. Use them to make your apps the best that they can be.

About the Authors
Krishna Kothapalli is an architect in the development of enterprise Java applications. He has served as a consultant for Xerox Corporation, Sun Microsystems, Proxicom, General Motors, Sapient Corporation, and MCI Systemhouse. His areas of interest include object-oriented distributed systems, Internet, and Java (especially Enterprise JavaBeans). He has more than eight years of IT experience, four of which were spent working with Java applications. He has a Masters degree in computer science from Indian Institute of Technology, Madras, India. He can be reached at krishna_sunitha@yahoo.com.

Raghava Kothapalli is a senior developer at EB2X. He has worked with PeopleSoft, Red Pepper, and Sun Microsystems. He specializes in the development of extended supply-chain enterprise applications using Java technologies. He has a PhD degree from Indian Institute of Technology, Madras, India. He can be reached at raghava@eb2x.com.

Close Window