Tải bản đầy đủ (.pdf) (82 trang)

microsoft press internet information services iis 70 resource kit phần 9 potx

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (690.89 KB, 82 trang )

620

Part IV:

Troubleshooting and Performance

Table 17-4 Memory Counters to Measure
Counter Name

Description

Process(w3wp)\Virtual Bytes

The current size, in bytes, of the virtual address
space the process is using. Use of virtual address
space does not necessarily imply corresponding
use of either disk or main memory pages. Virtual
space is finite, and the process can limit its ability
to load libraries.

Process(w3wp)\Working Set

The current size, in bytes, of the Working Set of
this process. The Working Set is the set of
memory pages touched recently by the threads
in the process. If free memory in the computer is
above a threshold, pages are left in the Working
Set of a process even if they are not in use. When
free memory falls below a threshold, pages are
trimmed from Working Sets. If they are needed,
they will then be soft-faulted back into the


Working Set before leaving main memory.

Impact of Constraints
When a server is low on RAM, it uses the paging file, causing the worker process to have to
retrieve data from disk, slowing down performance. This can be an expensive operation,
because the application has introduced another potential bottleneck, Disk I/O (Input/Output).
An application that is forced to use a portion of the information swapped to the paging file
has added latency and causes the server to use more resources.
Generally, with 32-bit operating systems, the recommended approach is to set the paging file
size to be 1.5 times the amount of RAM. In a 64-bit environment, you can set the operating
system to automatically handle the paging file size.

Countermeasures
One countermeasure against memory pressure is to verify that your Web server paging file is
configured properly and optimized on a separate set of disks. Spreading a paging file across
separate physical disks enables you to improve paging file performance by using drives that
do not contain your site’s content or log files. Although these steps are basic, they can go a
long way toward helping your application’s performance. They can also save your company
money by getting the most out of your servers.
Understanding how many resources a typical transaction uses is important. This number can
be valuable when you calculate what your production environment and monitoring thresholds will be. If your database holds a lot of detail data, you can calculate how the data might
grow over a period of months or years and how this might impact your application. It might
perform well at first, but you might find that as the amount detail data grows, your application
will be slower, and server performance will suffer.


Chapter 17:

Performance and Tuning


621

Hard Disks
As faster and faster disks evolve, chances of the disk being the issue become less likely.
Redundant Array of Inexpensive Disk (RAID) and striping technologies are not really IISrelated performance tricks, but they can help increase your server’s overall performance. The
real effect on hard disks depends on how much RAM your machine has.

What Causes Hard Disk Pressure?
Typically, pressure is a matter of the amount of disk reads and writes. A Web server that has a
high ratio of reads to writes tends to perform better. The Reliability and Performance Monitor
is a great tool for analyzing the total number of reads and writes a Web server generates. If
your application requires a lot of writes, you should have faster disks and a RAID implementation to support them. Disk bottlenecks can be improved by using Kernel-mode caching,
which greatly eliminates the number of direct reads from the disk.

Hard Disk Counters to Monitor
See Table 17-5 for a list of common hard disk counters that help identify which processes and
how much of the server resources are being used when your IIS 7.0 server is experiencing hard
disk-related issues.
Table 17-5 Disk Counters to Measure
Counter Name

Description

PhysicalDisk(_Total)\% Disk Time

The percentage of elapsed time that the selected
disk drive was busy servicing read or write requests.

PhysicalDisk(_Total)\% Disk Read Time


The percentage of elapsed time that the selected
disk drive was busy servicing read requests.

PhysicalDisk(_Total)\% Disk Write Time

The percentage of elapsed time that the selected
disk drive was busy servicing write requests.

PhysicalDisk(_Total)\Current Disk Queue
Length

The number of requests outstanding on the disk at
the time the performance data is collected. It also
includes requests in service at the time of the
collection. This is an instantaneous snapshot, not an
average over the time interval. Multispindle disk
devices can have multiple requests that are active at
one time, but other concurrent requests are awaiting
service. This counter might reflect a transitory high
or low queue length, but if there is a sustained
load on the disk drive, it is likely that this will be
consistently high. Requests experience delays
proportional to the length of this queue minus
the number of spindles on the disks. For good
performance, this difference should average less
than two.


622


Part IV:

Troubleshooting and Performance

Table 17-5 Disk Counters to Measure
Counter Name

Description

PhysicalDisk\Disk Reads/sec

The rate of read operations on the disk.

PhysicalDisk\Disk Writes/sec

The rate of write operations on the disk.

PhysicalDisk\Avg. Disk Bytes/Read

The average number of bytes transferred from the
disk during read operations.

PhysicalDisk\Avg. Disk Bytes/Write

The average number of bytes transferred to the disk
during write operations.

Impact of Constraints
Your application’s performance and throughput will be affected if your IIS 7.0 server does not
have enough RAM. When a server has to start writing and retrieving information from disk,

there will be latency to your application’s performance. Disk paging can be an expensive task,
and using disk performance counters can help you measure how your server is performing.

Countermeasures
You can implement a few countermeasures to help prevent disk latency. Here are some things
to keep in mind:


Choose the correct RAID for your server(s).



When implementing RAID, select a hardware controller over a software RAID solution.
It’s definitely worth the investment.



You can spread your paging file across multiple disks.



More spindles help with performance. Several smaller disks are faster than one large
drive.



Speed is very important. Faster disks help with performance, and in the long run they
are worth the few extra dollars they cost.




Definitely monitor performance by using the counters mentioned in this section.



Keep your disks from becoming fragmented.



For a Web server, have the logging and content on separate disk from the operating
system. Logging can be an expensive operation, so try to move logging to a separate set
of disks. Alternatively, offload it to a remote server.

Note To help you out with logging, we’d like to point out an option called httpLogging,
which enables you to control how much data is logged to your IIS log files. One attribute of
httpLogging, selectiveLogging, enables you to control which status codes are logged to your IIS
Logs. By default, the selectiveLogging option is set to LogAll, which means log all status codes.
You can set the value to LogSuccessful, which logs all HTTP status codes from 100 to 399. The
LogError option logs HTTP status codes from 400 to 999. The following example shows you


