2

I would like to have two tomcat servers behind a proxy_balancer so I can do rolling deploys.

I have this working so I can take down one tomcat and the other takes futire requests

<Proxy balancer://production>
    BalancerMember http://10.10.10.111:8080 route=s1
    BalancerMember http://10.10.10.112:8080 route=s2
    ProxySet stickysession=ROUTEID
</Proxy>
ProxyPass /services balancer://production/services
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/;" env=BALANCER_ROUTE_CHANGED

What I would now like to do is take down one server and take it off line from the pool which I can do with the balancer-manager. Then when I have upgraded and brought that server up and running - before returning to the pool I would like to be able to access it so I can sanity check it before returning to the pool. For example

ProxyPass /sanity_check http://10.10.10.111:8080/services

but that wont work becuase the server redirects itself to /services and goes through the balancer. I could do it with a separate domain but want to avoid this.

I thought of setting a cookie based on a URL param which might work but was awkward to do. Is there some feature to allow this easily. For example in HAProxy I can do this

use-server tomcat_01 if { path_end TOMCAT_01 }
use-server tomcat_02 if { path_end TOMCAT_02 }

1 Answer 1

1

This is how I did it. Set up 3 balancer pools - the main one and one for each individual server:

<Proxy balancer://tomcat1>
   BalancerMember http://10.10.10.111:8080 route=t1
   ProxySet stickysession=ROUTEID
</Proxy>
<Proxy balancer://tomcat2>
   BalancerMember http://10.10.10.112:8080 route=t2
   ProxySet stickysession=ROUTEID
</Proxy>
<Proxy balancer://production>
   BalancerMember http://10.10.10.111:8080 route=p1
   BalancerMember http://10.10.10.112:8080 route=p2
   ProxySet stickysession=ROUTEID
</Proxy>

Having a pool for the individual servers keeps things consistent.

The route=p1 is used to set a cookie so that the balancer can use stickysession session affinity - that is use the same server for a browser session. Even if sessions are shared between servers this is useful for a rolling deploy because I would not want a user to hit the old version and then get .js files etc from the new server.

I will use this cookie to decide which pool to use. E.g. if the ROUTEID cookie is .t1 (note the leading dot - this is necessary apparently) then use the tomcat1 balancer.

# Default to production pool 
SetEnvIf Request_URI "/" TARGET_POOL=production

SetEnvIf Cookie "ROUTEID=.t1" TARGET_POOL=tomcat1
SetEnvIf Cookie "ROUTEID=.t2" TARGET_POOL=tomcat2

Once the route cookie is set then the session will continue going through that backend balancer.

I can choose which balancer I want to use by appending an identifier to the end of the url to select the balancer pool I want to use for this session.

Set the environment variable TARGET_POOL to the appropriate pool

SetEnvIf Request_URI "/select_tomcat1$" TARGET_POOL=tomcat1
SetEnvIf Request_URI "/select_tomcat2$" TARGET_POOL=tomcat2
SetEnvIf Request_URI "/select_pool$" TARGET_POOL=production

Now I can use TARGET_POOL to pass the request to the selected backend balancer

ProxyPassInterpolateEnv On
ProxyPass /services balancer://${TARGET_POOL}/services interpolate
ProxyPassReverse /services balancer://${TARGET_POOL}/services interpolate

Note that for these variables to work ProxyPassInterpolateEnv On is required and each ProxyPass and ProxyPassReverse needs an interpolate

Finally I need to set the cookie that is used above for both stickysession session affinity by the balancer and by me to select the backend:

Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/;" env=BALANCER_ROUTE_CHANGED
3
  • Exactly the inspiration I was looking for!
    – ETL
    Sep 23, 2015 at 21:17
  • Getting Config variable ${TARGET_POOL} is not defined I think this solution would work well, any suggestion as to how to fix the above problem however?
    – user370988
    Aug 17, 2016 at 13:54
  • make sure you have ProxyPassInterpolateEnv On and each line ends with 'interpolate' as above
    – DavidC
    Aug 17, 2016 at 14:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .