Bug 38357 - mod_proxy_balancer doesn't support sticky session
Summary: mod_proxy_balancer doesn't support sticky session
Status: RESOLVED INVALID
Alias: None
Product: Apache httpd-2
Classification: Unclassified
Component: mod_proxy_balancer (show other bugs)
Version: 2.2.2
Hardware: PC Windows Server 2003
: P2 normal (vote)
Target Milestone: ---
Assignee: Apache HTTPD Bugs Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-01-23 16:44 UTC by dom
Modified: 2007-12-30 23:15 UTC (History)
1 user (show)



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description dom 2006-01-23 16:44:21 UTC
the sticky-session doesn't really work in my configuration. i guess that apache
never check for the 'route' in my environment.

-snip-
LogLevel debug
ProxyPass / balancer://prod/ stickysession=sessionkey nofailover=On
 <Proxy balancer://prod>
  BalancerMember http://192.168.1.1:8001 route=A_
  BalancerMember http://192.168.1.2:8001 route=B_
 </Proxy>
-snip-

the sessionkey-coockie is set to something like 12721798.A_

after a few clicks (depends from 2 to 15) i get connectet to the second Member,
but don't see why!

i also tried and set another cookie (name: rout, set to: "a.aplpha" and changed
the config to "route=alpha" and "route=beta" (and of course sticksession=rout)..
din't work either..

i'm pretty shure the cookie is set correctly, because i added the cookie into
the apache-log-file and it looks ok.. (LogFormat "%{rout}C .... => a.alpha)

when i see the logfile, there are following lines:

[debug] mod_proxy_balancer.c(41): proxy: BALANCER: canonicalising URL //produrl/site
[debug] mod_proxy_balancer.c(803): proxy: Entering byrequests for BALANCER
(balancer://prod)
[debug] mod_proxy_balancer.c(396): proxy: BALANCER (balancer://prod) worker
(http://192.168.1.1:8001) rewritten to http://192.168.1.1:8001/site
[debug] mod_proxy.c(736): Running scheme balancer handler (attempt 0)

i changed following line into the "proxy_balancer_pre_request"-function but i'me
not shure if this is correct (i'm not very used to C):

ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "proxy: BALANCER (%s) worker
(%s) rewritten to %s sticky %s route %s", (*balancer)->name, (*worker)->name,
*url, (*balancer)->sticky, route);

result:

[debug] mod_proxy_balancer.c(438): proxy: BALANCER (balancer://prod) worker
(http://192.168.1.1:8001) rewritten to http://192.168.1.1:8001/site!args sticky
(null) route (null)


as well, when i have a look at the balancer-manager the route of the members is
shown, but there's no entry for "StickySession".
Comment 1 Ruediger Pluem 2006-01-23 21:50:23 UTC
I currentlky cannot see any obvious confirguration flaws on your side from what
I can see in your config snippet. From the further log output and your remark
about the balancer manager I conclude that the stickysession parameter gets
somehow ignored. Tests in my environment show that it works. So please

- Attach your complete configuration
- In the mail you sent to me, you said that you applied all relevant patches.
Please provide links to all patches you applied to 2.2.0 that touch any of the
files in modules/proxy.
Comment 2 dom 2006-02-20 12:25:31 UTC
sorry, was away for a while..

i reinstalled a 'clean' version (the same version) and added the minor fixes,
and startet to test agian. i guess i found the problem in my configuration:

1. it seems that one of the changed cood made the problem even more worse!
2. the stickysession-function works until the Proxy is definied in the
VirtualHost Section. The Proxy works fine if you include the Proxy-Conf in the
'general' section, but stickysession doesn't work.. therfore you need to include
it for each virtualhost again.. [i guess you don't understand, so following
three samples..]

working:
<VirtualHost ..>
 ProxyPass / balancer://prod/ stickysession=sessionkey nofailover=On
 <Proxy balancer://prod/>
 ...
 </Proxy>
<VirtualHost ..>

it also works like that:
<VirtualHost ..>
 ProxyPass / balancer://prod/ stickysession=sessionkey nofailover=On
 Include balancemap.conf
</VirtualHost>
[and in balancemap: <Proxy balancer://prod/>...</Proxy>]

but it doesn't work like that!
Include balancemap.conf
<VirtualHost ..>
 ProxyPass / balancer://prod/ stickysession=sessionkey nofailover=On
<VirtualHost ..>
[and in balancemap: <Proxy balancer://prod/>...</Proxy>]
Comment 3 Fran 2006-04-14 10:30:17 UTC
I ran into about the same problem on my configuration. After applying the patch
http://svn.apache.org/viewcvs.cgi/httpd/httpd/trunk/modules/proxy/mod_proxy_balancer.c?rev=352010&view=diff&r1=352010&r2=352009&p1=httpd/httpd/trunk/modules/proxy/mod_proxy_balancer.c&p2=/httpd/httpd/trunk/modules/proxy/mod_proxy_balancer.c
, the balancer does not find any route so nothing is sticky.

[Fri Apr 14 11:58:17 2006] [debug] mod_proxy_balancer.c(198): proxy: BALANCER:
Found value 5C16625C0C45A7EF33487CCC19016A3
4 for stickysession jsessionid
[Fri Apr 14 11:58:17 2006] [debug] mod_proxy_balancer.c(803): proxy: Entering
byrequests for BALANCER (balancer://badmobil
e)
[Fri Apr 14 11:58:17 2006] [debug] mod_proxy_balancer.c(396): proxy: BALANCER
(balancer://badmobile) worker (ajp://10.0.15
.196:8538) rewritten to
ajp://10.0.15.196:8538/portail/thumbs;jsessionid=5C16625C0C45A7EF33487CCC19016A34?rsi=1906&code=60
294&&P=25
[Fri Apr 14 11:58:17 2006] [debug] mod_proxy_balancer.c(198): proxy: BALANCER:
Found value 5C16625C0C45A7EF33487CCC19016A3
4 for stickysession jsessionid
[Fri Apr 14 11:58:17 2006] [debug] mod_proxy_balancer.c(803): proxy: Entering
byrequests for BALANCER (balancer://badmobil
e)
[Fri Apr 14 11:58:17 2006] [debug] mod_proxy_balancer.c(396): proxy: BALANCER
(balancer://badmobile) worker (ajp://10.0.15
.197:8538) rewritten to
ajp://10.0.15.197:8538/portail/thumbs;jsessionid=5C16625C0C45A7EF33487CCC19016A34?rsi=1906&code=67
283&&P=25

As you can see, the requests are sent to 2 different real workers. There is no
route in the session. By the way, I didn't find where in the response you add
the route to the session ID. 

I would love to be able to use proxy_balancer instead of LVS, but at least
stickysession should work or an affinity mechanism should be implemented.

Opened to any extensive tests,

François.

Comment 4 Ruediger Pluem 2006-04-14 11:53:46 UTC
This cannot work as your backend server does not set a session route. The
session route must be added to the session value and has to be separated by a
'.'. So the contents of your jsessionid should be something like

5C16625C0C45A7EF33487CCC19016A34.first

for your first backend server and

5C16625C0C45A7EF33487CCC19016A34.second

for your second backend server.
If you use Tomcat you can get the session route added by setting the jvmRoute
attribute in your engine container to e.g. 'first' or 'second' (see
http://tomcat.apache.org/tomcat-5.5-doc/config/engine.html)

Comment 5 Fran 2006-04-14 14:09:39 UTC
It works for me but this information should lies somewhere in the doc, as it is
not clear currently that the route part of the id is to bet set by the
application server.

Many thanks for you help,

François.
Comment 6 Brian 2006-05-15 15:20:10 UTC
So, the backend server is responsible for adding the .route?  This needs to be
documented better.  Here is what the docs do say route is (no mention of who
sets this route or that the separator is a dot)...

"route - Route of the worker when used inside load balancer. The route is a
value appended to seesion id."

Also, I don't think that this works very well.

* Dot seems to be a bad separator
  - mod_usertrack uses dots and thus incompatible
  - Many other vendor session ids use dots
  - Need a way to change that seperator to something else?
  - Maybe option to store route in it's own var/cookie by proxy server?
  - Maybe use last dot, not first dot?  After all, you are appending to the
session id value, not prepending.

* If backend must add route, then it means that the app server (or app) must be
aware that it is being balanced.
  - I don't think that is a valid assumption
  - Some vendor app servers may not allow the addition of route
  - Changing the proxy config requires changes to the backend servers
  - Proxy server knows what route that was used and should be able to append the
value, then strip it off before proxying the request (the backend server may not
like it there).  Backend server has no way of knowing what arbitrary route you
used on the proxy side.
  - Maybe set env var to route value (and/or member value) that was used in the
proxy server so this info can be used to append the .route if the backend is not
capable of it?
Comment 7 fred 2006-06-22 09:55:13 UTC
I have the same result, when i have two or more backend servers in my 
balancer, stickysession doesn't work. Can we use "url parameter" like 
in "POUNDS" otherwise cookies. The Doc is not enough explained.
Here is my configuration :

ProxyRequests off
<VirtualHost IP1:4043>
SSLEngine ON
SSLCertificateFile conf/ssl/ca.crt
SSLCertificateKeyFile conf/ssl/ca.key
ProxyPass /balancer-manager/ ! 
ProxyPass / balancer://mycluster/ stickysession=TEST9?ID
<Proxy balancer://mycluster>
BalancerMember http://192.168.0.202
#BalancerMember http://192.168.0.43
</Proxy> 
</VirtualHost>

ID session example :
https://www.mydomain.com/testaera/TEST9?ID=eyhhf45s2sf5ERER785452

Comment 8 Josh Sled 2007-03-29 16:03:23 UTC
(In reply to comment #4)
> This cannot work as your backend server does not set a session route. The
> session route must be added to the session value and has to be separated by a
> '.'. So the contents of your jsessionid should be something like
> 
> 5C16625C0C45A7EF33487CCC19016A34.first

This is really not obvious, and not described in the doc. :/

In our (I imagine common) setup, we assume the session ID will be sufficiently
unique such that we don't need to further discriminate between specific app servers.

After thinking about it, I see the value of using '.' ... you can have
collisions in the session ids themselves, and use the post-'.' section to
strictly control stickyness of the dispatching.  But I'll echo support for the
comments about not necessarily being able to control this string in servers, let
alone principle of least surprise about the behavior without the '.'-parsing.

If the whole token was always used, both the common
random-sessionid-is-unique-enough case as well as the
qualified-by-a-particular-server-name case would both work.

(experienced here with apache-2.2.4 and resin-3.x)
Comment 9 Ruediger Pluem 2007-03-30 14:47:49 UTC
(In reply to comment #8)

> 
> This is really not obvious, and not described in the doc. :/
> 
> In our (I imagine common) setup, we assume the session ID will be sufficiently
> unique such that we don't need to further discriminate between specific app
servers.

This is not the point. If you only use the random session ID string you run into
the following problems that we avoid with our approach:

1. You need to store every session id in some sort of cache / hash and save to
which worker it belongs. So in fact you need to store this information inside
mod_proxy_balancer. Adding the name of the worker to the session id stores this
information at the client side.

2. If you have multiple webservers with a loadbalancer in front you either need
to configure stickyness on the loadbalancer or mod_proxy_balancer needs to use a
shared session cache among multiple boxes which makes this a lot more complex.

3. If you do not have the shared session cache between the webservers shuting
down one webserver will cause the stickyness lost for all the sessions that have
been handled by this webserver.

If your appserver cannot generate cookies which contain the required information
you can use mod_header in conjunction with the environment variables set by
mod_proxy_balancer
(http://httpd.apache.org/docs/2.2/en/mod/mod_proxy_balancer.html#environment) to
do this within httpd. Something like

Header add Set-Cookie "MYCOOKIE=SOMEVALUE.%{BALANCER_WORKER_ROUTE}e; path=/;"
env=BALANCER_ROUTE_CHANGED

and using MYCOOKIE as stickysession identifier.

But I agree that the documentation regarding this could be improved.
Comment 10 Josh Sled 2007-04-05 13:55:55 UTC
(In reply to comment #9)
> This is not the point. If you only use the random session ID string you run into
> the following problems that we avoid with our approach:

Good points, and thanks for explaining them.


> do this within httpd. Something like
> 
> Header add Set-Cookie "MYCOOKIE=SOMEVALUE.%{BALANCER_WORKER_ROUTE}e; path=/;"
> env=BALANCER_ROUTE_CHANGED

This is great, thanks again; one thing I note is that the route ID seems to
include the '.', so it seems better to prefix the `routeid` params in the
BalanceMember configs with '.', and leave it out of the Set-Cookie
header-manip.  As such:

  Header add Set-Cookie "app_lb=%{BALANCER_WORKER_ROUTE}e; path=/;"
env=BALANCER_ROUTE_CHANGED

  <Proxy balancer://our-app>
	BalancerMember http://host1:8080 route=.host1
	BalancerMember http://host2:8090 route=.host2
  </Proxy>
Comment 11 Ruediger Pluem 2007-04-05 14:38:46 UTC
(In reply to comment #10)

> This is great, thanks again; one thing I note is that the route ID seems to
> include the '.', so it seems better to prefix the `routeid` params in the

No, this is not the case. '.' is only the separator. It is not part of the ID.

> BalanceMember configs with '.', and leave it out of the Set-Cookie
> header-manip.  As such:
> 
>   Header add Set-Cookie "app_lb=%{BALANCER_WORKER_ROUTE}e; path=/;"
> env=BALANCER_ROUTE_CHANGED
> 
>   <Proxy balancer://our-app>
> 	BalancerMember http://host1:8080 route=.host1
> 	BalancerMember http://host2:8090 route=.host2
>   </Proxy>

Sorry, but this config does not work (I checked it). You need to have the '.' in
the Header directive, but the string before '.' can be empty. So it is ok if the
value of your cookie starts with the separator '.'.
Comment 12 Josh Sled 2007-04-05 15:12:44 UTC
(In reply to comment #11)
> (In reply to comment #10)
> 
> > This is great, thanks again; one thing I note is that the route ID seems to
> > include the '.', so it seems better to prefix the `routeid` params in the
> 
> No, this is not the case. '.' is only the separator. It is not part of the ID.

You're absolutely right; I was running with (mis-)patched sources.  Sorry for
the sloppyness and spam. :/
Comment 13 William A. Rowe Jr. 2007-12-30 23:15:29 UTC
Apparently user config; closing.