This article covers issues concerning SCALIBILITY, WEB FARMING and OPTIMIZATION.
The IIS/ASP framework conducts a thread-pooling scheme and maintains a request queue to accommodate peak traffic times. After the default installation, IIS is configured to allocate 10 threads per processor to service incoming ASP requests. If you need to maintain state on a per-user basis across requests, you can accomplish this in an IIS application by using an ASP Session variable.
The one problem with using ASP Session variables is that you must make the assumption that you're processing each incoming HTTP request for a particular user with the same IIS computer, an assumption you can't make when running a Web farm.
Increasing Scalability through Load Balancing
A Web site is like an aspiring Hollywood actor. In the beginning of its career, before a Web site has been discovered by the masses, it lives in obscurity. Its biggest problem is the paranoia that it will live in obscurity for its entire existence. However, once a Web site becomes famous, it has a new set of challenges. The volume of incoming requests increases dramatically. Moreover, the fans of a famous Web site have lofty expectations for the site's performance, and are highly critical when these expectations are not met. Unfortunately, these new challenges are sometimes more than a Web site can handle. Some Web sites respond to fame by going up in smokeùand they never recover. Other sites are able to handle the pressures of fame more gracefully. They go on to become the places that thousands of users return to again and again.
On their path to fame, some Web sites experience a user base that grows from hundreds to thousands to hundreds of thousands. Other sites (often the children of already popular Web sites) are famous from the first day they are launched. To meet the demands and the expectations of their fans, these famous Web sites must scale accordingly.
A simple definition of scalability is the ability of a system to accommodate a growing number of users and to give each user satisfactory levels of responsiveness.
To reach this goal, a Web site must be able to supply an adequate number of processing cycles per second to handle the volume of incoming requests. As you might expect, more users require more processing cycles. So the question becomes: where do all these processing cycles come from? At first, you might be able to increase your site's scalability with a single-server solution. You can upgrade your Web server to a computer with a faster processor and/or multiple processors. The new computer will handle a larger user base than the previous one.
However, at some point a single-server solution simply doesn't cut it. You can only scale up so far. Moreover, the computers at the high end of that market are prohibitively expensive. Once you hit a certain threshold, cost-effective scalability requires the use of multiple processors spread across multiple servers. This is where load balancing comes into play. You need to distribute the workload of incoming HTTP requests across several computers. I'm going to look at several different approaches to solving this problem.
Imagine you're designing a Web-based application that makes heavy use of Microsoft Transaction Server (MTS) objects built with Visual Basic. These MTS objects contain your business logic and data access code. You're creating these objects with ASP scripts and releasing them at the end of each request. Where's the best place to balance your load with this type of design? One possible place to load balance is the point at which your ASP scripts activate COM objects.This style of activation-time load balancing is currently planned as a feature of the infrastructure of Windows« 2000 and COM+.
Web designers have devised quite a few techniques to distribute HTTP requests across a set of servers. One simple approach is to design a Web site with a dedicated routing server, as shown in
The routing server usually has a well-known Domain Name Service (DNS) name (such as MyServer.com) and a dedicated IP address. The other servers in the farm have their own dedicated IP addresses and can optionally have a DNS names as well. When a user's initial request reaches the routing server, the request is redirected to one of the other servers in the farm. You can redirect your users from the routing server using the Session_OnStart event in the global.asa file. Say you want to redirect each new user to one of three different servers in a farm:
Once a user is redirected to a particular server, a session is created and the user sends all future requests to the same server. For this reason, you can think of this as a session-based load balancing technique. Note that if you use this technique, you must make sure that a user's initial request is for a page with an .asp extension. The Session_OnStart event will not be fired when the request is for a file with an .htm or .html extension, since IIS doesn't expect them to contain ASP code.
The code shown previously uses a random algorithm for redirection, but you could design a more elaborate load balancing mechanism. For instance, each server in the farm could send performance data back to the routing server. If each server periodically transmits a count of active sessions to the router, the load balancing code could redirect each new user to the server with the fewest number of current users.
Round-robin DNS is another common session-based load balancing technique. With a round-robin DNS, each logical DNS name (such as MyServer.com) maps to several IP addresses. When a browser attempts to resolve the DNS name, the DNS server sends back one of the addresses from the list. The DNS server rotates the addresses in order to distribute a set of users across a set of servers. Once a browser resolves a DNS name into an IP address, it caches the IP address for the duration of the user's session. Round-robin DNS is slightly faster than the redirection technique shown previously, yet it produces the same results. Different users are given different IP addresses to balance the load.
If you are going to set up a Web farm with one of these session-based load balancing techniques, you should write your pages and code in terms of relative URLs. For instance, you should use URLs such as \MyOtherPage.asp instead of absolute URLs like http://myserver/MyOtherPage.asp, which contain a server's DNS name or IP address. This will ensure that each user continues to send requests to the same server once a session has been started.
While both of these forms of session-based load balancing are easy to set up, they have a few notable limitations. First, load balancing is only performed once for each client at the beginning of a session. Second, it's possible for the load balancing scheme to get a little skewed. For instance, all the users that have been sent to MyServer1 may go to lunch while all the users who have been sent to MyServer2 continue to send requests. In this case, one server could become overloaded while another server is sitting by idly. Third, A more significant problem with session-based load balancing is that it exposes the IP addresses of the servers in the farm to the client-side browser. What happens when a server crashes or is taken offline? Your balancing algorithm needs to account for this as soon as possible, but doing so can be problematic. If you're passing out bad IP addresses, your users will start to receive "server not available" errors. In a round-robin DNS system, it still can take as long as 48 hours to fix the problem once you've discovered that one of your servers has crashed. This is due to the fact that the changes to your IP address mappings need to be propagated to DNS servers throughout the Internet.
Designing a Better Web Farm
As you have seen, exposing multiple IP addresses for a single Web site can compromise both availability and load distribution. It's better to expose a single IP address that maps to several physical servers. As it turns out, this is a very difficult problem to solve because it requires low-level networking code to reroute incoming IP packets across a set of servers. Most companies decide to buy a solution rather than roll their own. Let's take a quick look at two available off-the-shelf solutions. LocalDirector is a hardware-based solution from Cisco Systems. The Windows Load Balancing Service (WLBS) is a software-based solution from Microsoft that's part of Windows NT Server 4.0 Enterprise Edition. Many other vendors offer similar products. The marketplace is quite competitive and you should do some research to determine who can offer you the best combination of price and performance. LocalDirector is a proprietary piece of hardware with an embedded operating system that can load balance incoming HTTP requests. LocalDirector listens for incoming requests on a single virtual IP address and is able to redirect them across a set of IIS servers. Each physical server in the farm has its own unique IP address. However, unlike the load balancing techniques discussed earlier, the IP addresses of the physical servers are never seen by users. Load balancing is performed every time a request comes in across the virtual IP address. This is a style known as request-based load balancing.
The WLBS provides a software-based solution for request-based load balancing. Don't confuse the WLBS with either the COM+ load balancing service or the Microsoft Cluster Server (known in its beta incarnation by its codename, Wolfpack). The WLBS is based on Convoy Cluster software purchased by Microsoft from Valence Research Inc. It can be used by many types of applications that rely on IP traffic, but in this column I'll focus on using the WLBS to create a Web farm. You can download the WLBS installation files from the Microsoft Web site (http://www.microsoft.com/ntserver/ ntserverenterprise/exec/feature/wlbs/default.asp) and install it on any computer running Windows NT Server 4.0 with an Enterprise Edition license.
How do they do it on TEK-TIPS
Well, one way you make hardware scalable is to "load balance" your site across multiple servers. You're running into serious costs at this point, because in a true load balanced environment, all of your servers must have fully licensed copies of your software installed on every single box.
In our environment, we do clustering, but it is strictly a "fail-over" type of environment. In this scenario, for instance, our fully licensed version of SQL Server 2k can go on one machine, which is our primary, and be legally installed on a second IIF that server is strictly in a fail-over role.
That is, if something goes wrong on server1, server2 picks up services while we fix server1, and then move it back. So at any one time, you only have 1 server running an instance of SQL Server.
Now, in a load balanced environment, you would have a cluster of servers that are all sitting there communicating with one another. As requests come in, decisions are made as to which server handles the request... usually the one that is least busy. In this way, the more requests that are made, the requests are spread across more and more servers, and the users never know the difference.
It can get extremely complicated, and I'm not a network admin, so I'd be unable to provide you with detailed instructions on how to set up such a system. Clustering alone was a real mind bender. We just finished setting it up, and although we love it now, we were hating getting things up and running.
Now, there's also multi-processor machines to think about in the hardware arena. Coming with .NET is true multi-threaded environments. I haven't personally worked with it yet, but MS is touting it as a new feature of .NET. In this type of environment, you write software to be able to take advantage of multi-processor environments so that when large routines are run, you dole out the workload to many "worker bees", or threads, that can run simultaneously on more than one processor. In this way, work is completed faster. However, you must have the hardware (n processor machines) in order to make it an effective approach to writing software. Otherwise, you're wasting your time.
You can also setup fibre arrays to store your data. Again, this is a clustered environment, where you have a set of "headless" servers that serve no purpose other than processing requests, and all the data is stored on shared storage (the fibre array), with fibre channel routers connecting the storage to the servers. This is not so much scalablity as it is lightning fast data access and storage, which can help support and enhance a scalable environment.
Well, that's what I can think of right now as far as scalable hardware goes. Just keep in mind, though, that all the scalable hardware in the world won't help a lick if you don't write your software in such a way to take advantage of it.
Few Words On Optimization
IIS in itself doesn't necessarily have hard and fast limitations on the number of simultaneous users. Server CPUs and RAM will be your biggest factors. Also, with that many users, site design is a huge factor. You'll want to limit the use of session variables and only keep your database connections open for a minimum amount of time. Let IIS connection pooling manage this for you (turned on by default on Win2k Server). In other words, when you close an ADO connection and destroy the connection object, IIS keeps a hold of the connection for roughly 2-3 minutes in most cases. It can then "hand off" the connection to the next request for an ADO Connection object's .open method for another site visitor/page. For this many visitors, you probably need to be looking into running a web farm (set of Win2k/IIS servers). One server in the web farm would handle incoming requests and pass them on to the server that has the least amount of activity. In this scenario, if you chose to utilize session variables, you'll need to set up "sticky sessions".