Web-Tier Session Management

Regardless of which MVC framework we use, our approach to session management can have a big impact on performance and scalability. By holding server-side state on behalf of users we can simplify application code and may improve performance by caching data that may be used later in a user session. However, there is a tradeoff involved as holding server-side state can reduce scalability.

When we need to maintain session state, there are basically two options:

  • Use the standard J2EE infrastructure to have the server handle state transparently (usually the best option)

  • Try to hold state in the browser to avoid the need for server-side state

Let's consider each in turn.

Session State Managed by the J2EE Server

The Servlet API provides a simple means of holding state in a javax.servlet.http.HttpSession object. An HttpSession is essentially a map of name-value pairs, with the setAttribute() and getAttribute() methods analogous to a Map's get() and put() methods. A web container will hide the details of session object lookup, holding a unique key for a session in a cookie or special request parameter.

Clustering and Replication

In an application that runs on a single server, there is no problem in holding session state in an HttpSession object, managed transparently by the web container; the benefits in code simplification and performance come without any cost attached. As we noted in Chapter 10, this approach is usually preferable to using a stateful session EJB.

However, when we have a cluster of servers, such session state will need to be replicated by the server to ensure failover and to minimize server affinity. Replicated session state data is often stored in a database to ensure robust persistence: a major performance hit. This also means that all objects placed in an HttpSession must be serializable, to allow the server to store them in a database or file system.

Simple Optimizations

Due to the potential load of state replication, it's important to apply the following optimizations when using server-managed state:

  • Don't create session state unless necessary

  • Minimize the volume of data held in server-side session state

  • Use fine-grained, rather than large monolithic, session state objects

  • Consider optimizing the serialization of session data

None of these optimizations compromises application design. Let's consider each optimization in turn.

Don't Create Session State Unless Necessary

It's important to avoid the creation of session state (and hence the need to replicate it in a cluster) until it's necessary. For example, in the sample application, it's only during the booking process that we need to hold session state for users. The majority of user activity will involve browsing genre, performance, and show information and availability, so by creating session state only when users attempt to book we can avoid unnecessary state replication.

When we use JSP as the view technology, we must beware of a trap here. By default, every JSP creates a new HttpSession object if none exists, in case there is a JSP bean with session scope bound on the page. This is often undesirable behavior. We can override the default with the following JSP directive:

    <%@ page session= "false" %> 

I recommend the use of this directive on every JSP. Views shouldn't access or manipulate session state; a controller component should make all data available to the JSP with request scope. A controller can copy session attributes to the data model as necessary, to make them accessible to JSP pages that aren't session-aware.

Important 

Always switch off default JSP session creation with a page directive. This avoids needless creation of session state, and avoids the risk of JSP pages accessing and manipulating session state, which is inappropriate for views.

Another reason to avoid JSP pages accessing session objects is that it breaks the important rule that views should only work with data included in the model. Many views (such as XSLT views) may be unable to access session state. However, if necessary session state is included in the model, any view can access it like other model data, and view substitutability is preserved.

Minimize the Volume of Data Held in Server-side Session State

It's important to minimize the volume of data held in a user session. Holding unnecessary data will slow replication and will waste resources on the server. If too much session data is held in memory, the server will need to swap session data into a persistent store, resulting in a large performance hit when passivated sessions are reactivated.

Reference data that can be shared between users should always be held at application level. Data that is unlikely to be reused should probably just be retrieved again if it's ever needed. For example, a primary key might be held instead of a large volume of data retrieved from a database; this is a good sacrifice of performance in rare cases for a real benefit in scalability.

Use Fine-grained, Rather than Large Monolithic, Session State Objects

It's usually best to break session state into a number of smaller objects than one large, composite object. This means that only those objects that have changed will need replication in a cluster.

As there's no easy way to establish whether the state of a Java object has changed, some servers, such as WebLogic, only replicate session state in a cluster when an object is rebound in an HttpSession, although the Servlet 2.3 specification doesn't specify what behavior is expected here. (The Servlet 2.4 specification may define standard semantics for session replication.) Such selective replication can deliver a big performance gain when objects stored in a session are updated at varying rates. Thus, to ensure correct replication behavior, always rebind a session attribute when the session data is changed. This won't pose a problem in any server.

Consider Optimizing the Serialization of Session Data

Sometimes by overriding the default serialization behavior, we can greatly improve the performance and reduce the size of serialized objects. This is a specialized optimization that is rarely necessary. We'll discuss serialization optimization in Chapter 15.

Session State Held in the Browser

Some session state must always be held in the user's browser. As HTTP is a stateless protocol, a J2EE server can only retrieve a user's session object if it finds a cookie or a special request parameter containing a unique key for that user's session.

By holding session state in the browser, we lose the advantage of transparent server management of session state, but can achieve greater scalability and simplify clustering.

Session State Management with Cookies

In this approach, we use cookies to hold session state. The Servlet API makes it easy to set cookies, although we must be aware of the restrictions on the characters allowed in cookie values.

The advantage of this approach is that it allows us to make an application's web tier stateless, which has the potential to improve scalability dramatically and simplify clustering.

However, there are several disadvantages that often rule out this approach in practice:

  • Users must accept cookies. This isn't always feasible, as we don't have control over the client browser and often have little control over user behavior.

  • By rejecting server state management, we must build our own infrastructure for encoding state into cookies. Typically this involves using reflection to extract object properties, and using an ASCII-encoding algorithm to put that state into legal cookie values. (There are restrictions on the characters allowed in cookie values.) Theoretically such support could be added to a web application framework, but I've not seen this done in practice.

  • The amount of state that can be held in a cookie is limited to 2K. We could choose to use multiple cookies, but this increases the complexity of this approach.

  • All session data must be sent to and from the server with each request. However, this objection isn't so important in practice, as this approach isn't appropriate if there's a lot of state, and the page weight on typical web sites dwarves anything we might put in cookies.

Sometimes this approach can be used with good results. In one real application, I successfully used cookies in place of session state where user information consisted of three string values (none longer than 100 characters) and three Boolean values. This approach delivered business value because the application needed to run on several geographically dispersed servers, ruling out replication of server-managed session state. I used an infrastructure class to extract property values from the session object using reflection and generate an acceptable ASCII-encoded cookie value.

Session State Management with Hidden Form Fields

Another time-honored approach to session state management, which also isn't J2EE-specific, involves an application trailing hidden form fields from page to page containing session state.

I don't recommend this approach. It has several serious disadvantages:

  • It's relatively hard to implement.

  • It makes application logic vulnerable to errors in views such as JSP pages. This can make it harder to ensure a clean separation of the roles of Java developer and markup developer.

  • Like cookie state management, it requires session data to be stored purely as strings.

  • It makes it impossible to use ordinary hyperlinks for navigation within a site. Every page transaction needs to be a form submission. This usually means that we must use JavaScript links (to submit the form containing the hidden fields) instead of ordinary hyperlinks, complicating markup.

  • As with the use of cookies, bandwidth is consumed sending hidden form field values to and from the server. However, as with cookies, this objection is seldom a major problem in practice.

  • The user can easily see session state by viewing the page source.

  • Session state may be lost if the user leaves the site temporarily. This problem doesn't affect server state management or the use of cookies.

Important 

In some applications, session state can be held in cookies. However, when we need session state it's usually safer - and much simpler - to rely on the web container to manage HttpSession objects, ensuring that we do all we can to ensure efficient replication of session state in a clustered environment.



Expert One-on-One J2EE Design and Development
Microsoft Office PowerPoint 2007 On Demand
ISBN: B0085SG5O4
EAN: 2147483647
Year: 2005
Pages: 183

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net