Whether you are using the Internet Information Server for Internet or intranet publishing, the goal is to obtain the maximum performance from it. The starting point is to tune the base platform (Windows NT Server). Depending on your IIS implementation, however, you may need to tune other components as well. If you are using SQL Server to store your IIS logs or to use as dynamic WWW pages, you will need to tune SQL Server, for example. In this chapter, you will learn how to tune Windows NT Server first, and then the Internet Information Server, using some Performance Monitor examples. Along the way, you will see a few programs I wrote to illustrate the type of bottlenecks you might encounter.
Keep in mind while reading this chapter that the IIS basically provides the same services as a file server. It consumes processor cycles as an application server, and it provides shared resources (files, WWW pages, and so on) to network clients. You can think of the Internet as a large WAN connected to your internal network. The methodologies you use to tune for optimum IIS performance are the same as you would apply to any application or file server.
Performance tuning is based on finding your bottleneck (the item causing a performance limitation) and then doing something to correct the situation. The primary goal with performance tuning is to provide adequate system performance. And this basically falls into four categories: the processor, memory, disk subsystem, and network. If these components are performing well, your users generally will not complain to you about system performance. This section explores each of these areas and provides sample Performance Monitor workspaces to illustrate the process of finding bottlenecks in these areas.
One thing to consider about performance bottlenecks is that when you find and solve one bottleneck, it always exposes another bottleneck. Now look at an example that illustrates this point.
Suppose that you have a server with a 100 MHz Pentium processor, 32 MB of main memory, a really fast pair of EIDE disk drives, an EIDE disk controller, and a 16-bit network adapter. Your primary concern is providing a fast user response time for shared files and SQL Server access. Where do you think the performance bottleneck would be? The processor? Memory? The disk subsystem? The network adapter? Based on my experience, it would turn out to be the disk subsystem. This would be caused by the EIDE controller. This controller would use the standard ATDISK driver provided with Windows NT Server. And this driver can support only one pending I/O request at a time. It's not really the fault of the driver, though. Instead, it is the hardware it supports. Almost all IDE (and EIDE) disk controllers use programmed I/O (or PIO). A PIO controller uses the processor to move data from the disk, through the disk controller, and then to system memory. This requires a high percentage of processor time and limits the device to one I/O request at a time.
The solution here is to replace the EIDE disks and controller with SCSI disk drives and a SCSI controller that supports direct memory access (DMA). A controller that supports DMA moves data from the disk to system memory without processor intervention. Although even here, you need to exercise good judgment. Don't choose an 8-bit or 16-bit SCSI controller if you have a 32-bit expansion bus. Both these require copying data from the disk drive to memory below 1 MB for an 8-bit controller, and below 16 MB for a 16-bit controller. This data then must be copied to the application or system buffer above 16 MB if you have more than 16 MB installed in your system. This coping of data is referred to as double buffering, and it can severely hamper system performance.
Instead, choose a 32-bit SCSI controller. The basic idea is to choose a disk controller with the largest I/O bus that your expansion bus supports for the fastest data-transfer rate. Now that you have increased the performance of your I/O subsystem, however, and performance does increase compared to the base system, another performance bottleneck may be exposed. This most likely will be the processor. SQL Server can be very processor intensive. Adding an additional Pentium processor and dedicating this processor to SQL Server will increase SQL Server performance. After this occurs, you'll probably find that replacing your network adapter with a 32-bit network adapter and adding additional memory can increase performance even more. And this can go on and onliterally, forever. Eventually, you have to draw the line based on your budget and acceptable performance requirements.
Finding processor bottlenecks on your server is not an easy task, but it is possible. The starting point is to use the performance counters included in Processor.PMW, which can be found on my web site http://www.nt-guru.com/windows nt/performance or in my other books, Microsoft BackOffice Administrator's Survival Guide and Internet Information Server for Windows NT Unleashed. This workspace file includes processor chart, alert, and report view settings. Table 7.1 lists these object counters.
Table 7.1. Processor performance object counters.
Object
Counter
Instance
Parent
Description
System
% Total Processor Time
N/A
N/A
Percentage of processor time currently in use on your system. The basic formula for calculation is ((% CPU in Use on CPU 0) + (% CPU in Use on CPU 1) ... + (% CPU in Use on CPU x)) / Total number of CPUs.
System
System Calls/sec
N/A
N/A
Number of system service calls executed per second. If this value is lower than the number of interrupts/sec, this indicates that a hardware adapter is generating excessive interrupts.
System
Context Switches/sec
N/A
N/A
Frequency of switches between executing threads. A high value indicates that a program's use of critical sections or semaphores should have a higher priority to achieve a higher throughput and less task switching.
System
Processor Queue Length
N/A
N/A
Number of threads waiting in the processor queue for processor cycles. A consistent value of 2 or higher indicates a processor bottleneck. This value always is 0 unless at least one thread is being monitored.
System
Interrupts/sec
Per Processor
N/A
Number of interrupts the system is servicing.
Thread
% Processor Time
Per Processor
Idle
Percentage of processor time the thread is using.
The first step in finding a processor bottleneck is to obtain a baseline chart to familiarize yourself with your system in an idle state (see Figure 7.1). Then you should use the same counters to obtain a baseline in a normal working state.
The next step is to use these counters on an active system. Examine the % Total Processor Time counter. If this value is consistently more than 90 percent, you have a processor bottleneck. You then must examine each process in the system to see which one is using more of the processor than it should. If you have too many processes to view in a chart, you can use the report view. To select these processes, choose Edit|Add to Chart and select Process as the object type. Then select % Processor Time for the counter. Next, select each application listed in the Instance field. The process that has the highest peak generally is your performance bottleneck. Now take a look at this process in a little more detail by looking at a sample performance hog.
In a multithreaded environment, such as Windows NT Server, a processor shares CPU cycles among multiple threads. Each of these threads can be running or waiting for execution. If you have an application that is waiting for user input or for a disk I/O request, for example, while it is waiting, it is not scheduled for execution. So other threads that can perform work execute instead. This is based on the application design, however, and in this regard, not all applications are created equal. Many applications have been ported from a different application environment, and might not make efficient use of the Win32 APIs. If you ported an MS-DOS application to a Win32 console application, for example, you might have left programming constructs that constantly polls for user input, increments a counter in a loop, or performs a similar function. Listing 7.1 provides an example of this process.
Listing 7.1. A processor intensive application.
#include <stdio.h>
#include <stdlib.h>
int main (void)
{
unsigned long uMaxNumber,x;
char chUserInput;
for(x=0;x=4294967295;x++)
{
uMaxNumber=x;
}
printf("Counter = %d", uMaxNumber);
chUserInput=getchar();
return (0);
}
When this application executes, it uses between 80 and 98 percent of the processor, as shown in Figure 7.2. This is the definition of a processor-intensive application. Notice that I have the Process object selected for the BadExample application (or instance). This is the same object counter you will use (but, of course, you will use different process instances) to determine what percentage of the processor your applications are using and which process is the bottleneck.
The executable for this application is available at my web site at http://www.nt-guru.com/windows nt/performance (or in Microsoft BackOffice Administrator's Survival Guide and Internet Information Server for Windows NT Unleashed). You might want to try out this application on your system. On a uniprocessor system, this little code snippet uses most of your available processor cycles, but on a multiprocessor system, the other processors remain available to process other application requests. If you have a multiprocessor system, try this application and add the Processor %Total Processor Time counter for each processor to your chart. One of these processors shows 80 to 98 percent use, whereas the other processors continue to function normally.
To see how a multithreaded, processor-intensive application affects performance on a multiprocessor system, take a look at a multithreaded version of the application. It spawns three threads and equally distributes the load among them, as Figure 7.3 shows. Of course, my system is only a uniprocessor machine, so the load per thread is between 30 and 33 percent. If you have three or more processors, however, three of these processors should show 80 to 90 percent processor use. Notice in this example that the Thread object has been chosen (one for each thread of execution) as the item to display. This is the object counter you use to determine which thread of a process is using more of your processor than you want and is the bottleneck.
So after you isolate a performance-intensive application, what can you do about it? You can do several things, depending on your resources and the application. This breaks down into two categories.
If you have access to the source code, you can do the following:
Use a profiler to modify the application to be less processor intensive. This can include making more efficient use of critical sections or semaphores. If your application spawns multiple threads, for example, you should set the thread priorities to make more efficient use of these control mechanisms so that the threads are not being switched constantly in and out of the processor queue and performing less work than the overhead involved in switching them in and out of the processor queue.
You can rewrite the application to spread the load by distributing it among several computers.
You can rewrite the application to use thread affinities so that the application uses a specific processor (or processors) in a multiprocessor system. This method can achieve higher system performance because the threads are not switched constantly to different processors. As a thread is switched, it often requires that the processor cache be flushed to maintain data coherency. And that slows down the overall system performance.
If you do not have access to the source code, you can try the following:
Inform the manufacturer of the problem and try to get them to fix it by using the earlier suggestions.
Run the application at off-peak times by using the Scheduler service.
Start the application from the command line with the start command at a lower priority. You can use
start AppName /low
for example, where AppName is the name of the application to execute.
Add additional processors. This only provides additional benefits if you have multiple threads or processes to execute. For the Microsoft BackOffice products, this can provide significant benefits because these applications are designed with multithreading and multiprocessing concepts.
Upgrade the processor. Change from an 80486 to a Pentium. Or, change from an Intel processor to a RISC processor.
Upgrade the processor to a processor with a larger internal cache. The 486/DX4 (75 MHz and 100 MHz) models, for example, include a 16 KB cache rather than the default 8 KB cache of the other 486 models.
Upgrade the secondary system cache. This item is quite important when adding additional memory to the system. As you increase system memory, the cache must map a larger address space into the same size cache. This can increase the cache/miss ratio and degrade performance.
If you do nothing else to your system, adding additional memory almost always increases system performance. This is because Windows NT Server uses this memory instead of virtual memory and decreases paging. Memory also needs to be used by the Cache Manager to cache all data accesses. This includes remote (network) or local resource access. The other Microsoft BackOffice components also can benefit from this increased memory. SQL Server, for example, can use some of this memory for its data cache, its procedure cache, and the temporary database.
Just like finding processor bottlenecks, you have to start with the big picture and then narrow down the search to a specific application to find the memory resource hog. A good starting point is to use the performance counters listed in Table 7.2 to see whether you have a problem. If you find a problem, you can use the Process memory-related counters to see which application is the resource hog. This section provides an example so that you can see how this operation works.
Table 7.2. Memory Performance Object counters.
Object
Counter
Instance
Description
Memory
Pages/sec
N/A
Number of pages read from or written to disk to resolve memory references to pages that were not in physical memory at the time.
Memory
Available Bytes
N/A
Amount of free virtual memory.
Memory
Committed Bytes
N/A
Amount of memory that has been committed to use by the operating system, as opposed to memory that has been merely reserved for use by the operating system.
Memory
Page Faults/sec
N/A
Number of virtual memory page faults that occurred on the system because the physical page was not in the process's working set or main memory. A page might not need to be read from disk if the page is available on the standby list or is in use by another process that shares the page and has it in its working set.
Memory
Cache Faults/sec
N/A
Number of page faults that occur in the Cache Manager in reference to a memory page that is not in the cache.
Paging File
% Usage
Per Page File
Amount of use of a specific page file.
Paging File
% Usage Peak
Per Page File
Maximum use of a specific page file.
Tip: You can use the Windows NT Diagnostics applet (WINMSD.EXE) located in your Administrative Tools group to get a quick indication of your memory usage. Just click the Memory button to display the Memory dialog box. Check the value in the Available Physical Memory field to see whether it is higher than 1 MB for a Windows NT Server computer or higher than 4 MB for a Windows NT Workstation. If this value is less, you have a performance degradation due to excessive paging. The Memory Load Index indicates this in a color bar chart: green for good, yellow for warning, and red for a system in trouble.
The first step in isolating the memory bottleneck is to load the Memory.PMW workspace file into the Performance Monitor. This workspace includes basic counters for the chart, alert, and report views. Once more, you want to obtain a baseline for an inactive system, and then one for your normally active system. If you have a memory-intensive process, your chart will look similar to that shown in Figure 7.4. This particular chart is based on a log file (Memory.LOG) that I captured while running the MemHog.EXE program. The same basic object counter activity is displayed in real time for a memory-intensive application as well, however.
Note the behavior of these counters as items to watch. The behavior displayed in the chart in Figure 7.4 is an indication of memory-related problems. Specifically, you should note the following behavior:
Pages/sec: Notice the high peaks for this counter. This indicates a great deal of paging activitygenerally, because your system does not contain enough physical memory to handle the demands placed on it by the application. If you see such activity on your system, you should look closer to see which application is placing such a load on the system. It might be normal behavior for the application, in which case you should add more physical memory to increase system performance.
Page Faults/sec: Notice here that the peaks follow the peaks for the Pages/sec counter. It also is an indication that your system is paging heavily. A consistent value of more than 5 indicates that your system is paging more than it should. A consistent value of 10 or higher is a desperate cry for help. Adding additional physical memory is the only cure. Note in Figure 7.4 that these counters only peak to a high value and then drop back to a normal level. On an active file or application server, however, the activity should be more linear.
Available Bytes: This counter indicates the amount of virtual address space available to your system. As applications use memory and page to disk, this value decreases. When it drops below 10 MB, you most likely will see a message warning you that virtual memory is running low and that you should close some applications or increase your virtual memory settings. If this counter is consistently low after running an application, this generally indicates a system memory leak.
Committed Bytes: As the Available Bytes counter decreases, the Committed Bytes counter increases. This demonstrates that the process is allocating memory from the virtual address space but is not necessarily using it. Still, your virtual address space is a limited resource, and you should watch this counter to check for applications that allocate memory but do not use it. You should note this behavior and discuss this problem with the manufacturer to fix it. Notice in Figure 7.4 that this counter steps up as the paging file activity steps up. This is an indication that the application is using the memory it is allocating. High consistent values are an indication that adding additional physical memory will increase system performance. You also should note the counter value when an application ends; if this counter does not return to the original value, the application has a memory leak or a hidden process that is not terminating properly.
Cache Faults/sec: You should compare this counter with the Page Faults/sec counter to determine whether you really are paging too much in a normal system. If this counter is less than the Page Faults/sec counter, you definitely are paging too much and you should add additional physical memory.
% Usage: This counter indicates your current paging file activity. If this value is consistently larger than your minimum paging file size, you should increase your minimum paging file size. A significant amount of system overhead is involved in growing the page file, and any page file growth is not contiguous. This means that more overhead is involved in accessing pages stored in this section of the page file. Notice here that the paging file use is incremental in steps of 10 MB, and when the application terminates, the usage counter drops back to the original (or a little less) value. If your usage counter does not return to the original value after running an application, it has a memory leak or a hidden process that is not terminating.
% Usage Peak: This counter indicates the maximum usage of your page file. If this value consistently reaches 90 percent, your virtual address space is too small and you should increase the size of your paging file. When it reaches more than 75 percent, you generally will notice a significant system performance degradation.
Note: You can find the MemHog.EXE program and performance monitor workspace at http://www.nt-guru.com/windows nt/performance. This program allocates up to 100 MB of memory in 1 MB allocations. For every 10 MB of memory allocated, the program sleeps for 30 seconds. I have the program suspend execution for 30 seconds for every 10 MB allocated because, when making heavy use of the paging file, the system uses quite a bit of the processor to grow the pagefile and allocate the memory. This heavy processor use masks the memory use curve of the application. The purpose of this program is to simulate an application that is making heavy use of your system memory. You will not find many commercial programs that allocate 100 MB in less than 10 seconds. Also, the program uses the memset command to populate each 1 MB memory block with a series asterisk so that the memory actually is accessed. If you do not perform this step, the memory is merely allocated, but not used. The Committed Bytes object counter then maxes out momentarily as the virtual memory address space is increased, but no paging activity takes place because no memory was physically used.
The example shown in Figure 7.4 illustrates a general system-wide, memory-related problem. But in the real world, you need to find the specific cause of the problem. You can do this by using the Performance Monitor. Instead of looking at system-wide object counters, you want to narrow the search to the Process object counters to find the process that is using your system memory (see Figure 7.5).
Doesn't this look quite similar to the display shown in Figure 7.4? Notice the same basic peaks for Memory Page Faults/sec as for ProcessPage Faults/sec. If you directly overlay the Memory Page Faults/sec counter with the Process Page Faults/sec counter, however, you will notice that the Memory counter is a bit higher than the Process counter. This is because the Memory counter is a system-wide counter and includes other paging activity from other processes. Table 7.3 lists the corresponding system-to-process counters to help you in your analysis.
Of course, I knew which process was the problem, so my chart only includes the MemHog application. In order to find a real-world application problem, you should select all the Process instances except for the system processes, unless you are looking for a system process memory leak. A couple of other Process object counters you may find useful in your diagnosis of a memory-intensive application follow:
Pool Nonpaged Bytes: The nonpaged pool is a system-resource area devoted to system components. Allocations from this area cannot be paged out to disk. This is a finite resource, and if you run out of nonpaged pool bytes, some system services may fail.
Pool Paged Bytes: The paged pool is also a system-resource area devoted to system components. Allocations from this area may be paged to disk, however. It is also a finite resource, and if you run out of paged pool bytes, a system service may fail.
Note: Both of these counters is very useful in tracking down a process that is incorrectly making system calls and using all the available pool bytes.
Virtual Bytes Peak: This indicates the maximum size of the virtual memory address space used by the process.
Working Set: This counter indicates the size of the application's working set in bytes. The working set includes pages that have been used by the process's threads. When memory is low, pages are trimmed from the working set to provide additional memory for other processes. As the pages are needed, they are pulled from main memory if the page has not been removed, or they are read from the paging file.
Working Set Peak: This counter indicates the maximum working set size in bytes.
Tip: By monitoring the working set for a particular process and comparing that to the working set peak, you can determine whether adding additional memory will increase the performance of the process. The idea here is to add memory until the working set and working set peak values are equal; this provides the maximum benefit to the process. You should consider that this might be an unrealistic goal if your budget is limited.
Finding disk bottlenecks is easier than finding processor or memory bottlenecks because these performance degradations are readily apparent. There are really only four performance counters to monitor for bottlenecks:
% Disk Time: This counter is the percentage of elapsed time that the disk is servicing read or write requests. It also includes the time the disk driver is waiting in the disk queue.
Disk Queue Length: This counter indicates how many pending I/O requests are waiting to be serviced. If this value is greater than 2, it indicates a disk bottleneck. On a multidisk subsystem, such as a stripe set or stripe set with parity, a little calculating is in order to determine whether a disk bottleneck is occurring. The basic formula is
Disk Queue Length - Number of Physical Disk Drives in the MultiDisk Configuration
If this value is greater than 2, a disk bottleneck is indicated. If you have a stripe set with three disk drives and a queue length of 5, for example, then 5 - 3 = 2. And 2 is an acceptable value.
Avg. Disk Transfer/sec: This counter is the time in seconds of the average disk transfer. It is not used just for this information, however. You use this counter with the Memory Pages/sec counter.
Memory Pages/sec: Use this counter and the Avg. Disk Transfer/sec counter in the following formula to tell you how much of your disk bandwidth is used for paging:
Percent Disk Time Used for Paging = (Memory Pages/sec * Avg. Disk Transfer/sec) * 100
When I perform disk diagnostics, I break my Performance Monitor charts into two different settings. I use the first three counters in the preceding list plus the Memory Pages/sec counter from the LogicalDisk object to determine the performance on a drive letter basis. Then I use the same counters from the PhysicalDisk object to determine my hardware disk performance. If you look on my web site at http://www.nt-guru.com/windows nt/performance (or in Microsoft BackOffice Administrator's Survival Guide and Internet Information Server for Windows NT Unleashed)., you will find the LogicalDisk.PMW and PhysicalDisk.PMW Performance Monitor workspace files. These files include basic chart, alert, and report examples for you to use as a starting point.
If you want to see these examples in action, run two copies of the Performance Monitor and load LogicalDisk.PMW into one copy and PhysicalDisk.PMW into the other. Then run the DiskHog.EXE program. This program takes one command-line argument: the drive letter to write its data file tofor example, DiskHog H:. The default if no drive letter is specified is drive C. This program writes up to 1,000 1 MB blocks of data to the file (DumpFile.DAT), which can total almost 1 GB. The purpose of this program is two-fold. First, you can use it to demonstrate disk activity on logical drives, as shown in Figure 7.6, and disk activity on physical drives, as shown in Figure 7.7. Second, you can use it to test your alert conditions for low disk space. When the program finishes writing the data file, it informs you of how much data was written and prompts you to press a key to continue. At this point, it deletes the data file it created.
Note: Keep in mind that DiskHog.EXE is a simulation designed to overload your disk I/O subsystem. It cannot be used to demonstrate a normal usage pattern for a file server. It is designed only to give you an idea of what to look for in finding performance bottlenecks with the Performance Monitor.
Caution: If you run this program and place the data file on a compressed drive, it most likely will run to completion and write almost 1 GB of data, even if you have less than a couple of hundred megabytes free on the drive. This is because the data block it writes is composed of 1 MB of asterisks (*) and is easily compressible.
Tip: When using Performance Monitor to determine disk activities, you might want to change the default capture rate. I break mine down into 5 seconds, 1 second, 1/10 second, and 1/100 second intervals, depending on the amount of data I want to capture and the server activity.
If you find a bottleneck, you can take several actions in addition to those mentioned at the beginning of this section:
Create a mirror set. This can double your read performance if your disk driver can support multiple asynchronous I/O requests. This rules out most IDE and EIDE controllers, which use the default ATDISK driver.
Create a stripe set or stripe set with parity. This can increase both read and write performance if your disk driver can support multiple asynchronous I/O requests. The best choice for this is to use a 32-bit SCSI bus master controller.
If your budget is limited, spend your money on a fast SCSI controller and average disk drives (in terms of seek time), because the SCSI controller has more of an impact on a two-drive system.
If you have sufficient funds, purchase drives with the lowest seek time because the time seeking tracks (to find the data) versus The data-transfer time is 10 to 1 or more.
Distribute the workload (one reason to use the LogicalDisk.PMW example) to place highly accessed data files on different drives. You can place the application files for Microsoft Office on your first physical drive and your SQL Server databases on your second physical drive, for example. Do not place them on different logical drives on the same physical drive because this defeats the purpose of distributing the load.
If you use a FAT file system, defragment it occasionally. This prevents the multiple seeks required to read or write data to the disk.
If you have a volume of more than 400 MB, you should choose the NTFS file system. NTFS partitions make more efficient use of the disk to provide better performance. A FAT partition can support a maximum of 65,536 clusters, for example. On a large partition, the cluster size may be as large as 64 KB. A cluster is the minimum allocation unit, so if you store a 512 byte file, you have wasted 63.5 KB. NTFS partitions can have up to 264 clusters to access the partition, so the cluster size can be much smaller and therefore waste less space.
Note: Executive Software has a disk defragmenter called DiskKeeper that runs as a Windows NT Service. It can defragment your NTFS and FAT partitions.
Most of the network performance tuning options are provided by the graphical interface tools, such as the Control Panel applets and the hardware alternatives. You might want to try using the Registry Editor and Registry keys, however, which include some other mechanisms for configuring the Windows NT Services. Keep in mind that altering any of the Registry keys may prevent a Windows NT service from automatically tuning itself for maximum performance. I have included another example Performance Monitor workspace file on my web site at http://www.nt-guru.com/windows nt/performance called Network.pmw (also available in Microsoft BackOffice Administrator's Survival Guide and Internet Information Server for Windows NT Unleashed); this includes a chart, alert, and report view to help you in your network diagnostics (see Figure 7.8).
The performance object counters included in the chart and alert views are provided to give you a means to monitor how busy your server is and to determine basic network utilization. Table 7.4 lists the object counters I consider to be important for performing these tasks..
Table 7.4. Network performance counters.
Object
Counter
Instance
Description
Network the Interface
Current Bandwidth
Per Interface
An estimated value of current network use in bits per second.
Network Segment
Network Utilization
Per Adapter
An estimated value of the percentage of the network bandwidth currently in use on the network segment.
Server
Pool Nonpaged Failures
N/A
Number of times that allocations from the nonpaged memory pool has failed.
Server
Pool Paged Failures
N/A
Number of times that allocations from the paged memory pool have failed.
Server
Work Item Shortages
N/A
Number of times that a work item could not be allocated. This counter can indicate that the InitWorkItems and MaxWorkItems parameters for the LanMan Server service need to be increased.
Server
Logons Total
N/A
This number is a total count since the computer was last rebooted of all interactive logons, remote logons, service logons, and failed logons.
Server
Logons/sec
N/A
Rate at which all interactive logons, remote logons, service logons, and failed logons are occurring.
Server Work Queues
Work
Per Processor Item Shortages
Indicates the number of failed work item allocations. A number greater than 1 is an indication that the MaxWorkItem parameter should be increased.
Server Work Queues
Queue Length
Per Processor
Indicates the current number of requests currently waiting in the server queue. A consistent number greater than 4 indicates that a faster processor could improve performance.
Redirector
Current Commands
N/A
Indicates the number of outstanding network requests waiting to be serviced. If this number is greater than the number of network adapters installed in the computer, a network bottleneck is present. Adding an additional network adapter may increase performance.
Redirector
Network Errors/sec
N/A
Indicates that serious network errors have occurred. These errors generally are logged in the system event log, so you should look there for further information. If an error occurs, you should take immediate notice and attempt to resolve the situation.
Note: The Network Interface Current Bandwidth counter is available only if you install the Network Monitor Agent. This counter can be used to determine whether your network is overloaded. A value of 50000000.0000 is the 50 percent mark, which indicates that you should consider segmenting your network. Some network Administrators prefer to plan for additional growth and split the network segment at the 3040 percent mark. The Network Segment Network Utilization counter applies only if you have the TCP/IP protocol installed. This counter is in fractional percentages, and 50 percent or more indicates that the network segment should be split as well.
Depending on the size and activity of your Internet Information Server installation, you might run into a few performance-related problems. Before you try to configure the IIS services for better performance, however, you should try using the Performance Monitor to look at processor, memory, disk, or network bottlenecks as described in the previous sections. Only after you have done the best you can to solve those problems should you move on to optimizing your IIS services. The good news is that you can use several IIS counters to determine just how heavy a load your IIS server is carrying, as well as counters to scrutinize each service.
You should start your performance tuning with the general IIS counters, as described in Table 7.5, to get a basic look at how well your IIS server is performing. To determine how well a specific service is performing, you can use the counters in Table 7.6 for your WWW Publishing Service, Table 7.7 for your FTP Publishing Service, and Table 7.8 for your Gopher Publishing Service. You should pay particular attention to the global cache counters mentioned in Table 7.5, because the size of this cache may be changed by modifying the Registry key
The default is to allocate 3 MB (3145728 bytes), and the legal values range from 0 (which disables caching entirely) to FFFFFFFF (or 4 GB). If you are encountering large number of cache flushes, misses, or have a poor hit ratio, increasing this value may improve performance. You should be careful, however, to make sure that you only use physical memory that is not required by the base operating system or SQL Server. Otherwise, you might impact these systems and cause poor IIS performance.
Table 7.5. Global IIS performance counters.
Object
Counter
Description
Internet Information Services Global
Cache Flushes
Specifies how often a cached memory region expired due to changes in IIS files or a directory tree.
Internet Information Services Global
Cache Hits
Specifies how often a reference to a file, directory tree, or IIS specific object was found in the cache.
Internet Information Services Global
Cache Hits %
Specifies the hit ratio of all cache requests.
Internet Information Services Global
Cache Misses
Specifies how often a reference to a file, directory tree, or IIS specific object was not found in the cache.
Internet Information Services Global
Cache Size
Specifies the size of the shared memory cache.
Internet Information Services Global
Cache Used
Specifies the total number of bytes in use (file handles, IIS specific objects, and so on) in the cache.
Internet Information Services Global
Cached File Handles
Total number of file handles contained within the cache.
Internet Information Services Global
Current Blocked Async I/O Requests
Total number of current current asynchronous I/O requests blocked by the bandwidth throttle.
Internet Information Services Global
Directory Listings
Specifies the total number of directory listings contained within the cache.
Internet Information Services Global
Measured Asnyc I/O Bandwidth usage
Specifies the total amount of asynchronous I/O bandwidth average over a minute.
Internet Information Services Global
Objects
Specifies the total number of objects (file handle objects, directory listing objects, and so on) contained within the cache.
Internet Information Services Global
Total Allowed Async I/O Requests
Total number of asynchronous I/O requests admissible by the bandwidth throttle.
Internet Information Services Global
Total Blocked Async I/O Requests
Total number of asynchronous I/O requests blocked by the bandwidth throttle.
Internet Information Services Global
Total Rejected Async I/O Requests
Total number of asynchronous I/O requests rejected by the bandwidth throttle.
Table 7.6. HTTP service performance counters.
Object
Counter
Description
HTTP Service
Bytes Received/sec
Specifies the rate (in bytes/sec) at which the HTTP server is receiving data.
HTTP Service
Bytes Sent/sec
Specifies the rate (in bytes/sec) at which the HTTP server is transmitting data.
HTTP Service
Bytes Total/sec
Specifies the total amount of data being transmitted or received by the HTTP server in bytes per second.
HTTP Service
CGI Requests
Specifies the number of common gateway interface requests received by the HTTP server.
HTTP Service
Connection Attempts
Specifies the total number of attempts made to connect to the HTTP server.
HTTP Service
Connections/sec
Specifies the number of connections to the HTTP server per second.
HTTP Service
Current Anonymous Users
Specifies how many anonymous users currently are connected to the HTTP server.
HTTP Service
Current CGI Requests
Specifies how many CGI requests currently are being processed by the HTTP server.
HTTP Service
Current Connections
Specifies the current number of connections to the HTTP server.
HTTP Service
Current ISAPI Extension Requests
Specifies the current number of ISAPI requests being processed by the server.
HTTP Service
Current NonAnonymous Users
Specifies the total number of users currently connected to the HTTP server using a domain user account.
HTTP Service
File Received
Specifies the total number of files received by the HTTP server.
HTTP Service
File Sent
Specifies the total number of files transmitted by the HTTP server.
HTTP Service
File Total
Specifies the sum of the total number of files transmitted and received.
HTTP Service
Get Requests
Specifies the total number of HTTP requests using the GET method.
HTTP Service
Head Requests
Specifies the total number of HTTP requests using the HEAD method.
HTTP Service
ISAPI Extension Requests
Specifies the total number of ISAPI requests being processed by the server.
HTTP Service
Logon Requests
Specifies the total number of logon attempts that have been made by the HTTP server.
HTTP Service
Maximum Number of Anonymous Users
Specifies the maximum number of simultaneous connected anonymous users.
HTTP Service
Maximum CGI Requests
Specifies the maximum number of simultaneous CGI requests processed by the HTTP server.
HTTP Service
Maximum Connection
Specifies the maximum number of simultaneous connections to the HTTP server.
HTTP Service
Maximum ISAPI Extension Requests
Specifies the maximum number of simultaneous ISAPI requests processed by the HTTP server.
HTTP Service
Maximum NonAnonymous Users
Specifies the maximum number of simultaneous connected users using a domain user account.
HTTP Service
Not Found Errors
Specifies the total number of requests that failed due to a missing document.
HTTP Service
Other Requested Methods
Specifies the total number of HTTP requests that do not use the GET, HEAD, or POST method. This can include PUT, DELETE, LINK, or other methods.
HTTP Service
Post Requests
Specifies the total number of HTTP requests using the POST method.
HTTP Service
Total Anonymous Users
Specifies the total number of anonymous users that have ever connected to the HTTP server.
HTTP Service
Total NonAnonymous Users
Specifies the total number of users that have ever connected to the HTTP server using a domain user account.
Table 7.7. The FTP server performance counters.
Object
Counter
Description
FTP Server
Bytes Received/sec
Specifies the rate (in bytes/sec) at which the FTP server is receiving data.
FTP Server
Bytes Sent/sec
Specifies the rate (in bytes/sec) at which the FTP server is transmitting data.
FTP Server
Bytes Total/sec
Specifies the total amount of data being transmitted or received by the FTP server in bytes per second.
FTP Server
Current Anonymous Users
Specifies how many anonymous users currently are connected to the FTP server.
FTP Server
Current Connections
Specifies the current number of connections to the FTP server.
FTP Server
Current NonAnonymous Users
Specifies the total number of users currently connected to the FTP server using a domain user account.
FTP Server
File Received
Specifies the total number of files received by the FTP server.
FTP Server
File Sent
Specifies the total number of files transmitted by the FTP server.
FTP Server
File Total
Specifies the sum of the total number of files transmitted and received.
FTP Server
Logon Requests
Specifies the total number of logon attempts that have been made by the FTP server.
FTP Server
Maximum Anonymous Users
Specifies the maximum number of simultaneous connected anonymous users.
FTP Server
Maximum Connections
Specifies the maximum number of simultaneous connections to the FTP server.
FTP Server
Maximum NonAnonymous Users
Specifies the maximum number of simultaneous connected users using a domain user account.
FTP Server
Total Anonymous Users
Specifies the total number of anonymous users that have ever connected to the FTP server.
FTP Server
Total NonAnonymous Users
Specifies the total number of users that have ever connected to the FTP server using a domain user account.
Table 7.8. Gopher service performance counters.
Object
Counter
Description
Gopher Service
Aborted Connections
Specifies the total number of connections that failed due to errors or over limit requests made to the Gopher server.
Gopher Service
Bytes Received/sec
Specifies the rate (in bytes/sec) at which the Gopher server is receiving data.
Gopher Service
Bytes Sent/sec
Specifies the rate (in bytes/sec) at which the Gopher server is transmitting data.
Gopher Service
Bytes Total/sec
Specifies the total amount of data being transmitted or received by the Gopher server in bytes per second.
Gopher Service
Connection Attempts
Specifies the total number of attempts made to connect to the Gopher server.
Gopher Service
Connections in Error
Specifies the number of errors that occurred while being processed by the Gopher server.
Gopher Service
Current Anonymous Users
Specifies how many anonymous users currently are connected to the Gopher server.
Gopher Service
Current Connections
Specifies the current number of connections to the Gopher server.
Gopher Service
Current NonAnonymous Users
Specifies the total number of users currently connected to the Gopher server using a domain user account.
Gopher Service
Directory Listing Sent
Specifies the total number of directory listings transmitted by the Gopher server.
Gopher Service
File Sent
Specifies the total number of files transmitted by the Gopher server.
Gopher Service
File Total
Specifies the sum of the total number of files transmitted and received.
Gopher Service
Gopher Plus Requests
Specifies the total number of Gopher Plus requests received by the Gopher server.
Gopher Service
Logon Requests
Specifies the total number of logon attempts that have been made by the Gopher server.
Gopher Service
Maximum Anonymous Users
Specifies the maximum number of simultaneous connected anonymous users.
Gopher Service
Maximum NonAnonymous Users
Specifies the maximum number of simultaneous connected users using a domain user account.
Gopher Service
Maximum Connections
Specifies the maximum number of simultaneous connected users to the Gopher server.
Gopher Service
Searches Sent
Specifies the total number of searches performed by the Gopher server.
Gopher Service
Total Anonymous Users
Specifies the total number of anonymous users that have ever connected to the Gopher server.
Gopher Service
Total NonAnonymous Users
Specifies the total number of users that have ever connected to the Gopher server using a domain user account.
In this chapter, you looked at how to optimize your server using example performance monitor charts, alerts, reports, and workspace files. These files were used with sample programs to illustrate how to find processor, memory, disk, and network bottlenecks. You also looked at the performance counters you can use to determine how well your IIS server is performing.
In the next chapter, you will begin to use your new IIS to its fullest extentby publishing on the World Wide Web with Microsoft Office and Microsoft FrontPage.