GETTING THE MOST FROM YOUR WEB APPLICATIONS AND SERVER

Every time you load new software on a server, you have to address the performance of other applications on the same server, as well as the problem of optimizing that application's performance. Internet Information Server (IIS) runs on a server and consumes resources as other applications do. However, IIS can attract more traffic than many other applications. High traffic can negatively affect the server's operation if you use IIS in an Internet environment. To get the most from your Web server and ensure that IIS doesn't consume every system resource, developers have to tune Web applications and you have to tune your Web server. By controlling variables and ActiveX components and taking advantage of Windows NT's and IIS 4.0's built-in performance tuning features, you can make IIS perform at its optimum efficiency.

Optimizing Your Web Applications
The performance of your Web applications plays a direct role in the performance of your IIS server. As a result, you might want your inhouse development team to improve the code you're already using for your Web applications. By rewriting an application, developers can improve performance by a factor of 10 to 1000. Let's look at how developers can control two types of variables and ActiveX components to improve performance when writing Web-based applications.

Session and application variables. IIS 3.0 and Active Server Pages (ASP) introduced two types of variables (session variables and application variables) that are extremely useful in constructing Web-based applications. The ASP stores session variables as part of a user's session object and makes these variables available at any point in the Web application, but only for the duration of the user's session. ASP stores application variables as part of the application object and makes these variables available at any point in the Web application.

In addition to being useful, session variables are easy to use. For example, you can write an application so that it obtains and stores a username for later use. You simply add a statement similar to the following to the ASP code:

<%
   Session("UserName") = "Ken"
%>

You can use application variables in the same way. For example, you can write an application so that it obtains and stores a company name. You simply add a statement similar to the following to the ASP code:

<%
   Application("CompanyName") = "32X Corporation"
%>

Session variables exist only within one user's session, so you can't access them across multiple user sessions. In contrast, application variables can exist across multiple user sessions, so you can access them at any time from any page in the application.

Both session variables and application variables can affect the performance of your Web applications, depending on the type of data you place in each type of variable. If you place a lot of data in a session variable, every user who accesses the Web application consumes memory for that data. This memory usage can quickly add up because ASP stores both session and application objects in RAM on the IIS server. So, if you store 2KB of data in a session variable and your application hosts 400 users, just that one session variable uses about 800KB of RAM!

The ASP process doesn't duplicate data stored in an application object for each user, but this data can still cause problems. For example, if you create a set of Web pages on your Web server that contain a lookup using the Visual InterDev Data Form Wizard, the generated code will include statements similar to the following:

avarTestCustomers = rsTestCustomers.GetRows()
Application.Lock
Application(strDFName & "_Lookup_TestCustomers") = avarTestCustomers
Application.Unlock

This code loads all the values in the rsTestCustomers lookup record set into an application variable. This functionality is ideal for importing data such as a list of every state in the US. But what happens if you select a lookup for a client database that contains 1 million customers? All 1 million entries go into memory in the application object­not exactly what you're looking for. Although you can use this mechanism with the session object to hold data from a database, you must be careful to avoid overloading the server's memory.

Session lifetime is related to the session object and is another area that can affect the performance of your Web application. (Session lifetime is how long a session stays active after a user stops interacting with it.) A SessionTimeout parameter in the Registry controls the session lifetime, and the default SessionTimeout value for IIS 3.0 and IIS 4.0 is 20 minutes. You can analyze your users' activity in your Web application and reduce this value as low as possible to minimize the amount of time that each session consumes resources. A developer can change the SessionTimeout value on the fly for different users to customize the users' session timeout based on their needs and reduce the potential load on IIS and the system's resources.

To change the session lifetime for IIS 3.0, you must go to HKEY_LOCALMACHINE\SYSTEM\CurrentControlSet\Services\W3SVC\Parameters\ and change the SessionTimeout value. If you're using IIS 4.0, you can use the IIS Manager to change this parameter. First, select the virtual directory that contains the Web application you want to change this setting for, and click Configuration to display the Application Configuration dialog box. Next, select the App Options tab, as you see in Screen 1. You can change the session timeout by entering a new value (in minutes) in the Session timeout box.

