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 NullSkull.com
developer website. He can be reached at info@eggheadcafe.com
|