Remedies for common IIS headaches

Many administrators manage high-performance, high-traffic Web sites. HTTP 404 errors, slow response or processing times, or problems with applications, the applications server, or related servers can lead to problems in common Web applications. I've learned from experience that several of these problems have simple solutions—if you know where to find them. And you can always turn to the Microsoft Knowledge Base for IIS information, updates, and fixes.

Experience Matters
I've had to troubleshoot various IIS problems several times over the past few years. Recently, I ran across several common and interesting problems that you might run into as well.

Random load times. I worked with a client who was building a large Active Server Pages (ASP) application. The application had a rich interface and well-designed structure. The application broke out much of the standard code and placed it in various include files, then put those files in almost every page in the application. The results were a high level of code reuse and fast application development time. But the application had a performance problem: Several complex pages behaved strangely. At times, a page took only a few seconds to load; at other times, the page took up to 20 seconds to load. The load times seemed random.

When I carefully examined the application and the server configuration (I tested the application on a development server with less than 512MB of RAM), I found that the suspect page demonstrated an interesting behavior. When I stopped and restarted the Web server and browsed to the page, the page took 15 seconds or longer to load. After I'd visited the page, it loaded in just a few seconds whenever anyone visited. I looked at the page's ASP source code. With all the include files, the page appeared to have at least 4000 lines of code. I determined that the ASP page-caching method was causing the random behavior. When the first user visited the page, IIS read the page, handed it to ASP to compile, then cached and executed the page. When the next user visited, the page was already in cache, so the user experienced snappy performance.

To fix the slow load times for uncached pages, I moved several standard routines to COM objects (as I would when using Windows Distributed interNet Applications—Windows DNA—with a new Web application). I wrote the COM objects in Visual Basic (VB): I copied the VBScript code into the VB class modules. (A COM class becomes an object when you instantiate it—using CreateObject, for example.) In addition to moving the script code into the VB classes, I tweaked the code by explicitly typing all variables and by early-binding the ADO and other COM references. After I compiled the VB component, the ASP code could run methods in the executable. Moving the code from ASP to VB took several weeks. The client immediately received performance improvements as a result of several changes. First, because the script used compiled code, the ASP engine didn't need to interpret it. Second, the COM references were early bound rather than late bound. (Early-bound references let VB compile the reference into the .dll executable; late-bound references require VB or ASP to look up each reference to the COM object.) And third, I explicitly typed all variables to further make the application perform better.

Slow response times. Another client had a problem with application performance. The application ran slowly and required long response times for each page. To solve this problem, I reviewed the application's properties from Internet Service Manager (ISM) and found that the debugging switch was in the On position, which made the application run out of process (i.e., outside the IIS process namespace). Applications running out of process usually run slower than applications running in process. (For more information about running applications out of process or in process, see "Solving IIS Application Problems," January 2000.) I simply turned off the debugging switch, which made the application run in process. Because applications running in the IIS process namespace make the most use of the server's resources, the performance problems went away. (IIS 4.0 and IIS 5.0 let you run applications out of process.)

HTTP 404 error. Another common problem is the HTTP 404 error, which signifies that IIS can't find a specified link. This error usually results from renaming or moving a page or incorrectly editing a page link. With the current trend toward dynamic applications, many Web sites use ASP applications to read link information from a database and dynamically generate HTTP link code. If a user mistypes a URL in the database, HTTP 404 errors can result.

