Saturday, December 6, 2008

Session impl of a Web App served by multiple JVMs

Session implementation of a Web App spread on multiple JVMs/Servers

Should you need a refreshed understanding of what HTTP Sessions are and why are they actually needed, please refer to the article - Need for Session Tracking and Session Tracking Mechanism >>

All the three techniques of HTTP session maintenance namely Cookies, URL Rewriting, and Hidden Fields have quite a few limitations. Some of them are:

  • Support for small volume of data - especially in case of URL Rewriting as can be easily understood.
  • Support for simple character data only - URLs are made up of character strings.
  • Vulnerable to attacks - since all the data is visible to the clients hence attackers may get hold of the data and change them in between before the request reaches the server.
  • Developer needs to manage the session - the entire responsibility of maintaining the session (when to use the existing and when to create a new, ensuring uniqueness, consistent client-session integration, etc.) comes to the developer which obviously adds to the complexity of the overall application development.

How can we manage the session more effectively and more easily?

Using the HttpSession interface of the The Java Servlet Specification is one of the possible ways of maintaining the sessions more effectively and far more easily. All the J2EE compliant containers have the implementation of the underlying classes and the user simply need to call the APIs to use the services. For example, calling getSession() will return the session for the corresponding client if it already exists otherwise it will create a new session. Similarly, we can use the APIs putAttribute(String attrName, Object attrValue) and getAttribute(String attrName) to save the attribute values to the session OR to get them from the session, respectively. Here the important point to note is that we can save a value of type Object (i.e., effectively any Data Type supported by Java) which means we are no more limited to the character based name-value pairs. Almost all of the above mentioned limitations either get eliminated OR at least get reduced to a considerable extent by using this approach. Right?

Managing the Session Manager of your Application Server

Almost all the Application Servers come with an integrated Session Manager which facilitates an even easier way of configuring the session handling for your web application by facilitating the session configuration via simple GUI screens. You may refer to your Web/App Server manual for more details. Some common taks which we can do via App Server Session Manager are:

  • Enable Sessions - if it's not enabled then the runtime system will throw an exception if the servlet tries to create one (and of course no existing session would be returned as there wouln't be any existing...right?). Why at all do we need this configuration? Well... because not all your web applications require Session Support and for them it's wiser to disable this feature to avoid the extra overhead which the runtime system incurs for session management.
  • Enable Cookies - Ohh, back to Cookies again? Yeah... the reason why we still need cookies is because we need the client to maintain the unique Session ID of the session object created and maintained on the server. But, now we are left with storing just a single ID either in the Cookies or via URL Rewriting and not the entire session information. That definitely makes a web developer's life easier.
  • Enable URL Rewriting - Again for the same purpose of passing the unique Session ID to and from the individual clients. This of course requires a piece of code to be written as the Session ID needs to be added to the URL programmatically and hence this approach is not supported for static pages (plain HTML pages). How to overcome this limitation? Pretty simple... convert all the plain HTML pages to JSP pages as every HTML page is a valid JSP page so this should not be a problem. You would of course not like to convert your static HTML pages to Servlets :-) You of course need to encode the URL in these converted JSP pages as well. Any JSP page or Servlet which doesn't do the URL encoding will not be able to access the session if it relies on URL Rewriting approach. Beware of this!
  • Enable Persistent Sessions - sessions are maintained in the Application/Web Server memory and hence the data will be lost if the server is shut down. If you're interested in maintaining the session data then you need to store it in some database or in some other persistent medium. Almost all the Application Servers support this feature and you just need to specify the Data Source which would be used to store the session data.

What will happen if both 'Enable Cookies' and Enable URL Rewriting' are enabled?

If both these features are selected then the approach which would actually be used to maintain the session will depend upon the browser setting (to see if it accepts cookies or not) and also on the fact whether Servlet (in use) is using URL encoding or not. Below are the two possible cases where the session will be maintained if both 'Enable Cookies' and 'Enable URL Rewriting' are enabled:

  • Servlet has URL Encoding code - if this is the case then URL Rewriting approach will be used irrespective of whether Cookies are enabled or not. Even if the browser is set to accept the Cookies.
  • No URL Encoding code in Servlet and Browser accepting Cookies - cookies approach will be followed to maintain the sessions.

Implementing HTTP sessions for Web Applications spread across multiple physical servers (or JVMs)

Say your Web Application is spread across multiple physical servers (or may be on the same server, but using different JVMs which is of course a rarity) which might have been done to balance the load of your application OR may be the requirement is such that separate physical servers is a need than a luxury. Whatever be the case, in such a scenario if a user say log into one of the machines (JVMs to be specific) and then s/he is taken to some other Servlet/JSP running on some other server (JVM) to fulfill the client request. Now if that Servlet/JSP also requires authentication (which it would in most of the practical scenarios) then the user would be prompted to enter his/her credentials once again which s/he would of course not like. It's the applications responsibility to transfer the credentials from one server (JVM) to another)... right?

Using Persistent Sessions, we can easily achieve a solution to this complex problem. This approach requires the session to be saved in a data source which can easily be accessed by any of the scattered servers (JVMs) and the client gets a feeling that his application is virtually running on a single server (JVM). It's a better practice to have a completely separate data Source just for the purpose of session persistence and not to integrate session data with the application data source(s) for the obvious reason of making the overall implementation loosely coupled and hence better maintainable and more scalable.

Though the Session Manager discussed above behaves more or less the same for all the popular Application Servers like BEA WebLogic, IBM WebSphere, Oracle Application Server, etc., but the article is based on IBM WebSphere Application Server.

References: Maintaining Session Data with WebSphere, The WebSphere InfoCenter

Liked the article? You may like to Subscribe to this blog for regular updates. You may also like to follow the blog to manage the bookmark easily and to tell the world that you enjoy GeekExplains. You can find the 'Followers' widget in the rightmost sidebar.



Anonymous said...

So if the web appln is over 2 jvms there is no way to directly access the session from one jvm to other jvm.
We must use persistance ?

Geek said...

Probably YES in most of the cases. I can think of two possible ways of accessing session data among JVMs:- (i) Using Persistent Session - implemented using persistent files or databases (ii) Using multicasting - whenever some data changes, multicast it to all the JVMs.

The second option looks okay only for sharing common, insecure, and insensitive data like live cricket scores. Therefore, not used in most of practical scenarios for accessing/sharing session info amongst JVMs. Hope this helps.