On 23.07.2014 16:37, Christopher Schultz wrote:
On 7/18/14, 12:13 PM, Rainer Jung wrote:
On 17.06.2014 16:43, Christopher Schultz wrote:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256
All,
I've been using sticky sessions with mod_jk and I can see that
there is a bit of a problem when attempting to take a backend
Tomcat server out of load-balanced rotation: a user who never (or
rarely) restarts their web browser will keep the same JSESSIONID
cookie forever and therefore end up with the same backend server
whether it has been disabled or not.
Quick series of events:
1. User visits load-balancer and gets a randomly-assigned
backend server/route. We'll call this route "X". The JSESSIONID
cookie set by the backend server is therefore foo.X.
2. User's requests are routed by mod_jk to route X.
3. Route X is disabled using mod_jk's status worker
4. User's session on server X expires.
[Technically, 3 and 4 can happen in either order]
5. User makes a new request to the load-balancer, and mod_jk sees
the JSESSIONID cookie still set to foo.X. mod_jk sends the
request to route X which allows the user to login, etc.
Thus, it takes more time than necessary to bleed all the traffic
from route X for maintenance, etc.
Is there a way for mod_jk to ask route X if the session is
*still* valid? It seems that mod_jk will not re-route a request
that looks like it's got a valid session id to a new (active)
backend server unless the backend server X is actually down.
Any ideas?
Not exactly what you want, but you can build something around it:
1) Switch off stickyness for specific URLs
If you know that users will come via specific URLs, like a login
page, and you want that page to be handled non-sticky to optimize
load balancing even if users have an old cookie, you can do that by
setting the Apache envvar JK_STICKY_IGNORE. Look for
JK_STICKY_IGNORE on:
http://tomcat.apache.org/connectors-doc/reference/apache.html
This seems like a reasonable way to do things, except that we still
want to support requests to protected resources being saved and
redirected to the login page. If we did this (JK_STICKY_IGNORE), then
we'd end up "forgetting" the saved request (because the client would
be re-balanced to another node for the login page) and ending up with
a (useless) session on the node we are trying to take down.
We'd like to retain the request-saving capabilities of the container.
Whatever "saved" exactly means: if you can identify that situation in
terms of any part of the request (e.g. something in the referer header
etc.), you can add that as a positive or negative condition via
RewriteCond (or the 2.4 unified expression parser) and set
JK_STICKY_IGNORE in a RewriteRule that does not change the URI, only
sets the variable and also only of the RewriteConds apply. You'd have to
analyze the request-response stream e.g. with a browser plugin to look
for a useful header or similar which can be used to distinguish the
"saved" and the "normal" case.
One option we have here is to provide separate URLs for "regular"
logins versus the saved-request logins mentioned above: that would
probably solve both problems.
2) Improve handling of sessions for node with activation
"disabled"
If you switch a node to activation "disabled", mod_jk will not
send requests there, that have no session id (and of course also
not when the session route points to another node). But the old
cookie requests might still go there.
Yes, this is what we would normally do.
For that you can use the feature, that mod_jk forwards the
activation state to the Tomcat node. The node can then decide on
itself, whether it will handle a request coming in with an invalid
session id, or for example clears the session cookie and does a
self-referential redirect, which then by mod_jk is balanced on the
fully enabled nodes.
This sounds like a promising technique. I was thinking we'd just tell
the Tomcat node directly (e.g. set a context-scoped flag) that it was
"disabled", but having AJP forward that information would be even
better, so the state can be managed entirely by the status worker on
the httpd side.
This logic can be put into a servlet filter.
I'm not sure it can be in a Filter because of the interaction with the
saved-request features described above. If in a Filter, the request
would be saved before the Filter has a chance to see it, then
authentication would take place, etc.
I think this has to be in a Valve, and it has to happen before the
AuthenticatorValve sees the request. Do you see a way around using a
Valve? Assuming that such a Valve would be required, I think we should
provide one with Tomcat. I'd be happy to write such a Valve.
Can't comment because I don't know what exactly the "saved request"
feature means, resp. how it works.
Regards,
Rainer
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org