Microsoft FrontPage, IIS 5.0, IIS 4.0, Site Server 3.0, and Visual InterDev contain tools for fixing broken links. These tools are handy for static links but don't work for dynamically generated links. You must manually test those links—unless you can create an automated application to cycle through the database finding and testing links. You can use VB's Internet feature to download or access links. Also, the WebCheck utility in the Microsoft Windows Internet Information Server Resource Kit includes code to check for links. You can modify the resource kit code to browse through the database and to verify all the links in it. (For more information about WebCheck, see Windows 2000 Magazine's IIS Administrator newsletter, "Setting Up WebCheck," December 1999.)

Using the Knowledge Base
Over the years, I've found the Knowledge Base to be a rich source of information about Microsoft technologies and one of my best sources of information. Although I find many solutions through trial and error, many problem-solving expeditions start with an idea from the Knowledge Base. I've found several interesting tips for dealing with common problems.

Custom error display failure. When errors occur in an application's ASP and IIS doesn't return the custom error messages that you specified, the problem might be that the Internet Server API (ISAPI) extension doesn't have access to the error message file. (For more information about this problem, see the Microsoft article "PRB: IIS Fails to Display Custom Error Messages for .asp Files" at http://support.microsoft.com/ support/kb/articles/q176/9/19.asp.) To fix the problem, you must select the Check that file exists option for the extension that handles the error (e.g., asp.dll for ASP). After you enable this option, IIS will return the appropriate custom error message when a file is missing or an authenticated user has inappropriate permissions. You can use the following steps to change the setting:

  1. Start ISM.
  2. If you use your Web server's virtual directories, expand the folders until you see the virtual directories, then right-click the virtual directory that you want to change. Otherwise, right-click the Web server that you want to change.
  3. Select Properties.
  4. Select the Virtual Directory tab for a virtual directory or the Home Directory tab for a Web server.
  5. Click Configuration.
  6. Select the extension (e.g., .asp) that fails to return the custom error message.
  7. Click Edit. The Add/Edit Application Extension Mapping dialog box, which Screen 1 shows, will appear.
  8. Select the Check that file exists check box.
  9. Click OK.
  10. Click Apply.

Enabling debugging. Developers might run into problems when they try to use the Microsoft Visual InterDev 6.0 Script Debugger to debug an ASP or a Visual InterDev application without first enabling debugging for the application. (For more information about this problem, see the Microsoft articles "HOW TO: Configure Your Web Server for Visual InterDev 6.0 ASP Debugging" at http://support.microsoft.com/support/kb/articles/q192/0/11.asp and "HOWTO: Debugging Active Server Pages Applications Manually" at http://support.microsoft.com/support/kb/articles/q196/3/78.asp.)

You can set the debugging option in ISM or with Visual InterDev 6.0, which has a debug settings toggle switch on the project Property sheet's Launch tab. (The debugging option places extra overhead on the application, so enable it only when you need to use the debug features.) The debug setting affects all application users, and a problem can occur when a developer debugs an application on a shared server. If Visual InterDev 6.0 crashes during the debug process, the tool might not reset the IIS debug settings to Off. This failure leaves the application in a debug state. The server will run slower until you turn off debugging. You can use the following steps to enable or disable debugging from the Microsoft Management Console (MMC):

  1. Start ISM.
  2. If you use your Web server's virtual directories, expand the folders until you see the virtual directories, then right-click the virtual directory that you want to change. Otherwise, right-click the Web server that you want to change.
  3. Select Properties.
  4. Select the Virtual Directory tab for a virtual directory or the Home Directory tab for a Web server.
  5. Click Configuration.
  6. Select the App Debugging tab.
  7. In the Debugging flags section, select either the Enable ASP server-side script debugging check box or the Enable ASP client-side debugging check box.
  8. Click Apply.

To use debugging on a server running the Microsoft Windows NT 4.0 Option Pack or Visual Studio (VS) 6.0's ASP fix, you must install NT 4.0 Service Pack 4 (SP4) or later. I strongly recommend that you use debugging only on local test servers and workstations. You'll have an easier time setting up debugging, and debugging on those machines won't affect production servers.

The problem with cookies. Another set of problems arises from using cookies in a Web site or application. (For more information about this problem, see the Microsoft articles "INFO: ASP Requires Session State to Maintain Static Cookies" at http://support.microsoft.com/support/kb/articles/q184/5/74.asp and "HOWTO: Disabling Cookies Sent by Active Server Pages" at http://support.microsoft.com/support/kb/articles/q163/0/10.asp.) HTML supports client-side cookies to store information locally on a user's system. The user's system stores the cookies in RAM (during browser use) or in the file system (for persistent storage). ASP sends a sessionid cookie to a user's browser to identify the user within an application session. When the user first accesses an ASP file, IIS loads and executes global.asa and automatically creates the sessionid cookie for the user's session. IIS sends the cookie without an expiration date to the browser, and the user's system stores the cookie in the browser's RAM. Each time the user accesses another page in the application, IIS requests the sessionid cookie and checks it against the server's open sessions. If IIS finds a match, it knows the user has a current session and can interact with session variables and continue to work in the application. If the user's browser doesn't support cookies or if the user has disabled cookies, any part of the application that requires session variables won't work. To fix this problem, you can minimize the use of cookies by using techniques such as query strings to pass information within your application. (For more information about alternatives to storing session data, see SQL Server Magazine, Web Dev, "Storing Session Data in SQL Server," February 2000.)

Developers might also have problems with their applications if they don't set a cookie's expiration date. When you roll out new applications or make changes to existing applications, if the application experiences problems because cookies don't write to the client's disk, ask the developers to check their code and make sure that they've supplied expiration dates for all stored cookies.

Session and application variables. Session variables cause problems in at least two ways. First, these variables don't scale well and cause a server to dramatically slow down when site usage goes up. Second, session variables might not work when users visit a site, such as AOL, through a proxy server. From the Application Configuration dialog box, which Screen 2 shows, you can use the following steps to disable session support in IIS for any and all applications:

  1. Start ISM.
  2. If you use your Web server's virtual directories, expand the folders until you see the virtual directories, then right-click the virtual directory that you want to change. Otherwise, right-click the Web server that you want to change.
  3. Select Properties.
  4. Select the Virtual Directory tab for a virtual directory or the Home Directory tab for a Web server.
  5. Click Configuration.
  6. Select the App Options tab, which Screen 2 shows.
  7. Clear the Enable session state check box to turn off session support (you can alternatively select the check box to turn on session support). After you disable this option, the Session_onstart and Session_onend events in global.asa won't execute.
  8. Click Apply.

Disabling session state support disables session variables in the entire application. Disabling session state support can improve performance, but you need to wait until your developers have eliminated the use of session variables in the affected application. With session variables disabled, you can still track users' data through a site by storing user data in a variety of places, such as the file system or a database.

Besides disabling session state support, several other factors (e.g., changes in Visual InterDev 6.0, changes to programming settings) can cause application and session variables to be unavailable in an application. For example, .htm pages might not be mapped to asp.dll. The IIS default application mappings will execute the asp.dll for ASP only. If a user first enters a site through an .htm page, asp.dll won't execute, global.asa won't execute, and ASP functionality won't be available. You can use these steps to map .htm pages to asp.dll:

  1. Start ISM.
  2. If you use your Web server's virtual directories, expand the folders until you see the virtual directories, then right-click the virtual directory that you want to change. Otherwise, right-click the Web server that you want to change.
  3. Select Properties.
  4. Select the Virtual Directory tab for a virtual directory or the Home Directory tab for a Web server.
  5. Select the App Mappings tab.
  6. Enter a new entry for .htm files. The new entry needs to match the ASP entry. (You can edit the ASP entry, then copy it for the .htm page.)
  7. Click OK.

Developers can also use a server-side script directive to disable session variables. To change the ASP and disable sessions, insert the following code in the directive line at the start of the page:

Enablesessionstate=False

NT SP6a to the rescue. Finally, NT 4.0 SP6a fixes several problems that are central to IIS 4.0 or Microsoft Transaction Server (MTS—IIS won't run without MTS, so MTS fixes might fix IIS problems) and can affect the server's performance or stability. See the sidebar "NT Server 4.0 Service Pack 6a's IIS and MTS Debugging Resources" for a list of Microsoft articles that address IIS and MTS problems.

Keep the Faith
With a little research and a little determination, you can usually work around IIS application problems. Microsoft does a good job documenting known problems and bugs and offering a variety of solutions. And don't forget that NT SP6a might offer quick fixes to otherwise time-consuming troubles. (I like how Microsoft rolls out information about problems and solves them in NT service packs.) All these problem-solving resources are good medicine for your IIS ills.