Monday, June 21, 2010

Six Steps to Faster J2EE Apps: Performance Tuning with JSP and Servlets

Can your J2EE application sustain a large number of client requests simultaneously? Or does it become sluggish, with painfully slow response times? There are many reasons for such performance bottlenecks and many ways to prevent them. However, sometimes it's just a matter of following some simple best practices that can make all the difference. The following are six simple changes you can make, some in the design and some in the coding phases, that can help you build faster, more robust applications.



Step 1: Adopt the Correct Include Mechanism

There may be cases where you have a choice between including either a dynamic page (JSP) or a static page (HTML). Making the wrong choice can affect performance.There are two ways you can include files in a JSP page:
  1. Include directive (): This includes the contents of the file during the compilation phase—i.e., when the page is converted to a servlet.
  2. Include action (): This includes the contents of the file in the run-time—i.e., when a request is made for the page by the user.
The include directive is better and faster than the include action, because the page does not get compiled during run-time and hence does not require any server side processing—except the delivery of the page to the client. If your file does not change often, or if it is not a dynamic page, use include directive to improve performance.

Step 2: Use the Correct Scope in the useBean Action

JSP pages allow you to reuse existing code in the form of JavaBeans. You can embed that JavaBeans code in a page and access it using the  action tag.Below is the syntax:



The scope attribute is an important one. It specifies the scope of the bean which is being is used. If the scope goes unspecified, the default value for the scope attribute is page. Selecting the correct scope can fetch you better performance.For example, if the bean that you are using is required only for a particular request, butscope is set to session, that object will remain in the memory even after your request is complete. The object will exist in the memory until you explicitly remove it invalidate the session, or, in the case of time-outs, the session.



Step 3: Use the init() Method of HttpServlet for Data Caching

The init() method of a servlet is invoked by the server immediately after the instance of the servlet is created and before processing any of the client requests. It is invoked only once in the lifetime of the servlet. Performing all the expensive operations and initialization in the init()method can yield better performance.Connection pooling is one of the best examples of an activity better performed in this method. You can create the required/configured number of connections, to be re-used later, as required.
Here's some example code:

public class TaskServlet extends HttpServlet{

   private javax.sql.DataSource dataSource = null;

   public void init(ServletConfig config) throws ServletException{
      super.init(config); 
      Context context  = null;
      try
      { 
         context = new InitialContext();
         dataSource = (javax.sql.DataSource)context.lookup
   ("jdbc/dataSource");
         }
      catch(NamingException namingException)
      {
         namingException.printStackTrace();              
       }
       catch(Exception exception)
       {
          exception.printStackTrace();
       }
   }

   public java.sql.Connection getConnection(){
         //return connection from dataSource
   }

 //Other methods will go here
}

Step 4: Disable Auto-reloading of Servlets and JSPs

Auto-reloading of JSP/Servlets eliminates the hassle of restarting the server after every change in your servlet/JSP.However, when an application is deployed, auto-reloading is very expensive. Auto-reloading affects performance because it includes the additional activity of unnecessary loading, which is a burden on the Classloader. It's also risky due to the possibility of unexpected conflicts when classes, loaded by a previous Classloader, cannot cooperate with classes loaded by the current Classloader. The best option is to keep this facility OFF in a live/production environment.

Step 5: Session Management

Most applications require a session to maintain a sequence of requests from the same client. Java servlet technology has exposed this feature with an API for session management. You can use the HttpSession object for maintaining sessions, but only at the cost of yourapplication's performance.By default, all JSP pages create an instance of HttpSession. This allows you to take a call and decide if it is required. However, if you're not going to use it, you should choose not to create it. The below code segment will instruct the server not to create a session:

Another reason to avoid using HttpSession is that every time there is a request, theHttpSession object is processed. If you've got large objects stored there, this can create yet another performance bottleneck. If you must use HttpSession, at least try to avoid using it for storage of large objects. Actually, it's not advisable to maintain sessions for any extended period of time. Setting a low session time-out value not only improves application performance, it prevents also long-term degradradation of your server's performance. Always remember to close sessions when they are no longer required. You can use theinvalidate() method on HttpSession to close/release the session for memory.

Step 6: Use gzip cCompression

In general, compression is the process of compacting data into a smaller size. There are many defined compression standards defined, but gzip is the focus here.Most browsers these days support gzip. Basically, sending data in gzip-compressed format gets your data to the client faster. The following code sample shows how:

public void doGet(HttpServletRequest httpServletRequest, HttpServletResponse
httpServletResponse)
          throws IOException, ServletException{
          
   OutputStream out = null

   // Perform the check to see if the requesting client can support the format.
   // We can check the from the Accepting-Encoding header of the HTTP request.
   // If the header includes gzip, choose GZIP, else dont compress

   String encoding = httpServletRequest.getHeader("Accept-Encoding");    
      
   if (encoding != null && encoding.indexOf("gzip") != -1){
       httpServletResponse.setHeader("Content-Encoding" , "gzip");
       out = new GZIPOutputStream(httpServletResponse.getOutputStream());
   }
   else if (encoding != null && encoding.indexOf("compress") != -1){
       httpServletResponse.setHeader("Content-Encoding" , "compress");
       out = new ZIPOutputStream(httpServletResponse.getOutputStream());
   } 
   else{
       out = httpServletResponse.getOutputStream();

   }
   //Other methods will go here
}  

Spend More Time on Design

Starting with a sound application design always makes things easier down the line. Many of us don't generally spend a very little time actually designing applications—an approach that many times leads to the failure of anapplication. Failing that, if you can find a way to dedicate time to following best practices, the resulting clean code will definitely help you achieve better results.

No comments:

Post a Comment