You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Riyad Kalla <rk...@gmail.com> on 2005/04/27 00:20:19 UTC

Tomcat creating new sessions between Servlet->JSP request dispatch under load

The subject is sort of a brain dump of what is going on, let me
explain what is happening:

Setup:
ControllerServlet loads page content from DB and stores it in the
session under a well known key, then it uses a requestDispatcher to
send control to the appropriate JSP to render the content. So it looks
something like this:

ControllerServlet (Load DB content, Store in Session) -> (REQUEST
DISPATCH) -> JSP page (render results)


Server Hardware:
Quad 2.4ghz XEON
2GB Ram
Gentoo Linux (all stable), 2.6.9 Kernel
Tomcat 5.0.28/JDK 1.4.2_08
(AND also tested on)
Tomcat 5.5.9/JDK1.5.2_02


Description of Problem:
When we recieve 8 or more concurrent requests, what happens is when
the JSP page goes to display the DB content that was loaded for it by
the ControllerServlet, the content variable is actually null and the
page throws a NPE. As we up the requests (15 concurrent, 20
concurrent, all the way to 40 concurrent) the number of failed clients
hovers around 1/2, sometimes more, sometimes less. It is seemingly
random which ones fail and how many, but there are definately pages
failing.

The strangest part of all this is that I thought something might be
occuring with the Sessions, because the last lines of code in the
ControllerServlet look like this:
-------------
session.setAttribute(Constants.DTO_PAGE, pageDTO);
requestDispatcher.forward(request, response);
-------------

and the first line of the JSP page looks like this:
-----------
PageDTO pageDTO = (PageDTO)session.getAttribute(Constants.DTO_PAGE);
<NPE thrown here from pageDTO being null sometimes>
-----------

so what I did was print out the session.hashCode() value in the
ControllerServlet right before the requestDispatch call, and then I
printed it out in the JSP page on the condition that pageDTO was null,
and oddly (I think) enough, in every case where pageDTO was null, the
hashCode of the session I printed out from the JSP page, was a totally
new Session that had no matching hashCode value printed out from the
ControllerServlet.

So it *seems* that under heavy load Tomcat is creating entirely new
Sessions for the client between the ControllerServlet and then the
dispatch to the JSP page, so by the time the JSP page loads, the old
Session that had it's DB information in it, has been toasted for some
reason.

What confuses me the most, is that I'm using a requestDispatcher to do
this transfer, not a sendRedirect, so I don't understand how or why a
new Session would be created, there is no chance for the client to
turn around and re-request information as I understand the
requestDispatcher's behavior.

Any ideas or comments on how I can approach debugging this issue?
There is limited code to analyze for bugs as this seems to magically
happen between the last lines of Servlet and first lines of the JSP
page, but i might be missing some fundamental design of Web apps, I'd
appreciate any suggestions.

Best,
Riyad

---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-user-help@jakarta.apache.org


Re: Tomcat creating new sessions between Servlet->JSP request dispatch under load

Posted by Andre Van Klaveren <ny...@gmail.com>.
Riyad,

Close, but it's more like this:

1 client (user)  == 1 session.

In most cases your client (assuming it's a browser) would only send
one request, which would translate into one thread, and therefor you
wouldn't have a threading issue with your Session object.  There is no
guarantee that your users won't either open up multiple browsers and
hit your application or, more realistically, they hit the submit
button twice therefor generating multiple requests to the server.  In
this situation it is conceivable that there could be a contention
between the two threads and the Session object.

This might sound far fetched but I've experienced this problem first
hand.  In general, you should only place objects in session if you
need to access it over several requests and you can't or don't want to
retrieve it from persistent storage.  If the data is meant for a
single request, place your object in request scope and forward to your
view component.

You mentioned that your problem got worse when you increased the
number of requests to the application.  This makes sense depending on
how you are generating the requests.  If you are using a tool that is
session aware then you are creating multiple threads that are all
trying to use the same Session object.

BTW, I copied this reply to the Tomcat Users List because I think this
is an important issue that a lot of developers don't
understand/realize.  I hope that's OK with you.



On 4/26/05, Riyad Kalla <rk...@gmail.com> wrote:
> Andre,
> I appreciate the reply, something you said perked my interesting. You
> mentioned synchronizing on the session object, but as I understand it:
> 
> 1 session == 1 thread == 1 client
> 
> in Tomcat (or most typical application servers). So each client will
> have their own thread and session object, I don't need to synchronize
> on it (as I understand) because no two threads will ever be contenting
> with eachother for access to it.
> 
> These are the facts that I have learned up until now, but if they are
> wrong please let me know, this is a pretty big oversight if indeed it
> is on my part.
> 
> Best,
> Riyad
> 
> On 4/26/05, Andre Van Klaveren <ny...@gmail.com> wrote:
> > Riyad,
> >
> > You should not be using the Session object to store your DTO for
> > display.  Especially if you are forwarding the request to a JSP.  The
> > Session object should only be used to store data that is required to
> > remain in server memory between client requests.  I would place your
> > DTO in the Request object instead.  That alone will probably solve
> > your problem.
> >
> > Now, assuming you continue to use the Session object, you should
> > synchronize on the Session object before attempting to add your DTO
> > object to it.  That will prevent multiple requests from stepping on
> > each other while trying to add their DTOs to the Session.
> >
> > I haven't looked at Tomcat's code to see how they implemented the
> > hashCode method of the Session object but it's not the best way to
> > determine if two Sessions are equal in your case.  The hash code may
> > depend on the contents of the Session object.  I would print out the
> > session ID instead.  This will truely tell you if you have two
> > different sessions.  From what you describe I find it hard to beleive
> > that you there is a second session creeping into the picture within
> > the same request.
> >
> > --
> > Virtually,
> > Andre Van Klaveren
> > SCP
> >
> 


-- 
Virtually,
Andre Van Klaveren
Architect III, SCP
Enterprise Transformation Services
Unisys Corporation

---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-user-help@jakarta.apache.org


Re: Tomcat creating new sessions between Servlet->JSP request dispatch under load

Posted by Andre Van Klaveren <ny...@gmail.com>.
Riyad,

You should not be using the Session object to store your DTO for
display.  Especially if you are forwarding the request to a JSP.  The
Session object should only be used to store data that is required to
remain in server memory between client requests.  I would place your
DTO in the Request object instead.  That alone will probably solve
your problem.

Now, assuming you continue to use the Session object, you should
synchronize on the Session object before attempting to add your DTO
object to it.  That will prevent multiple requests from stepping on
each other while trying to add their DTOs to the Session.

I haven't looked at Tomcat's code to see how they implemented the
hashCode method of the Session object but it's not the best way to
determine if two Sessions are equal in your case.  The hash code may
depend on the contents of the Session object.  I would print out the
session ID instead.  This will truely tell you if you have two
different sessions.  From what you describe I find it hard to beleive
that you there is a second session creeping into the picture within
the same request.


-- 
Virtually,
Andre Van Klaveren
SCP

---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-user-help@jakarta.apache.org