Chapter 17:

Performance and Tuning

623

how to adjust the selectLogging setting by using Appcmd. You can also set httpLogging to
dontLog, which will prevent any logs from being generated. Logging is discussed more in
Chapter 15, “Logging.”

//Code sample to set the selectiveLogging attribute using Appcmd.
//LogAll is the default, LogSuccessful and LogError are the other options.
Appcmd set config -section:httpLogging -selectiveLogging:LogSuccessful
//Here is the part of the schema that controls the system.webServer/ httpLogging/selectiveLogging attribute
<attribute name="selectiveLogging" type="enum" defaultValue="LogAll">
<enum name="LogAll" value="0" />
<enum name="LogSuccessful" value="1" />
<enum name="LogError" value="2" />
</attribute>

Turn off unnecessary disk intensive services such as Index Server or other search type
functions if the service is not in use. These types of services can continually index content and
take up precious disk cycles.
Tuning your hard disk subsystem is one issue you’ll probably not have to deal with when
working to optimize your system. Providing your server with enough RAM can go a long way
towards ensuring that your hard disk is not the cause when a problem arises.

Network
One of the best performance enhancements in Microsoft Windows Server 2008 is a complete
redesign of the Transmission Control Protocol/Internet Protocol (TCP/IP) stack, also
known as the Next Generation TCP/IP stack. The TCP/IP stack has been redesigned to
enable high-speed multi-gigabit capabilities without consuming all of the CPU power and
resources on the server. It integrates security products into the Windows platform and makes
it more manageable. In addition, the TCP/IP stack has been redesigned to make it more
easily serviced, to add capabilities, and to let third-party independent software vendors (ISVs)
add capabilities to it (specifically in the firewall and antivirus categories).

What Causes Network Pressure?
In a perfect world, bandwidth restrictions would not be an issue. Switched networks as well
as 1 GB and greater network speeds have helped, but network utilization still can be a

bottleneck. How you deal with it can make your applications successful or not. The increasing
availability of high-speed networks and broadband connections does not guarantee a low
latency experience.


624

Part IV:

Troubleshooting and Performance

High demand for content such as video streaming or audio files can lead to pressure on the
network. The Internet is one big wide area network, and it takes only one slow connection to
become saturated and cause packet loss. When packet loss occurs, higher latency and slower
response times for applications can occur. Low latency and slow application response are less
likely in a local area network. However, the network is only as strong as the weakest link.

Network Counters to Monitor
See Table 17-6 for a list of common network counters used to identify network-related issues
on your IIS 7.0 server.
Table 17-6 Network Counters to Measure
Counter Name

Description

Network Interface(NICNAME)\Bytes Total/sec The rate at which bytes are sent and received over
each network adapter, including framing characters. Network Interface\Bytes Total/sec is a sum of
Network Interface\Bytes Received/sec and Network
Interface\Bytes Sent/sec.
Network Interface(NICNAME)\Current Band- An estimate of the current bandwidth of the netwidth

work interface in bits per second (BPS). For interfaces that do not vary in bandwidth or for those where
no accurate estimation can be made, this value is
the nominal bandwidth.

Impact of Constraints
Dealing with slow router points or switches that are saturated can constrain how you provide
services and keep the network functional. Using QoS (Quality of Service) and scheduling
network-intensive operations during off-hours can help the impact on your network.
Having tools in place to monitor your network can help you spot trends and understand
if your network is operating efficiently. The Next Generation TCP/IP stack supports the
IETF draft RFC 4898, “TCP Extended Statistics MIB,” which defines extended performance
statistics for TCP. By analyzing ESTATS on a connection, you can determine whether a
connection’s performance is based on the sending application, the receiving application, or
the network. ESTATS is disabled by default and can be enabled per connection. With
ESTATS, non-Microsoft independent software vendor (ISVs) can create powerful diagnostics
and network throughput analysis applications. Tcpanalyzer.exe, which is available in the
Windows Vista SDK, is a diagnostic tool based on ESTATS.
The Explicit Congestion Notification (ECN) feature also enhances performance. When a TCP
segment is lost, TCP assumes that the segment was lost due to congestion at a router, and it
performs congestion control, dramatically lowering the TCP sender’s transmission rate. With
ECN support on both TCP peers and in the routing infrastructure, a router experiencing
congestion mark packets as it forwards them. TCP peers receiving marked packets lower their


Chapter 17:

Performance and Tuning

625


transmission rate to ease congestion and prevent segment losses. Detecting congestion
before packet losses are incurred increases the overall throughput between TCP peers. ECN is
not enabled by default. To enable ECN, run this command: netsh interface tcp set global
ecncapability=enabled.

Countermeasures
How do you know what your network utilization is? Right-click in the Start Bar, select Task
Manager, and navigate to the Networking tab. Select the network interface you would like
to view and check its network utilization statistics. If your primary network card is close to
100 percent, the card is likely a bottleneck in the performance of your application. Generally,
you should start to investigate if network utilization is around 50 percent. Figure 17-3 shows
how Task Manager presents network utilization statistics.

Figure 17-3 Network utilization in Windows Task Manager.

The Next Generation TCP/IP stack is a complete redesign of TCP/IP functionality for
both IPv4 and IPv6 that meets the connectivity and performance needs of today’s varied
networking environments and technologies. The following features are new or enhanced:


Receive Window Auto-Tuning



Compound TCP



Enhancements for high-loss environments




Neighbor Unreachability Detection for IPv4



Dead Gateway Detection


626

Part IV:

Troubleshooting and Performance



Path Maximum Transmission Unit (PMTU) Black Hole Router Detection



Routing Compartments



Network Diagnostics Framework Support



Windows Filtering Platform




Explicit Congestion Notification

With its many new features and enhancements, Windows Server 2008 should help keep
network pressure at a minimum. For more information, see the article posted on TechNet
called “New Networking Features in Windows Server 2008 and Windows Vista” at
/>
Application-Level Counters
Microsoft provides several key application-level counters that can be useful in troubleshooting
your application. Table 17-7 presents a subset of counters that can help troubleshoot ASP.NET
and Web-related issues.
Table 17-7 Application Counters
Counter Name

