Network Load Balancing, Session State and
IP Affinity

By Peter A. Bromberg, Ph.D.

Peter Bromberg  


Recently I returned from the Microsoft Testing Labs in Charlotte where our group did a week and a half of scalability testing on a web - based banking application. It's a complex application that accesses both SQL Server and an AS400 back-end with DataQueues. We found out a lot of things while we were there, things that apply not just to this particular app but across the spectrum. The Microsoft technical people demonstrated expert knowledge and a real commitment to make the lab a success. We got to use some advanced tools such as AD plus for process dumps and Mutex Black Box, a tracing / debugging tool that is absolutely amazing. And I think I gained six pounds. The cafeteria there is more like a gourmet restaurant but at poor - man's prices.

Among other things, we found out that while we were retooling this app to include our latest technology and scaling it up into a fully .NET - enabled product, we needed to scale it out in the meantime to meet the needs of existing clients until the new release is ready. Since the app was orginally written a few years ago, it uses classic ASP and make extensive use of the intrinsic ASP Session state mechanism.

Down on the Farm with Sally

So the question becomes, how do you scale out an ASP - based application that requires session state without rewriting the app? Obviously, you need to put separate copies of it on more than one webserver, and this means that you're not guaranteed that if customer A originates his form post from Server A and it ends up posting to and being returned by Server B, that your all-important ASP session data will remain intact. So now you basically have two alternatives:

1) Rewrite the application to use SQL Server or some other data store for Session State or use a third - party or custom component to do this (I have one here, called SessMgr). Depending on the application's architecture, this could prove to be a very expensive and time-consuming task.

2) Figure out a way to have the application work with more than one web server but somehow ensure "IP Affinity" - e.g., any request originating on one machine must always come back to that machine only so that ASP Session and Application variables are preserved. Your load balancing solution for your web farm may not be quite as effective, but you will still get many of the benefits of having a web farm, and you should be able to continue to use classic ASP Session state.

As it turned out, we we all ready to install Network Load Balancing and have me and another developer work feverishly for three or four days to meet a time deadline in order to add SQL Server session management to the application, when I decided to stop and read up some more on Network Load Balancing. Now mind you, we spent a bunch of time with experts at the Microsoft labs on this, and not once was the solution I'm going to share with you brought up!

Let's take a look, direct out of the NLB "whitepaper":

Managing Application State

Application state refers to data maintained by a server application on behalf of its clients. If a server application (such as a Web server) maintains state information about a client session-that is, when it maintains a client's session state-that spans multiple TCP connections, it is usually important that all TCP connections for this client be directed to the same cluster host. Shopping cart contents at an e-commerce site and Secure Sockets Layer (SSL) authentication data are examples of a client's session state. Network Load Balancing can be used to scale applications that manage session state spanning multiple connections. When its client affinity parameter setting is enabled, Network Load Balancing directs all TCP connections from one client IP address to the same cluster host. This allows session state to be maintained in host memory. However, should a server or network failure occur during a client session, a new logon may be required to re-authenticate the client and re-establish session state. Also, adding a new cluster host redirects some client traffic to the new host, which can affect sessions, although ongoing TCP connections are not disturbed. Client/server applications that manage client state so that it can be retrieved from any cluster host (for example, by embedding state within cookies or pushing it to a back-end database) do not need to use client affinity.

To further assist in managing session state, Network Load Balancing provides an optional client affinity setting that directs all client requests from a TCP/IP class C address range to a single cluster host. With this feature, clients that use multiple proxy servers can have their TCP connections directed to the same cluster host. The use of multiple proxy servers at the client's site causes requests from a single client to appear to originate from different systems. Assuming that all of the client's proxy servers are located within the same 254-host class C address range, Network Load Balancing ensures that the same host handles client sessions with minimum impact on load distribution among the cluster hosts. Some very large client sites may use multiple proxy servers that span class C address spaces.

In addition to session state, server applications often maintain persistent, server-based state information that is updated by client transactions, such as merchandise inventory at an e-commerce site. Network Load Balancing should not be used to directly scale applications, such as Microsoft SQL Server™ (other than for read-only database access), that independently update inter-client state because updates made on one cluster host will not be visible to other cluster hosts. To benefit from Network Load Balancing, applications must be designed to permit multiple instances to simultaneously access a shared database server that synchronizes updates. For example, Web servers with Active Server Pages should have their client updates pushed to a shared back-end database server.

As we have seen, NLB provides the client affinity parameter, which, when enabled, basically makes you "always come back to the server you landed on first", thereby insuring that your Session and Application variables don't get thrown away. Also, we can further control the affinity parameters, enabling us to counteract the effect that client proxy servers produce, which is basically that single - client requests coming over the proxy boundary can appear to the receiving server to have come from different clients. As long as all the client requests behind the proxy are emanating from the same Class C address range, we can still insure that the same host handles client sessions and get the benefits we need.

So the bottom line? I think I just may have saved my company around 50 to 60 hours of programmer time by practicing a little known technique in the software industry: it's called, "RTFM". Fact is, we programmers aren't just paid to write code. We're also paid to THINK!

Peter Bromberg is an independent consultant specializing in distributed .NET solutions Inc. in Orlando and a co-developer of the developer website. He can be reached at