tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From André Warnier>
Subject Re: Sticky Session Not Working With Apache 2.0.54 and Tomcat 7.0.8
Date Tue, 09 Aug 2011 21:04:15 GMT
Be reassured : your questions are not stupid.
It is just that your situation is a bit unusual, so it takes us time to figure out 
precisely what you want to achieve, and to try to fit this (if it has to be fitted) to how

Tomcat handles sessions and session-id's.
But maybe this is just a misconception on our part, and some parts of your explanations 
are still not very clear.  So let's try to summarise.

a) the "clients" in this case are not browsers, but proprietary equipment which runs some

software (also under your direct/indirect control) which is capable of receiving/sending 
messages with a webserver (in this case Tomcat, fronted by Apache httpd), using the HTTP 
protocol. But they cannot handle HTTP cookies, and they cannot handle URL-rewriting.

b) on this Tomcat webserver, runs an application (composed of one or more servlets), and 
this is what the appliances in question communicate with.  The Tomcat webserver is fronted

by an Apache httpd server which acts as a load-balancer and/or router to the back-end 

c) you have a need to handle some form of "session" between a given client and the 
webserver.  This means that the individual requests/responses between an appliance and the

webserver are not independent of one another (which is normally the case with the standard

HTTP protocol), but your client and your webserver application need to maintain a form of

"state" between them.

d) what is not so clear, is if your notion of "session" matches Tomcat's notion of 
"session".  On the one hand, you seem to say that your application maintains this session

internally, in other words that Tomcat basically knows nothing about these sessions.
But you also seem to say that Tomcat should be aware of these "internal sessions", for 
some reason which I do not remember. (Is it because you want Apache httpd to act as a load

balancer, and keep sending the requests of one appliance to the same Tomcat as the one 
with which this appliance started the session ?).

e) to handle "Tomcat-type sessions", Tomcat's standard built-in mechanisms (and also the 
mod_jk connector's built-in mechanisms) require this session-id to be exchanged either via

cookies, or via a modification of the request URLs.
Both of which apparently your appliances are unable to handle.