Description

.NET CLR Exceptions(w3wp)\# of Exceps Thrown The number of exceptions thrown per second.
/ sec
These include both .NET exceptions and unmanaged exceptions that get converted into .NET exceptions (e.g., a null pointer reference exception
in unmanaged code would get rethrown in
managed code as a .NET System.NullReferenceException). This counter includes both handled
and unhandled exceptions. Exceptions should
only occur in rare situations and not in the
normal control flow of the program; this counter
was designed as an indicator of potential
performance problems due to large (>100s) rate
of exceptions thrown. This counter is not an
average over time; it displays the difference

between the values observed in the last two
samples divided by the duration of the sample
interval.
.NET CLR Jit(w3wp)\% Time in Jit

The percentage of elapsed time spent in JIT
compilation since the last JIT compilation phase.
This counter is updated at the end of every JIT
compilation phase. A JIT compilation phase is the
phase when a method and its dependencies are
being compiled.

.NET CLR Jit(w3wp)\IL Bytes Jitted / sec

The total IL bytes jitted since the start of the
application. This counter is exactly equivalent to
the “Total # of IL Bytes Jitted” counter.


Chapter 17:

Performance and Tuning

627

Table 17-7 Application Counters
Counter Name

Description


.NET CLR Loading(w3wp)\% Time Loading
.NET CLR Loading(w3wp)\Current appdomains

The current number of AppDomains loaded in
this application. AppDomains (application
domains) provide a secure and versatile unit of
processing that the CLR can use to provide
isolation between applications running in the
same process.

.NET CLR Loading(w3wp)\Current Assemblies

The current number of Assemblies loaded across
all AppDomains in this application. If the Assembly is loaded as domain-neutral from multiple
AppDomains, then this counter is incremented
once only. Assemblies can be loaded as domainneutral when their code can be shared by all AppDomains, or they can be loaded as domain-specific when their code is private to the
AppDomain.

.NET CLR LocksAndThreads(w3wp)\Queue
Length / sec

The total number of times threads in the CLR
have attempted to acquire a managed lock unsuccessfully. Managed locks can be acquired in
many ways—by the “lock” statement in C#, or by
calling System.Monitor.Enter, or by using MethodImplOptions.Synchronized custom attribute.

.NET CLR LocksAndThreads(w3wp)\Total # of
Contentions

The total number of times threads in the CLR

have attempted to acquire a managed lock unsuccessfully. Managed locks can be acquired in
many ways—by the “lock” statement in C#, or by
calling System.Monitor.Enter, or by using MethodImplOptions.Synchronized custom attribute.

.NET CLR Memory(w3wp)\% Time in GC

The percentage of elapsed time that was spent in
performing a garbage collection (GC) since the
last GC cycle. This counter is usually an indicator
of the work done by the Garbage Collector on
behalf of the application to collect and compact
memory. This counter is updated only at the end
of every GC, and the counter value reflects the
last observed value; it is not an average.

.NET CLR Memory(w3wp)\# Total Committed
Bytes

The amount of virtual memory (in bytes) currently committed by the Garbage Collector. (Committed memory is the physical memory for which
space has been reserved on the disk paging file.)

.NET CLR Memory(w3wp)\# Bytes in all Heaps

The sum of four other counters—Gen 0 Heap
Size, Gen 1 Heap Size, Gen 2 Heap Size, and the
Large Object Heap Size. This counter indicates
the current memory allocated in bytes on the GC
Heaps.



628

Part IV:

Troubleshooting and Performance

Table 17-7 Application Counters
Counter Name

Description

.NET CLR Memory(w3wp)\# Gen 0 Collections

The number of times the generation 0 objects
(youngest; most recently allocated) are garbage
collected (Gen 0 GC) since the start of the
application. Gen 0 GC occurs when the available
memory in generation 0 is not sufficient to satisfy
an allocation request. This counter is incremented
at the end of a Gen 0 GC. Higher generation GCs
include all lower generation GCs. This counter is
explicitly incremented when a higher generation
(Gen 1 or Gen 2) GC occurs. _Global_ counter
value is not accurate and should be ignored. This
counter displays the last observed value.

.NET CLR Memory(w3wp)\# Gen 1 Collections

The number of times the generation 1 objects
are garbage collected since the start of the

application. The counter is incremented at the
end of a Gen 1 GC. Higher generation GCs include all lower generation GCs. This counter is
explicitly incremented when a higher generation
(Gen 2) GC occurs. _Global_ counter value is not
accurate and should be ignored. This counter
displays the last observed value.

.NET CLR Memory(w3wp)\# Gen 2 Collections

The number of times the generation 2 objects
(older) are garbage collected since the start of
the application. The counter is incremented at
the end of a Gen 2 GC (also called full GC).
_Global_ counter value is not accurate and
should be ignored. This counter displays the last
observed value.

.NET CLR Memory(w3wp)\# Induced GC

The peak number of times a garbage collection
was performed because of an explicit call to
GC.Collect. It’s a good practice to let the GC tune
the frequency of its collections.

.NET CLR Memory(w3wp)\Allocated Bytes/sec

The rate of bytes per second allocated on the GC
Heap. This counter is updated at the end of
every GC, not at each allocation. This counter
is not an average over time; it displays the

difference between the values observed in the
last two samples divided by the duration of the
sample interval.


Chapter 17:

Performance and Tuning

629

Table 17-7 Application Counters
Counter Name

Description

.NET CLR Memory(w3wp)\Finalization Survivors The number of garbage collected objects that
survive a collection because they are waiting to
be finalized. If these objects hold references to
other objects, then those objects also survive
but are not counted by this counter; the
“Promoted Finalization-Memory from Gen 0”
and “Promoted Finalization-Memory from
Gen 1” counters represent all the memory that
survived due to finalization. This counter is not a
cumulative counter; it’s updated at the end of
every GC with count of the survivors during that
particular GC only. This counter was designed to
indicate the extra overhead that the application
might incur because of finalization.

.NET CLR Memory(w3wp)\Gen 0 Heap Size

The maximum bytes that can be allocated in
generation 0 (Gen 0); it does not indicate the
current number of bytes allocated in Gen 0. A
Gen 0 GC is triggered when the allocations since
the last GC exceed this size. The Gen 0 size is
tuned by the Garbage Collector and can change
during the execution of the application. At the
end of a Gen 0 collection, the size of the Gen 0
heap is in fact 0 bytes; this counter displays the
size (in bytes) of allocations that would trigger
the next Gen 0 GC. This counter is updated at the
end of a GC; it’s not updated on every allocation.

.NET CLR Memory(w3wp)\Gen 1 Heap Size

The current number of bytes in generation 1 (Gen
1); this counter does not display the maximum
size of Gen 1. Objects are not directly allocated in
this generation; they are promoted from previous
Gen 0 GCs. This counter is updated at the end of
a GC; it’s not updated on every allocation.

.NET CLR Memory(w3wp)\Gen 2 Heap Size

The current number of bytes in generation 1
(Gen 1); this counter does not display the
maximum size of Gen 1. Objects are not directly
allocated in this generation; they are promoted

from previous Gen 0 GCs. This counter is updated
at the end of a GC; it’s not updated on every
allocation.

.NET CLR Memory(w3wp)\Large Object Heap
Size

The current size of the Large Object Heap in
bytes. Objects greater than 20 kilobytes (KB) are
treated as large objects by the Garbage Collector
and are directly allocated in a special heap; they
are not promoted through the generations.
This counter is updated at the end of a GC; it’s
not updated on every allocation.


630

Part IV:

Troubleshooting and Performance

Table 17-7 Application Counters
Counter Name

Description

.NET CLR Memory(w3wp)\Process ID

The process ID of the CLR process instance being

monitored.

.NET CLR Security(w3wp)\% Time in RT checks

The percentage of elapsed time spent in
performing run-time Code Access Security (CAS)
checks since the last such check. CAS allows code
to be trusted to varying degrees and enforces
these varying levels of trust depending on code
identity. This counter is updated at the end of a
run-time security check. It represents the last
observed value; it’s not an average.

ASP.NET Applications(__Total__)\Cache Total
Trims

Total number of entries forcibly removed from
the cache due to memory pressure.

ASP.NET Applications(__Total__)\Cache Total
Entries

Total number of entries within the cache (both
internal and user added)

ASP.NET Applications(__Total__)\Cache Total Hit Ratio of hits from all cache calls.
Ratio
ASP.NET Applications(__Total__)\Cache Total
Turnover Rate


Number of additions and removals to the total
cache per second.

ASP.NET Applications(__Total__)\Output Cache
Entries

Current number of entries in the output cache.

ASP.NET Applications(__Total__)\Output Cache
Hits

Total number of output cacheable requests
served from the output cache.

ASP.NET Applications(__Total__)\Output Cache
Hit Ratio

Ratio of hits to requests for output cacheable
requests.

ASP.NET Applications(__Total__)\Output Cache
Turnover Rate

Number of additions and removals to the output
cache per second.

ASP.NET Applications(__Total__)\Compilations
Total

Number of .asax, .ascx, .ashx, .asmx, or .aspx

source files dynamically compiled.

ASP.NET Applications(__Total__)\Errors Total/
Sec

Rate of errors occurred.

ASP.NET Applications(__Total__)\Pipeline
Instance Count

Number of active pipeline instances.

ASP.NET Applications(__Total__)\Requests
Executing

The number of requests currently executing.

ASP.NET Applications(__Total__)\Requests in
Application Queue

The number of requests in the application
request queue.

ASP.NET Applications(__Total__)\Requests/Sec

The number of requests executed per second.

ASP.NET\Application Restarts

Number of times the application has been

restarted during the Web server's lifetime.

ASP.NET\Request Wait Time

The number of milliseconds the most recent
request was waiting in the queue.


Chapter 17:

Performance and Tuning

631

Table 17-7 Application Counters
Counter Name

Description

ASP.NET\Requests Current

The current number of requests, including those
that are queued, currently executing, or waiting
to be written to the client. Under the ASP.NET
process model, when this counter exceeds the
requestQueueLimit defined in the processModel
configuration section, ASP.NET will begin
rejecting requests.

ASP.NET\Requests Queued


The number of requests waiting to be processed.

ASP.NET\Requests Rejected

The number of requests rejected because the
request queue was full.

Web Service(_Total)\Get Requests/sec

The rate at which HTTP requests using the GET
method are made. GET requests are the most
common HTTP request.

Web Service(_Total)\Post Requests/sec

The rate at which HTTP requests using the POST
method are made.

Web Service(_Total)\Connection Attempts/sec

The rate that connections to the Web service are
being attempted.

Web Service(_Total)\Current Connections

Current Connections is the current number of
connections established with the Web service.

Web Service(_Total)\ISAPI Extension Requests/

sec

The rate at which ISAPI Extension requests are
received by the Web service.

Web Service\Service Uptime

The length of time the Web Service has been
running.

Web Service\Total Method Requests

The number of all HTTP requests (since service
startup).

Web Service Cache\URI Cache Hits %

The ratio of user-mode URI Cache Hits to total
cache requests (since service startup).

64-Bit Mode vs. 32-Bit Mode
In general, 64-bit computing has greatly expanded resource limits over 32-bit computing. At
first, the limits seem very high compared to 32-bit (x86) computing. Windows Server 2008
offers two 64-bit versions. The x64 platform provides the ability to run 32-bit and 64-bit
on the same machine, and this solution is the obvious choice for most server application
deployments, whether small or large.
The other type of 64-bit version is an Itanium-based system. IA64 systems are best suited for
extremely large database and custom application solutions. For our purposes, the rest of
this section discusses x64.
One of the major differences between IIS 6.0 and IIS 7.0 is that you could run a 32-bit

application on a 64-bit machine with IIS 6.0, but the entire IIS 6.0 server is running in 32-bit


632

Part IV:

Troubleshooting and Performance

mode. In IIS 7.0, you can split the .NET version on a per-application basis. You have the
potential to run the application pools presented in Table 17-8 on a single x64 machine.
Table 17-8 Application Pool Version Types
Application Version

.NET Framework Version

32-bit application pool

ASP.NET 1.1

32-bit application pool

ASP.NET 2.0

64-bit application pool

ASP.NET 2.0

All handlers for various ASP.NET versions/pipeline modes are registered globally by the IIS
7.0 core server. This enables you to run an ASP.NET 2.0 application in 32-bit and 64-bit

mode on the same machine. The appropriate preconditions and settings on the application
pool automatically select the correct set of handlers that apply to that application pool. The
preconditions apply to Internet Server Application Programming Interface (ISAPI) filters also.
Another advantage of running 32-bit applications on a 64-bit machine is that 32-bit processes
running under Windows-on-Windows 64-bit (WoW64) get 4 GB of addressable virtual
memory. Kernel memory is not sacrificed to squeeze out more virtual memory for user mode
processes. Even with 32-bit IIS worker processes, the kernel runs 64-bit natively.
Table 17-9 presents a breakdown of the differences between Windows Server 2008 32-bit and
64-bit CPU and memory limits for each operating system version.
Table 17-9 Server CPU/Memory Limits for Windows Server 2008
Technology

Web Edition

Standard
Edition

Enterprise

DataCenter

IA-Based
Systems

Sockets, x86

4

4


8

32

n/a

Sockets, x64

4

4

8

64

n/a

Sockets, IA64

n/a

n/a

n/a

n/a

64


RAM, 32-bit

4 GB

4 GB

64 GB

64 GB

n/a

RAM, 64-bit

32 GB

32 GB

2 TB

2 TB

n/a

RAM, IA64

n/a

n/a


n/a

n/a

2 TB

IIS 7.0 provides a compelling reason to move your systems to Windows Server 2008 x64-bit
edition. Being able to run .NET 1.1 and 2.0, as well as other frameworks on an application
pool basis, enables you to experience the benefits of 64-bit computing without making any
code changes.

Configuring for Performance
Configuring your environment for performance requires that you truly understand your
applications and how your users will interact with the applications. How many times have you
heard administrators tell the tale that an application worked great in the lab, but when it was


Chapter 17:

Performance and Tuning

633

deployed to production, it crashed? Sound familiar? I hope not! Performing adequate testing
beforehand should be a requirement before you purchase production hardware.
You should consider a few scenarios when configuring your servers. First, you need to know
some basic information, such as the following:


How many users do you expect to use your application?




At peak usage, how many concurrent users do you expect?



Where are your users based—are they on well-connected networks such as a local area
network, or are they connecting over the Internet?



How long will a typical session last?



Does your application require session state?



Does your application interact with a database?



How much RAM does a typical session take?



Will your application be disk-intensive?


These questions are important to understand when you are configuring your environment.
Your answers can influence the decision to run everything on a stand-alone or on a set of
servers. A set of servers could include a Web farm front end with a separate database server.
If your current application is in production, you can use the Reliability and Performance
Monitor to capture baseline numbers that will help you load-test your environment. If your
application is brand new, you’ll have to calculate usage numbers and estimate how much
traffic you expect.
This section of the chapter is not intended to provide an in-depth discussion of application
architecture. However, good development practices and methodologies can have a great
impact on how you set up and scale your environment. The ultimate goal is to have well-tuned
applications that provide good user experiences. A lot of planning up front can give you big
wins when you decide to get in the lab and test your applications.

Server Level
You can do many things at the server level to configure your environment for performance.
Before you do anything at server level, however, understanding the application you want to
support will go a long way toward creating a smooth running environment. Here are a few
things you can do to make sure your server will perform at acceptable levels:


If possible, run the 64-bit version of Windows Server 2008.



Configure your application pools to run 32-bit mode.



Make sure your server has enough RAM.



634

Part IV:

Troubleshooting and Performance



Make sure your server firmware and basic input/output system (BIOS) are up to date.



If running a Web farm, try to keep your servers configured identically.



Configure your system to use RAID.



Install only necessary software such as monitoring agents, antivirus software, and so on.

IIS
IIS has always been pretty much a self-tuning service. There have been a few registry tweaks
here and a metabase adjustment there, but overall, IIS has a good reputation for self-tuning
based on a wide variety of workloads. IIS 7.0 continues this behavior. Before we say that IIS 7.0
will scale on any type of hardware, though, you need to take into account the types of applications that you will be deploying. The application types that you choose can greatly change
IIS performance, but they have little to do with IIS 7.0 itself. The hardware setup, amount of
RAM, and speed of the disk all contribute to the overall Web server experience.


Optimizing for the Type of Load
How you optimize your environment really depends on your needs. For example, do you need
to support a large concurrent connection base of users, or is it important to provide numbers
of transactions? The following sections provide a couple examples illustrating what to take
into account when optimizing your environment.

Load
Load is one of the first performance requirements that should be identified in the planning
stages for your application. If your application will have spikes of load, you’ll need to account
for that in your design. An application that has peaks and valleys can be harder to design for.
Most likely, you’ll need to account for spikes no matter what the load is.
Consider this example: You are the director of IT for Contoso Ltd. You are aware that every
year on December 31, the Contoso.com Web site experiences a thousand times more than
normal traffic. The visitors are submitting expenses for the previous year, so that they can be
reimbursed. Does that mean you scale your environment to meet the volume on December 31,
and the rest of the year you have excess capacity? Probably not, but realistically, you need to
take into account how to plan for the additional load created by so many visitors accessing the
site at one time. You may want to consider using staggered schedules or some other option
to prevent all the users from being on the system at once. This might seem like an unreal
example, but it provides a picture of what you should define as load and what kinds of things
you need to think about when testing. In this scenario, for example, when a user finishes
submitting expenses and clicks Submit, that person is going to want the transaction to work
so that they don’t have to enter the information again—and of course so they get paid back
for their expenses sooner rather than later.


