17.5 HttpSession

The HttpSession object associates particular clients with a session. Under the covers, this association is typically done by using a cookie. HttpSession lets you maintain state associated with the session. If you don't need to maintain session state, there is no need to use HttpSession. You can eliminate the creation of session objects with the JSP directive <%@ page session="false"%>. If you are maintaining session state, HttpSession seems to provide adequate performance as long as you are aware of the points covered in the following sections.

17.5.1 Timing Out Sessions

Among the HttpSession methods is setMaxinactiveInterval(int interval), which allows you to specify how many seconds the session can be inactive before it is terminated. Try to set this value as low as possible. However, do bear in mind that too low a setting will really annoy your users if it means that they have to reestablish the session state. On the other hand, leaving session objects around too long can be a heavy drain, especially if each session uses anything significant in the way of server resources. Therefore, this method is a classic performance-tuning parameter, requiring optimization on the basis of testing the application to see what value is best.

You can also have pages automatically refresh themselves with embedded page commands, and these pages can keep a session alive indefinitely, even when the page is no longer in use. Each time the page reloads, the session timeout counter is reset. You can explicitly terminate a session yourself at any time by using the HttpSession.invalidate( ) method.

17.5.2 HttpSession Versus Stateful Session Beans

A number of sources recommend that you use HttpSession objects to manage session state rather than using stateful beans. However, in their book J2EE Performance Testing with BEA WebLogic Server (Expert Press), Peter Zadrozny, Philip Aston, and Ted Osborne state that there is no real difference in performance between these two options, as long as the beans are explicitly removed from the container when the session expires.[2] The beans are removed automatically by binding the session to a session listener that calls ejbRemove( ) when the session terminates. Removing the beans is critical to achieving comparable performance. Beans not removed are passivated, which imposes a large overhead on the system and causes enormous performance degradation.

[2] An excerpt is available at http://www.sys-con.com/weblogic/article.cfm?id=101.

The cited test situation was idealized; the sessions were always removed before the test terminated, and the beans were removed when the session terminated. In a production system, lingering sessions can be a problem. Consequently, for optimal performance across the board, use HttpSession rather than stateful session beans to maintain state. If you prefer stateful session beans for design reasons, ensure timely session termination and bean removal.

17.5.3 HttpSession Serialization

HttpSession objects can be serialized by the servlet engine under certain situations: different conditions in different servlet engines cause this to happen. Serialization has costly overheads (see Chapter 8), and you can minimize the chances of and cost associated with serialization. Memory conditions and session longevity are the two primary reasons for serialization of HttpSession objects. Longevity can be minimized by timing out sessions; memory usage is best minimized by reducing the number and size of objects stored in the HttpSession.

If your HttpSession is serialized, the smaller the graph of objects reachable from the HttpSession, the faster the serialization will be. Try to avoid storing large object graphs in the HttpSession, use transient variables wherever possible to avoid serializing objects unnecessarily, and bear in mind the costs of serialization when considering what is stored in the HttpSession.

17.5.4 Distributing Sessions for Higher Scalability

Spreading your requests across multiple application servers helps make the application more scalable. If you are maintaining state, you may need to replicate your sessions across the application servers to handle requests that may be distributed across the servers. However, session replication is expensive. If you use a frontend load balancer for your application distribution, then you should ensure that the load balancer can support "sticky" sessionsi.e., that it automatically routes any particular session to the application server handling that session. DNS and hardware load balancers both support this (DNS by virtue of the cached DNS lookup value). A software load balancer may need to be programmed to handle sticky sessions.

If replication of sessions is a definite requirement, then building your own session mechanism is probably better than using HttpSessions. HttpSession identifiers are not unique or consistent across multiple servers. You can build your own session mechanism without too much difficulty to replicate the HttpSession functionality while ensuring that the session mechanism is optimized for distribution. A file-based distributed session mechanism, implemented by altering URLs to encode the session identifier, is described in Budi Kurniawan's article "Pseudo Sessions for JSP, Servlets and HTTP."[3] Many web sites use this method of session management.

[3] Budi Kurniawan, "Pseudo Sessions for JSP, Servlets and HTTP," ONJava.com, 3/01/2001, http://www.onjava.com/pub/a/onjava/2001/03/01/pseudo_sessions.html.

17.5.5 Efficient Resource Management

Optimize your use of HttpSession objects by following these guidelines, some of which summarize earlier tips:

  • Remove HttpSession objects explicitly with HttpSession.invalidate( ) when the session is finished, such as when the user logs out.

  • Remove HttpSession objects implicitly by timing out the session with HttpSession.setMaxInactiveInterval( ). Set the timeout as low as is reasonable.

  • Implement the HttpSessionBindingListener for resources that need to be cleaned up when sessions terminate, and explicitly release resources in the valueUnbound( ) method.

  • Remove stateful session beans as soon as the session terminates; use the HttpSessionBindingListener as described in the last point.

  • The servlet init( ) and destroy( ) methods are ideal for creating and destroying limited and expensive resources, such as cached objects and database connections.

  • The servlet init( ) method is a good place to perform once-only operations.

  • You can use the jspInit( ) and jspDestroy( ) methods in the same way as init( )and destroy( ).