So there are apparently two kinds of solutions :
a) to modify the internal mechanisms of Tomcat and mod_jk to handle the exchange of 
session-id differently (in a way which your appliances can handle)
b) to create some kind of "adaptor" which would take a session-id as generated by the 
standard Tomcat mechanisms and translate it to a form which your appliances understand; 
and vice-versa, to take the session-id as your appliances can send it, and transform it 
on-the-fly to a form which mod_jk and Tomcat can understand and handle (cookie or URL 

(a) is possible, since after all both are open-source.  But it is also likely to be hard 
to do, because the code which handles this is probably not trivial, and there are probably

umpteen possibilities to do this wrong.
(And you could hire a mod_jk specialist to do this for you; there are several on this list

probably willing to take on a job like that)

(b) seems (to me) an easier path, but there are some limitations.
First, for some intermediate piece of software to go and get this session-id out of a POST

body sent by the client, is complicated (need to parse the body) and inefficient (need to

parse each body of each request). It may also a problem for the Tomcat application side, 
because when something at the Tomcat level reads the request body, that body is read, and

it is no longer available for the application to read (at least not via the standard 
request API).

So it would be better indeed if the session-id sent by the client was sent in a HTTP 
header.  That is easier to parse, more efficient and does not interfere with the 
subsequent application's parsing of the request body.

What this intermediate piece of software would need to do, is to parse the HTTP headers 
coming from the client, find this session-id header, and modify the request URL to add the

session-id to it.  Or, replace this HTTP header by another header (or add another one) (a

JSESSIONID Cookie header), which mod_jk and Tomcat can understand.  This would need to be

done early, when the request first reaches Apache httpd, and before mod_jk uses this 
information to "balance" this request to one Tomcat or the other.
(All of which make me think now however, that if you can modify the client code to add 
such a special header, then why can that header not be a "Cookie" header which the 
standard mod_jk/Tomcat could handle ? creating a Cookie header is not that hard.)

In the other direction, Tomcat sends a "Set-Cookie" header (named JSESSION-ID) with every

response, and this cookie contains the Tomcat session-id.  So the intermediate piece of 
software would need to read that response Set-Cookie header, and transform it into some 
form that your client appliance can understand.
(But them again comes the same question : if the client code can be modified to recognise

a custom HTTP header with the session-id, then why can it not be modified to decode a 
standard Set-Cookie header ?)

So maybe finally, the solution to your problem could consist in implementing some level of

Cookie support in your appliances.  Cookies are just quite simple HTTP headers, with a 
string value easy to encode/decode.  You do not necessarily have to implement the full 
arcana of the Cookie specifications for your purposes, just what is strictly necessary for

mod_jk and Tomcat to handle sessions and load-balancing with it.

The result of such a modification of the appliances, would be to make them more similar to

browsers in terms of handling cookies.  This in turn would help at the server side, in 
handling their requests in a more HTTP-compliant way, which would probably bring 
advantages in the long term in terms of application development.

And if for some reason you cannot do that, then there are standard mechanisms in Apache 
httpd which can do things like this (like mod_headers and mod_rewrite).  But their fields

of action also tend to be on HTTP headers and cookies, rather than request/response 
bodies.  And the moment in the request/response cycle where they can intervene, may not 
necessarily fit very well with the needs of mod_jk for load-balancing or sticky sessions.

There are also non-standard mechanisms which can achieve what you want, for example using

mod_perl on the front-end Apache.  But there we are entering the realm of bespoke programming.

Hope this helps.

Lataxes, Karl wrote:
> Our clients cannot send or process JSESSIONIDs as they are not web browsers, but proprietary
equipment running embedded software that sends HTTP POST messages to a servlet on our internal
network.  The servlet keeps track of sessions internally by assigning a session id which is
contained within the HTTP request body.
> I believe my best solution would be to send an additional header containing the session
id with the servlet response and using that for sticky sessions.  I am working with our embedded
software developers on sending this header back to the servlet during subsequent client requests
to facilitate sticky sessions.  I know I will probably have to go to Apache 2.2 to accommodate
this, but that was something I expected.
> I am somewhat unfamiliar with these aspects of Tomcat/Apache and I'm learning a lot of
this stuff on the fly, so please forgive the stupid questions. 
> -----Original Message-----
> From: Christopher Schultz [] 
> Sent: Monday, August 08, 2011 12:14 PM
> To: Tomcat Users List
> Subject: Re: Sticky Session Not Working With Apache 2.0.54 and Tomcat 7.0.8
> Hash: SHA1
> Karl,
> On 8/5/2011 7:49 AM, Lataxes, Karl wrote:
>> After some testing, I determined that appending the session ID to the 
>> URL will not work.
> Why not?
>> I can, however, add the session ID as a new HTTP header, but I have to 
>> determine which modules to use (mod_headers, mod_proxy, 
>> mod_proxy_http, mod_proxy_balancer?)
> How about just having the client send JSESSIONID in the way that Tomcat expects it?
>> and how to configure sticky sessions using the new HTTP header.  I am 
>> somewhat unfamiliar with this aspect of Apache, so is anyone able to 
>> point me in the right direction?
> You said that your client was sending this information:
> "session-id= <unique_client_identifier>-<current_time_in_milliseconds>"
> but you never said where that information was. If it's in the query-string of the URL,
then it should be easy to fetch and set into a request header.
> To fetch the session id, you can do something like this:
> SetEnvIf "Request_URI" "/session-id=([A-Za-z0-1.]+)-/" SESSION_ID=$1
> That will set an environment variable SESSION_ID to an id passed-in via the query string
(unless you have the misfortune of having "session-id=[A-Za-z0-1.]+" somewhere else in your
URL, too). You might have to tweak the regular expression if it won't match your "unique_client_identifier"
which I'm assuming is the Tomcat session id.
> If you can use mod_headers /before/ mod_jk gets it's hands on things, you ought to be
able to do something like this:
> RequestHeader append "Cookie" "JSESSIONID=%{SESSION_ID}e"
> That will set the "JSESSIONID" cookie header to the value of the session id retrieved
from the query string above.
> I hope that gets you on the right track.
> - -chris
> Version: GnuPG v1.4.10 (MingW32)
> Comment: Using GnuPG with Mozilla -
> iEYEARECAAYFAk5ACzMACgkQ9CaO5/Lv0PBQDgCeKtjV7nqZ/HoE/i3Wz2oLtwqy
> HqcAn0rIRIvf5FZwVl1L1npDqKy/iL26
> =5Fxb
> ---------------------------------------------------------------------
> To unsubscribe, e-mail:
> For additional commands, e-mail:

To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message