Chapter 17:

Performance and Tuning


635

As another example, consider that you are in a situation in which you have to scale your
application to meet a lot of concurrent connections. In such a case, you would want to look at
having multiple servers in a Web farm to handle not only the load, but also the site availability.

Required Availability
You usually will work with your business partners to determine what an acceptable level of
application availability is. As the Internet has matured, applications need to be available 24
hours a day, 7 days a week to maintain this type of availability. Performing routine maintenance or security patching can be tough. One recommendation is to schedule a standard
maintenance window. This can be difficult, because Internet applications can be accessed
from anywhere. The standard window helps provide some consistency when changes happen,
however.

Performance Requirement
Having a defined SLA (service level agreement) can help you understand your performance
requirements. Frequent and critical functions need to be identified and tested to ensure they
perform properly. Frequently used transactions, intensive operations, and business-critical
operations need to perform under load and must be available to users.
When testing your application, it is critical that you use data that is as close to real-world
data and user patterns as possible to make sure your system performs optimally. Creating an
application baseline in the real world is a key component to being successful.

Type of Content
The type of content in your application has a significant impact on performance and how
you might design your Web server environment. You can start by looking at the amount of
static content versus dynamic content used on your Web site. The server should be tuned in
a way that accommodates the type of content that is more prevalent on the server. A server
that contains mostly static content, for example, can take advantage of Kernel-mode caching

and output caching.
IIS 7.0 output caching can handle content scenarios that are semi-dynamic, such as an
ASP.NET application that pulls data from a database with content that remains relatively
unchanged. One suggested technique when using output caching is that you can see a huge
performance boost by caching your content for just a few seconds.

Server-Side Tools
IIS 7.0 tries to cache content in many places. Each feature covered in this section determines
what type of content is cached along with how the content will be cached. Each has their own
place but can help with overall server performance.


636

Part IV:

Troubleshooting and Performance

HTTP.sys Cache
Microsoft introduced Kernel-mode caching in IIS 6.0. This feature eliminates the need for
accessing User-mode cache in many cases. The HTTP.sys cache helps increase server performance and reduces disk cost. The content has to be requested a few times before IIS 7.0
considers caching an URL. You can configure frequentHitTimePeriod and frequentHitThreshold
thresholds in the serverRuntime applicationHost.config section. Here are the default serverRuntime settings located in the %windir%\system32\inetsrv\config\schema\IIS_schema.xml
folder. These settings are inherited by default.
<sectionSchema name="system.webServer/serverRuntime">
<attribute name="enabled" type="bool" defaultValue="true" />
<attribute name="appConcurrentRequestLimit" type="uint" defaultValue="5000" />
<attribute name="maxRequestEntityAllowed" type="uint" defaultValue="4294967295" />
"integerRange" validationParameter="0,2147483647" />

<attribute name="alternateHostName" type="string" />
<attribute name="enableNagling" type="bool" defaultValue="false" />
"integerRange" validationParameter="1,2147483647" />
<attribute name="frequentHitTimePeriod" type="timeSpan" defaultValue="00:00:10" />
</sectionSchema>

