Tuesday, November 9, 2010

JEE Performance - servlet

Better Performance of J2EE web application – few more tips
Generally we are facing performance issues in web application when working with JEE based application. Client is always expecting better performance and criteria for better performance bench mark is going high and high day by day, any way there are few step may help:
Few  best practices are available here:

Let’s first discuss for Compressive investigation of servlet performance.
1.    Servlet operates inside servlet container that basically provides services like network connection, formatting response, caching request. When servlet is first referenced (either by server startup or by client call), it is loaded in memory by container by invoking its init() method. Init method can be used of caching also like constants strings, data for each requests etc.  In that case a static variable can be created in init() method and can be initialized/used in doPost/doGet methods.

2.    Session timeout: Default is 30 mins for most of server. In case we are working with lots of session data, it can be managed by session timeout configuration. You can reduce session time out as minimum as possible as per your business requirement, in case there is a need to high session time out setting (like page data input is taking 10-15 mins) you may experiment with setMaxInactiveIntervals() of HTTPSession interface.

3.    User browser and server cache: Effeciently use of ‘If-Modified-Since' and ‘Expire’ headers.  ‘If-Modified-Since' header makes call to server to check if page is modified, if not, return 302 response. However ‘Expire’ header is not making any call to server unless time mentioned in servlet is expired.

4.    Managing servlet thread pools: Most of cases we are avoiding Single thread model of servlet (unless there is a strict requirement of Synchronization). A thread is created for every request hitting to servlet. Creating and destroying thread for each request is a heavy operation, however most of containers provides thread pools at server startup and allocate them dynamically on incoming request. You can specify minimum and maximum numbers of thread on the basis of concurrent user requirement to application. All consider hardware availability for creating max number of pools (Like tomcat concurrent requests to 200 per CPU)

5.    Object serialization; In case application is using HTTPSession extensively, check serialization behavior of application. A single object serialization will serialize all objects in hierarchy. Use 'transient' for variables to avoid unnecessary serialization. In case there is requirement of clustering with fail over support, consider bulk data set in session. Check session replication mechanism, in case of ‘immediate in-memory’ replication, performance may degrade if there is too much use of session objects.

6.    Disable Auto-reloading of servlet: Generally at development time (or default) server is loading servlet for every change. To avoid unnecessary load on class loaded and to start server faster, it can be disabled.

7.    Disable logging to required level: In case there are lots of debug Logging statements in application, Time to reduce it or make debug off to reduce response time. In my experience, there can be up to 40% increment in AART (Aggregate Average response time) when we are doing log off to certain level. In case of there is  a need to maintain heavy log for debugging purpose, use rolling log behavior to avoid large size log file.

8.    User keep-alive option to maintain connection to server: HTTP 1.0 is having default behavior to close connection every time hence it should be configured with keep-alive attribute (Connection: Keep-Alive). However HTTP 1.1 requests are having Keep-Alive as default. Set contents length in response, it helps browser to buffer and flush contents in a given contents size rather than flushing contents on default content size (generally 13 KB).HttpServletResponse provides API to set header for it. - response.setContentLength(responseBytes.length);

9.    In case of large response, use GZIP response filter to gzip response contents.

ByteArrayOutputStream  output = new ByteArrayOutputStream(responseBytes.length);
GZIPOutputStream  gzipOutputStream = new GZIPOutputStream(output);

Also set header like: response.setHeader(“Content-Encoding”, “gzip”);
GZIP requires further processing for wrapping and unwrapping contents, hence is not advisable for web application having large number of user base.
Object size in session: Do not flood multiple small objects in session. It is advisable to have single Object in session and update it with single session key. Like customer object can be maintained in session with independent keys like customer name, address, phone, city etc. Performance will be better if we are updating one consolidated object in single go.
HTTP session object Vs Stateful session bean: It is common confusion in between HTTP session and stateful session bean for using to store session data. However there is no difference in size of object in server memory in both of case. Performance of Stateful session bean will be significantly higher if using for high number of users (>500) with removing bean using ejbRemove(). ejbRemove is getting called when user is disassociated with bean by removing on terminating session.
In case of not removing bean from session, cost of passivation will be much higher than using simple HTTPSession object.