views:

128

answers:

4

Can I have multiple web servers hooked up to a SQL Server cluster and still maintain a user's session?

I've thought of various approaches. The one suggested by the Microsoft site is to use response.redirect to the "correct" server. While I can understand the reasoning for this, it seems kind of short sighted.

If the load balancer is sending you to the server currently under the least strain, surely as a developer you should honor that?

Are there any best practices to follow in this instance? If so, I would appreciate knowing what they are and any insights into the pros/cons of using them.

A: 

While you could use "sticky" sessions in your load balancer, a more optimal path is to have your Session use a State Server instead of InProc. At that point, all of your webservers can point to the same state server and share session.

http://msdn.microsoft.com/en-us/library/ms972429.aspx MSDN has plenty to say on the subject :D

UPDATE:

The State Server is a service on your windows server boxes, but yeah it produces a single point of failure.

Additionally, you could specify serialization of the session to a SQL Server, which wouldn't be a single point of failure if you had it farmed.

I'm not sure of how "heavy" the workload is for a state server, does anyone else have any metrics?

JustLoren
Would having a single "state" server not introduce not only a single point of failure, but also mean that it is also working for every page request across all of your servers? How do you get around that issue?
BobTheBuilder
+2  A: 

Some options:

The load balancer can be configured to have sticky sessions. Make sure your app session timeout is less than the load balancers or you'll get bounced around with unpredictable results.

You can use a designated state server to handle session. Then it won't matter where they get bounced by the LB.

You can use SQL server to manage session.

Check this on serverfault. http://serverfault.com/questions/19717/load-balanced-iis-servers-with-asp-net-inproc-session

Chuck
*the* load balancer? How do you get away from this single point of failure? If the load balancer dies, then what? *Is* there a realistic way to avoid that or no?
BobTheBuilder
As for using SQL server to manage the session, wouldn't this bring its own scalability issues? i.e. having to grab the user data from the database on every page refresh?
BobTheBuilder
I actually haven't used SQL server to manage so I can't speak to scalability. I wouldn't have just one LB - I'd have a min of 2 and possibly as many as 5 (2x prod, 2x test, 1x dev)
Chuck
@bobthebuilder-If you did go with SQLServer, this would be an excellent division for splitting onto a second db server. Where core data would be on one db server, and state management on another.
John MacIntyre
A: 

This isn't probably the answer you're looking for, but can you eliminate the NEED for session state? We've gone to great lengths to encode whatever we might need between requests in the page itself. That way I have no concern for state across a farm or scalability issues with having to hang onto something owned by someone who might never come back.

n8wrl
We thought about this too, and may actually go down that road, so it's not that I *don't* want to hear this. It's just that I'm not ready to make that decision yet. I wanted all options on the table so I could make an informed decision. I thought it would also be useful for other developers.
BobTheBuilder
+2  A: 

I'm taking here from my experience of Java App Servers, some with very sophisticated balancing algorithms.

A reasonable general assumption is that "Session Affinity" is preferable to balancing every request. If we allocate the initial request for each user with some level of work-load knowledge (or even on a random basis) and the population comes and goes them we do end up with a reasonable behaviours. Remember that the objective is to give each user a good experience not to end up with evenly used servers!

In the event of a server failing we can then see our requests move eleswhere and we expect to see our session transfered. Lots of way to achieve that (session in DB, session state propogated via high speed messaging ...).

djna
Okay, so this leads to questions about propogating the session state if the original server were to fail or be taken out of service. Are there any best practices for achieving this?
BobTheBuilder
+1, Excellent (IMO) answer, had pretty much the same substance myself.
AnthonyWJones
@BobTheBuilder: One option is don't, take it on the chin and move on. Seriously if its critical that the user must not loose what we would otherwise consider to be volitile if the server crashes then the Session object is not the right place for that data.
AnthonyWJones