A request is cached if more than the number of frequentHitThreshold requests for a cacheable
URL arrive within the frequentHitTimePeriod setting. Following is an example of the benefits
you can get by using Kernel-level cache rather than User-mode caching or no caching enabled.
The example shows how to setup Web Capacity Analysis Tool (WCAT) and run the WCAT
controller, WCAT client, and setup Output Caching policies in IIS Manager. There are three
tests using different Output Caching policies.
First, the following steps allow you to configure WCAT to use this example in your environment:
1. Download the IIS6 Resource Kit Tools (go to do a custom
install, and install only WCAT. You’ll use three files to help configure WCAT:


A script file that tells WCAT which URLs to request. Each URL gets a unique
ClassID.



A distribution file that tells WCAT how the requests should be distributed across
the URLs specified in the script file.



A configuration file that configures the parameters of a particular performance
run, for example, the duration of the tests, how many HTTP clients to simulate,

and so on.

2. Create a folder named C:\LoadTest to hold the configuration files.


Chapter 17:

Performance and Tuning

637

3. Create a file called Default.aspx in C:\LoadTest. Type <% = Datetime.Now() %> and save
Default.aspx. This file will be used for load-testing.
4. Create a new file called script.cfg in C:\LoadTest and type the following text:
NEW TRANSACTION
classId = 1
NEW REQUEST HTTP
Verb = "GET"
URL = "http://localhost/Default.aspx"

5. Create a file called distribution.cfg and type the following text inside the file:
1 100

6. Create a file called config.cfg and type the following text inside the file:
Warmuptime 5s
Duration 30s
CooldownTime 5s
NumClientMachines 1
NumClientThreads 20


Next, after you have configured the LoadTest folder and supporting WCAT files, you can
enable the WCAT controller. This is required to perform the tests. Open a command prompt
and type the following syntax:
Cd \LoadTest
"%programfiles%\IIS Resources\WCAT Controller\wcctl"
-c config.cfg -s script.cfg -d distribution.cfg -a localhost

After enabling the WCAT controller, you can run the WCAT client to perform your performance tests. You’ll need to open another command prompt window to start the WCAT client.
"%programfiles%\IIS Resources\WCAT Client\wcclient.exe" localhost

The first test has no Output Cache policy enabled. You can set the Output caching policy in
IIS Manager. Figure 17-4 shows no Output Cache policy enabled.
Per Table 17-10, running a test has results of 575 requests per second, which is an acceptable
number. Let’s see how caching can help improve performance.
The second test enables User-mode policy only. The test using User-mode policy assumes you
are using the file notifications option displayed in Figure 17-5. Figure 17-5 also shows how to
enable a User-mode cache policy.


638

Part IV:

Troubleshooting and Performance

Figure 17-4 No Output Cache policy enabled.

Figure 17-5 User-mode cache policy.



Chapter 17:

Performance and Tuning

639

As you can see in Table 17-10, after running a test with User-mode caching enabled, the results
are 656 requests per second, which is a 13 percent increase over no cache policy enabled.
For the third test, disable the User-mode caching policy and enable Kernel-mode caching. The
Kernel-mode caching test assumes you are using the file notifications option displayed in
Figure 17-6. Figure 17-6 shows how to configure a Kernel-mode caching policy.

Figure 17-6 Kernel-mode caching policy.

After running the test with Kernel-mode caching enabled, the results are 946 requests per
second, which is 60 percent more than if you had had no cache policy. Table 17-10 shows
results from the three performance tests. The results can vary depending on what type of
hardware you are using.
Table 17-10

Output Caching Results

Requests per Second

Cache Level

575

No cache enabled


656

User-mode caching only

946

Kernel-mode caching only

You should be aware of limitations when you are using Kernel-mode caching. Kernel-mode
caching does not support modules and features that run in user mode, for example, if your
application uses basic authentication or Windows Authentication or authorization. The
content will be served, but it won’t be cached. The Kernel-mode caching option supports the
varyByHeaders attribute, but not varyByQuerystring. To see if a request is in the Kernel-mode
cache, type netsh http show cachestate.


640

Part IV:

Troubleshooting and Performance

Note For more information on Http.sys changes in Vista and Windows Server 2008, go to
and search for HTTP.sys within the
article.

User-mode Caching
One important change with User-mode caching is that any content type can be cached, not
just Classic ASP or ASP.NET.


Direct from the Source: Native Output Cache Changes in IIS 7.0
Native output cache is the new user mode response cache added in IIS 7.0. This
module provides functionality that is similar to that provided by the managed output
cache module in ASP.NET. You can control this module’s functionality by editing the
system.webServer/caching section, located in applicationHost.config, or by using
IHttpCachePolicy intrinsic. The IHttpCachePolicy intrinsic is for getting/setting kernelresponse cache or user-mode output cache policy from code. You can set the following
properties in the system.webServer/caching section:


enabled This property tells if output caching is enabled or not for this URL. If
disabled, output cache module won’t do anything in ResolveRequestCache and
UpdateRequestCache stages.

Note that setting the enabled property to true doesn’t ensure response caching.
Some modules must set User-cache policy.


enableKernelCache Controls if kernel caching is enabled for this URL. The output

cache module calls IHttpResponse::DisableKernelCache if this property is set to
false. The output cache module does kernel caching work in the SendResponse
stage if no one called DisableKernelCache in the pipeline. Note that setting enableKernelCache to true doesn’t ensure kernel caching of the response. Some modules
must set the kernel cache policy.


maxCacheSize This is the maximum size of the output cache in megabytes. A

value of 0 means the maximum cache size is calculated automatically by IIS 7.0.
IIS 7.0 uses half of the available physical memory or the available virtual memory—
whichever is less.



maxResponseSize This is the maximum size of the response in bytes that can be

stored in the output cache. A value of 0 means no limit.
Note that although you can set maxCacheSize and maxResponseSize for a URL, the
output cache module uses values set at the root level only.
Per application pool properties in the future will be configurable for each application
pool. If the output cache is enabled, you can control its behavior for different file types


Chapter 17:

Performance and Tuning

641

by adding profiles for different file extensions. These profiles make the output cache
module populate IHttpCachePolicy intrinsic, which enables user/kernel caching of
the response. Properties that you can set in a profile are similar to those available for
system.web/caching/outputCacheSettings profiles. The following properties are
allowed for system.webServer/caching profiles:


extension For example, .asp, .htm. Use * as a wildcard entry. If the profile for a

particular extension is not found, the profile for extension * will be used if it is
present.



Can be DontCache, CacheUntilChange, CacheForTimePeriod, or DisableCache
(only in the server). Output cache module changes IHttpCachePolicy intrinsic,
depending on the value of this property.

policy

Note that DontCache means that intrinsic is not set, but that doesn’t prevent other
modules from setting it and enabling caching. In the server, we have added the
DisableCache option, which ensures that the response is not cached even if some
other module sets the policy telling output cache module to cache the response.


kernelCachePolicy Can be DontCache, CacheUntilChange, CacheForTimePeriod, or
DisableCache (only in the server). As previously mentioned, DontCache doesn’t
prevent other modules from setting kernel cache policy. For static files, the static
file handler sets kernel cache policy, which enables kernel caching of the response.
In the server, the DisableCache option ensures that the response doesn’t get cached
in kernel.



duration The duration property is used only when policy or kernelCachePolicy is

set to CacheForTimePeriod.


location Sets cache-control response header for client caching. The cache-control
response header is set depending on value of this property, as follows:
Any | Downstream: public
ServerAndClient | Client: private

None | Server: no-cache



varyByHeaders Comma-separated list of request headers. Multiple responses to
requests having different values of these headers will be stored in the cache. You
might be returning different responses based on Accept-Language or User-Agent
or Accept-Encoding headers. All the responses will get cached in memory.



varyByQueryString Comma-separated query string variables. Multiple responses

get cached if query string variable values are different in different requests. In the
server, you can set varyByQueryString to *, which makes the output cache module
cache a separate response if any of the query string variable values are different.
Only user mode cache uses location headers and varyBy. These properties have no effect
on kernel caching. So if policy is set to DontCache, these properties are not used. To


642

Part IV:

Troubleshooting and Performance

make output cache module cache multiple responses by an ASP page for 30 minutes,
which returns different responses based on value of query string variable “action” and
also based on request header “User-agent,” the caching section will look like the following,
which is located in the applicationHost.config file:

<caching>

varyByQueryString="action" varyByHeaders="User-Agent"/>
</profiles>
</caching>

Output cache module populates the IHttpCachePolicy intrinsic in the BeginRequest
stage if a matching profile is found. Other modules can still change cache policy for the
current request, which might change User-mode or Kernel-mode caching behavior.
The output cache caches 200 responses to GET requests only. If some module already
flushed the response by the time the request reaches the UpdateRequestCache stage, or
if headers are suppressed, the response is not cached in the output cache module.
The output cache module caches the response only if some other module hasn’t already
cached it, as indicated by IHttpCachePolicy::SetIsCached. In addition, caching happens
only for frequently hit content. The definition of frequently hit content is controlled by
the frequentHitThreshold and frequentHitTimePeriod properties, which are defined in
the system.webServer/serverRuntime section located in applicationHost.config. Default
values define frequently hit content as content that is requested twice in any 10-second
period.
Kanwaljeet Singla
IIS Team Microsoft

Compression
IIS 7.0 provides static and dynamic compression capabilities. Most of the properties are managed under system.webServer\httpCompression, which is located in applicationHost.config.

Direct from the Source: Changes Made to Compression Modules
in IIS 7.0
Static compression is on by default in IIS 7.0. Dynamic compression is still off by
default, and you can turn it on for all content by using the following syntax.

Appcmd set config -section:urlCompression /doDynamicCompression:true

In IIS 6.0, static compression happens on a separate thread. So, upon receiving a
request, the first response is uncompressed, and IIS 6.0 starts a separate thread to
compress the file and keep it in compressed files cache. Requests for compressed


Chapter 17:

Performance and Tuning

643

content reaching IIS 6.0 after the compression is complete receive a compressed
response.
In IIS 7.0, compression happens on the main thread. But to avoid the cost of compression for all requests, compression happens only for frequently requested content. The
definition of frequently requested content is controlled by the properties frequentHitThreshold and frequentHitTimePeriod under the section system.webServer/serverRuntime.
If IIS 7.0 receives more than the threshold number of requests in frequentlyHitTimePeriod
for the same URL, IIS 7.0 will go ahead and compress the file to serve a compressed
response for the same request that made IIS reach threshold.
This compressed response is saved in the compressed files cache, as in IIS 6.0. If the
compressed response was already present in compression cache, frequentHitThreshhold
logic is not applied, because compressed content will be picked from cache and there
will be no additional cost for compressing the content. Hit count is maintained per URL.
So sending the first request with Accept-Encoding: gzip and the second with deflate will
still qualify as frequently hit content, and IIS will go ahead and compress the response.
This will require cachuri.dll to present in the globalModules section, because it is the
module that keeps URL hit count.
The temporary compressed files folder has a nested directory structure in IIS 7.0,
whereas it is flat in IIS 6.0. IIS 7.0 creates folders for each application pool in temporary

compressed files and then creates separate folders for different schemes under each
application pool. Under these scheme folders, IIS 7.0 creates a folder structure similar to
the folder from which the content was picked. So, if iisstart.htm from D:\inetpub\wwwroot
was compressed using gzip, a cache entry will be created in the D:\inetpub\temp\IIS
Temporary Compressed Files\DefaultAppPool\$^_gzip_D^\INETPUB\WWWROOT
folder.
IIS 7.0 will ACL (access control list) the application pool folder with worker process
identity to protect the content from worker processes serving other application
pools. You can still configure the directory from config, but the default is moved from
%windir%\iis temporary compressed files to %SystemDrive%\inetpub\temp\iis
temporary compressed files.
Also with this change, the maxDiskSpaceUsage limit is applied per application pool. So,
if you have a value of 100 MB for HcMaxDiskSpaceUsage in IIS 6.0, then that limit is
applied to all the compressed content in the compressed files cache. In IIS 7.0, this limit
applies to compressed files per application pool. If you have 10 application pools and
have maxDiskSpaceUsage set to 100 MB, total space allocated to compressed files cache
is actually 1 GB.
Because static compression is enabled by default, and compression is happening on the
main thread, on-the-fly compression shuts off or resumes, depending on CPU load. Four


644

Part IV:

Troubleshooting and Performance

properties are added to the system.webServer/httpCompression section to control this
behavior. These are as follow:



staticCompressionDisableCpuUsage Compression is disabled when average CPU

usage over a specified period of time is above this number.


staticCompressionEnableCpuUsage Compression is enabled if average CPU usage
over a specified period of time falls below this number.



dynamicCompressionDisableCpuUsage and dynamicCompressionEnableCpuUsage

Enable or disable dynamic compression depending on the CPU load. IIS 7.0 will
calculate average CPU utilization every 30 seconds.
In IIS 7.0, you can enable/disable compression depending on the content type of the
response. In IIS 6.0, this is possible on an extension basis. In IIS 7.0, you can have just
one entry in the configuration to enable static or dynamic compression for text/HTML
responses. You no longer need to pick up all extensions that return text/HTML
responses. When configuring these MIME types under the httpCompression section, you
can use * as a wildcard. If the response type is text/HTML, look for an entry for text/
HTML. If you find it, use the corresponding enabled value. If text/HTML is not found,
look for text/* or */html. If both are present, pick the one that comes first and use that
enabled property value. If you don’t find them, look for */* and use the corresponding
enabled value. For enabling compression for all content types, add an entry under the
httpCompression section in applicationHost.config as shown here.
<staticTypes>
<add mimeType="*/*" enabled="true" />
</staticTypes>


The maxDiskSpaceUsage entry in IIS 7.0 is configured in megabytes rather than bytes.
We realized that people don’t really want to configure the limit to the byte level, but the
main reason we made this decision was because the limit is UINT, and we didn’t want
users to set it to a value that cannot be stored in UINT. With large disks today, having a
large value won’t be uncommon.
With static compression enabled by default, IIS 7.0 has only cache-compressed
responses in the kernel (HTTP.sys). So if compression is enabled for a file, but the
current request doesn’t contain an Accept-Encoding header (or compression didn’t
happen because it was the first request), IIS 7.0 won’t tell the HTTP.sys to cache it. Only
the compressed response is cached in the kernel for which compression is enabled.
Dynamically compressed responses are not cached in any of the caches (even in
compressed files, as happens in IIS 6.0).
Deflate is removed in the default configuration, but the functionality is still present in
gzip.dll. To add the deflate scheme, add the following in the httpCompression section.
<scheme name="deflate" dll="%Windir%\system32\inetsrv\gzip.dll" />


×