Proxy on statefull services - looking for references


#1

Gentlemen,

i have a servlet running on a tomcat, providing a html web app. What is special about the servlet is it s statefullness. After a user logs in, a Session object is created which contains some form of command container, executing the current command. That command container gets closed after a timeout or when the user logs out again.

Assuming multiple tomcats behind a reverse proxy / balancer, i recognised that one can route some clients to the same tomcat over and over again. However, in a continuos delivery / deployment scenario, i want to shut one version of the servlet down and start the new one, having both versions on the tomcat. Tricky bit: The logged in users should be routed to the old version of the servlet, all “new” users should be routed to the new version of the servlet.

Any hints to literature, documentation or products would be very helpful. Does that scenario sound familiar to someone?

Thanks in advance,
Daniel


#2

Not a Tomcat users, could you elaborate how it looks like from a HTTP perspective when you “shut one version of the servlet and start a new one, with both servlets remaing on Tomcat”?


#3

Hi Lukas,

thanks for your reply. Well from a HTTP standpoint we do have

Servlet New on: http://myhost/myapp1
Servlet Old on: http://myhost/myappold

The Balancer forwards request from h t t p://balancer/app to one of the two servlets. Typically, only one servlet is around. But when comming up with a new version of the servlet, both have to be available. I do not want to shut down the old servlet, users might be working with it.

Now again the tricky part when both servlets are available:
Users who are logged in should be allowed to finish their work on /myappold. That is, /myappold checks if a local session is available (user is logged in). If yes, let user proceed with work, if no, do not create a session but return 500 or 300 or a redirect (i can determine that behaviour to support the balancing). Finally, If no sessions are around on /myappold, then one can take down the old app. The new app /myapp1 should be available for all “new users” (no session on /myappold active) redirected from /myappold and new users straight on /myapp1.

Hope that i m not explaining thing s too confusing… the balancer should

  • forward users with a session to the /oldapp
  • route users with no session to the /newapp

Thanks,
Daniel


#4

Maybe the servlets can add some routing information in HTTP Headers?


#5

I find this kind of behavior quite strange. How is the load balancer supposed to know the servlet URL in the first place (when you spawn a new servlet)? Are you reconfiguring the load balancer each time?

Why don’t you redirect instead of rewrite, and on the backend, not the balancer, since:

  • the backend is aware of new and old servlets
  • a servlet URL can be unique, so instead of newapp and oldapp, you could have appv1, appv2, appv365, so once the customer is initially redirected you don’t have to maintain that state (or if he will connect to the main servlet, write that state in a cookie, so the customer maintains the state for you)

That’s probably not applicable to servlets, I just don’t know anything about them …


#6

Hi Lukas,

thanks again for your input. Well indeed a redirect would work! However, i would loose the central load-balancer. I thought that all traffic should be routed through the loadbalancer.

Skipping the servlet thing, i guess my situation is quite common…

(1) There is a central load balancer which provides the central application url http://myserver/myapp
(2) There are two application servers app1/myapp and app2/myapp as backend.
(3) All logged in users (identified via cookie? or http-header info? or hidden field in a html form) should be routed to app1/myapp
(4) All “new” users which are not logged in should be routed to app2/myapp

app1/myapp privides the old version, app2/myapp provides the new version for “new” users.

Without a central load balancer, i would just have a landing page on a http server. The users will get redirected to app1 or app2 and stay on that server. This would perfectly solve my issues, but then i would have to expose both app1 and app2 backend server to the users without having a single access point. I thought exposing the backend servers directly should be inhibited.

Regards,
Daniel


#7

So you want to reconfigure the load balancer every time you deploy a new app?


#8

Hi Lukas,

well if that is necessary yes. Maybe there are multiple solutions to my problem. I just want to ensure continuous service while still be able to deploy new application versions.

Is that untypical?

Regards,
Daniel


#9

Sorry Lukas, once me again,

assuming i have a reverse proxy configuration like

route half of the traffic to appserver1/myapp sticky session
rotue half of the traffic to appserver2/myapp sticky session

can i configure a reverse proxy to:

route only existing sessions to appserver1/myapp sticky session
rotue only existing sessions to appserver2/myapp sticky session
route half of the traffic to appserver1/myapp2 sticky session
rotue half of the traffic to appserver2/myapp2 sticky session

That would solve my problem perfectly.

Cheers,
Daniel


#10

I doubt this is possible with haproxy, at least I can’t think of a way.


#11

Okay,

thanks Lukas for providing some feedback!

Daniel


#12

Hi,

It’s a common sense idea to have that functionality. Please share any progress you have with such balancing.

Regards,
Ostap


#13

you might be able to solve this with an ACL to check for JSESSIONID in the incoming requests, per docs:

For example, to quickly detect the presence of cookie “JSESSIONID” in an HTTP
request, it is possible to do :

acl jsess_present cook(JSESSIONID) -m found

route to old app if jessionid found, new app if not. Note you’d need to make sure the the cookie expiry was set to the same as the session timeout (not sure if tomcat does this by default), otherwise you could have ppl with previous, expired sessions still being routed to old app.

FYI weblogic implements the type of function you are talking about, without having to change load balancers or even the application context with every version. Think they call it “versioned applications” You might get some ideas from reading about what it does - it may be more appropriate to try and solve this in the container rather than in load balancer. E.g. create a basic landing app that does nothing other than forward requests onto right version of app based on checking presence and validity of session