A final tip about using session variables in your Web applications: You can do away with the session overhead by not using session variables. If you eliminate sessions, your developers must use techniques such as passing variables with a URL as part of the QueryString, or using HTML forms to pass information between pages and code. With IIS 4.0, you can run session-less Web pages if you enter the following directive in each page:

<%@ EnableSessionState=False %>

If you place this directive in the first page of your Web application that a user connects to, the Session_OnStart procedure won't activate until the user navigates to a page without this directive. This directive delays the resource intensive session startup until a particular page needs it. You can also turn off session management for the application to further reduce the load the application places on the server. To turn off the session management, clear the Enable session state check box in the Application Configuration dialog box.

In addition to reducing the need for system resources, another advantage of not using sessions is that you can host the Web application on multiple servers and use a smart router or similar technology to shuffle users to the server with the lightest load. Session and application variables exist only on the server running the Web application, but URL variables and HTML form variables can cross servers. With the latter types of variables, IIS passes any variable data with the HTML stream, so your servers can efficiently handle user requests. You must make sure the servers sharing the Web load can access all resources (e.g., databases, Open Database Connectivity­ODBC­information, and files) the Web application requires. (For more information about maintaining application state information using ASP on one or more servers, go to http://www.15seconds.com/Issue/page.asp?Issue_Id=115.)

ActiveX components. In addition to optimizing the code of your Web applications, you can improve their performance by using ActiveX components to create server-side functionality and encapsulate code into one object. (Server-side objects typically provide one or more functions and hide the function's code from the developer and user.) However, components can have an adverse effect on your Web application if you don't understand how they work and perform. In fact, most problems associated with application development projects stem from improper design choices that lead to a poor-performing application. Let's look at a few tips for using components to enhance the performance of your Web applications.

Most developers use Visual Basic (VB) to write inhouse ActiveX components. To effectively use an ActiveX component in a Web application, you need to understand that VB uses a set of rules to determine when to shut down the component. Without these rules, a component can sit in memory and consume system resources when it doesn't need to. Table 1 describes the rules VB uses to shut down unnecessary components (for more information about these rules, consult the VB documentation).

So how much of a server's resources does an ActiveX component require? The answer to that question depends on the type and construction of the particular component. If you use an out-of-process component, it consumes a certain amount of memory every time it executes. Screen 2 shows the WinntMag.exe component from the NT Task Manager (I created this do-nothing component to use in testing concepts in this article). This component has a few properties and one method and uses 2216KB of system memory, which is a lot of RAM for not doing anything. If you add calculating logic, database logic, and error handling code, an out-of-process component starts to use more memory and can affect other resources such as the CPU.

In-process ActiveX components consume system memory within the process space of the application, which in this case is IIS, that uses the component. In-process components don't require the overhead in resources that out-of-process components require. In VB, you choose to make the component either an ActiveX .exe (out-of-process) or an ActiveX .dll (in-process).

The way you construct your components determines how many system resources they use. A Web application transfers data to an ActiveX component through a process known as marshalling. Although marshalling takes a lot of resources, you can minimize its effect. First, limit the number of calls the Web application has to make to the component. Don't call a component over and over again and pass it one piece of data at a time. Instead, create a procedure that feeds the component all the data in one pass as parameters. This simple change can make a huge difference in performance. Finally, make sure your developers understand the advantages and disadvantages of using different component models. For example, they need to be well versed in the advantages and disadvantages of using out-of-process versus in-process components and understand how marshalling affects their components. The VB documentation, Microsoft TechNet, and Microsoft Support Online have detailed information about the ramifications of constructing components.

You need to be careful when referencing a component from a session variable or application variable because the component stays loaded until the reference disappears. Depending on the lifetime of the variable, the reference can last for a long time. Use discretion: If you don't need a component, kill the references to it.

Finally, look at how Microsoft Transaction Server (MTS) works with components. MTS manages components and loads and unloads them as necessary. You can also use MTS to effectively manage transactions for your applications, removing the need for the applications to manage the transactions. (For information about MTS, see Charles Caison, "Optimizing MTS," page 153.)

Optimizing Your Web Server
Whereas the developer can optimize the variables and components associated with many inhouse Web applications, the systems administrator can use many of IIS 4.0's performance tuning features to optimize the Web server. For starters, IIS's bandwidth throttling feature lets you balance the network throughput IIS uses for the entire Web server, as well as individual Web sites, with the other loads on the server. To use this feature, display the properties for the server or site and select the Enable Bandwidth Throttling check box, as Screen 3 shows. Next, in the Maximum network use box, enter a number that is slightly higher than your expected bandwidth requires. You can determine your expected bandwidth by knowing the throughput of your system and monitoring its performance. You can also adjust the Enable Bandwidth Throttling option from the Performance tab for each Web site, as Screen 4 shows. You can use the IIS Global: Measured Async I/O Bandwidth Usage/Minute counter to determine your current bandwidth through the Performance Monitor.

Screen 4 also shows the Performance Tuning option. This option lets you tailor the amount of memory you want to assign to your site (the memory you allot coincides with the number of hits you expect your Web site will receive per day). IIS uses this memory to listen for new requests to your Web site. By setting the slider in Screen 4 to about 10,000 hits per day, you can ensure that IIS doesn't allocate unnecessary memory to listen for more requests. To achieve the optimum performance for your server, you want to set this value slightly higher than the total number of hits you expect to access the site each day.

Finally, Screen 4 shows the HTTP Keep-Alives Enabled property on the Performance tab. IIS enables this property by default to keep a connection open when a browser makes a request. This setting improves the performance of the server because IIS requires fewer new connections for each user. For example, if a user accesses a page with numerous graphics, HTTP Keep Alives let the server keep the connection open while each graphic downloads, instead of requiring a new connection for each graphic.

You can limit the number of connections users can make to your Web server at one time. Screen 5 shows the Property page for the default Web site included with IIS 4.0. To limit the number of connections, select Limited To and enter the maximum number of connections. You can also use the Connection Timeout property to set the number of seconds before the Web server disconnects an inactive user. Setting this parameter is useful because HTTP might not always disconnect an inactive user properly. However, be careful when changing the default value because a session may be inactive for a period for several valid reasons. This precaution is especially true with Internet sites where you might encounter a slow response time and other unexpected delays because of the Internet's unpredictable infrastructure.

Performance Monitor Objects for IIS
IIS 3.0 and 4.0 install Performance Monitor objects that you can use to monitor your Web servers. Table 2, page 141, lists the objects that come with IIS 4.0. These objects let you see inside IIS and your Web applications. Keep in mind that you can't look at these objects in a vacuum: You must take into account any other applications running on the server hosting IIS and the effect those applications and the operating system (OS) have on the server. Therefore, compare the IIS objects and their counters with the other applications.

If you use ActiveX components with your IIS server, you need to monitor the components' performance with the IIS Performance Monitor objects. Screen 6, page 140, shows the Add to Chart dialog box from Performance Monitor with the WinntMag.exe process selected. This object is the same one I used in Screen 2. The trick with using Performance Monitor to track processes is that the process must be running when you use the Add to Chart dialog box to place it. In this example, I forced the object to load by running a simple program that uses the object. After I add the WinntMag.exe object to my chart, I can add other counters and track the overall system's performance.

Scratching the Surface
This article only scratches the surface for tuning the performance of IIS. For more information about performance tuning, check out the Microsoft Windows NT Server 4.0 Resource Kit and go to http://www.microsoft.com/iis and http://www.15seconds.com.