Process Model





Process Model

One of the most interesting configuration elements available is the processModel element. It is different from all the other configuration elements in several ways.

  • It can be placed only in the systemwide machine.config file.

  • Changes to this element do not take effect until the worker process is restarted.

  • The configuration settings defined in this element are read in by the unmanaged aspnet_isapi.dll ISAPI extension DLL instead of the managed mechanism used by the other settings.

This element controls various aspects of the ASP.NET worker process (aspnet_wp.exe), including its lifetime, how many instances are created at a time, what security identity it runs under, and how large a thread pool it should use to service requests. Figure shows the attributes available with this element.

Attributes of the processModel Element

Attribute

Values

Default

Description

Enable

true | false

true

Whether ASP.NET is hosted in an external worker process (true) or directly in inetinfo.exe (false)

timeout

Infinite | HH:MM:SS

Infinite

Total life of a process—process bounced after timeout

idleTimeout

Infinite | HH:MM:SS

Infinite

Total idle life of a process—process bounced when reached

shutdownTimeout

Infinite | HH:MM:SS

0:00:05

Time given to process to shut down before being killed

requestLimit

Infinite | number

Infinite

Total number of requests to serve before bouncing process

requestQueueLimit

Infinite | number

5000

Number of queued requests allowed before bouncing process

restartQueueLimit

Infinite | number

10

Number of requests kept in queue while process is restarting

memoryLimit

Number

60

Percentage of physical memory process is allowed to use before bouncing process

webGarden

true | false

false

Whether process should be affinitized with a particular CPU (for multi-CPU machines)

cpuMask

Bitmask

0xffffffff

Controls number of CPUs available for ASP.NET worker processes (webGarden must be true)

userName

SYSTEM | MACHINE | username

MACHINE

Windows identity to run the worker process in (MACHINE uses low-privileged ASPNET account)

Password

AutoGenerate | password

AutoGenerate

Password for username

logLevel

All | None | Errors

Errors

Event types logged to event log

clientConnectedCheck

HH:MM:SS

0:00:05

Time a request is left in the queue before a client-connected check is performed

comAuthenticationLevel

Default | None | Connect | Call | Pkt | PktIntegrity | PktPrivacy

Connect

Level of authentication for DCOM security

comImpersonationLevel

Default | Anonymous | Identify | Impersonate | Delegate

Impersonate

Authentication level for COM security

responseRestartDeadlockInterval

Infinite | HH:MM:SS

00:09:00

Time to wait between restarting worker process because of responseRestartDeadlockInterval

responseDeadlockInterval

Infinite | HH:MM:SS

00:03:00

For deadlock detection, timeout for responses when there are queued requests

maxWorkerThreads

Number

25

Maximum number of I/O threads per CPU in the thread pool

maxIoThreads

Number

25

Maximum number of I/O threads per CPU in the thread pool

serverErrorMessageFile

File name

""

Customization for "Server Unavailable" message

Most of the attributes shown in Figure affect the lifetime of the worker process. At first, it may seem illogical to have such precise control over how long the worker process lives. After all, why not just have it live forever, and be done with it? The sheer number of ways you can request that the worker process self-terminate and restart indicates that the ASP.NET team recognized that sometimes things go wrong—resources leak, deadlocks occur, memory limits are reached, and so on. Some of these things may be beyond your control, and the best choice in those cases is often to simply terminate the worker process and restart it. In many cases, this will have little impact on the servicing of clients because of the disconnected nature of the HTTP protocol. The primary drawbacks of a process bounce are the loss of in-process session state, application state, and entries in the data cache.

This practice of bouncing the process servicing requests is not as uncommon as you may think—many high-volume Web servers today make it a regular practice to bounce the server process periodically. The ASP.NET team recognized this in the beginning and built in a number of safeguards to ensure that the process bounce would occur smoothly and under the right conditions. This was so important in their list of goals that internally they liked to use the slogan "ASP.NET—Designed for Failure," which of course did not go over very well with the marketing people and was therefore left as an internal slogan only.

As mentioned, the conditions under which you can elect to have the server process bounce are numerous. By default, only two conditions cause the process to bounce: 1) if the total memory utilization of the process exceeds 60% of the physical memory on the machine (specified by the memoryLimit attribute) and 2) if more than 5,000 requests are queued. Both of these conditions are abnormal and should not be encountered under normal operating conditions; but if they do occur, it is likely that something is wrong and that bouncing the process may very well cure it. You can add conditions that will bounce the process, including an explicit timeout (timeout), an idle timeout (accumulated time spent idle—idleTimeout), and an upper bound on the number of requests serviced by a worker process (requestLimit).

You also have some amount of control over CPU utilization through the processModel element. For example, if your server has multiple CPUs, you can enable the webGarden attribute, to request that a dedicated worker process run on each CPU. You can also restrict which CPUs are used to host worker processes if you don't want to use them all, through the cpuMask attribute. For example, if you have a 4 CPU machine, but you want to use only processors 0, 1, and 2 to host ASP.NET worker processes, you specify webGarden as true and cpuMask as 0x00000007, which corresponds to the binary bitmask 0...0111, as shown in Listing 3-5.

-5 Specifying Multiple Worker Processes on a Multi-CPU machine
<processModel enable="true"
              timeout="Infinite"
                idleTimeout="Infinite"
                shutdownTimeout="0:00:05"
                requestLimit="Infinite"
                requestQueueLimit="5000"
                restartQueueLimit="10"
                memoryLimit="60"
                webGarden="true"
                cpuMask="0x00000007"
                userName="machine"
                password="AutoGenerate"
                logLevel="Errors"
                clientConnectedCheck="0:00:05"
                comAuthenticationLevel="Connect"
                comImpersonationLevel="Impersonate"
                responseRestartDeadlockInterval="00:09:00"
                responseDeadlockInterval="00:03:00"
                maxWorkerThreads="25"
                maxIoThreads="25" />

Be aware that if you enable the webGarden attribute on a multi-CPU machine, session state, application state, and the global data cache are not shared between worker processes. Chapter 10 discusses ways of dealing with state sharing between processes.

The other way you have control over CPU utilization is through the number of worker and I/O threads used within the worker process to service requests. The distinction between the two types of threads is that I/O threads are bound to I/O completion ports and are used to access a particular I/O object (such as a stream or a pipe), and worker threads are traditional unrestricted threads. Currently, ASP.NET processes requests primarily on I/O threads[8] because requests are initiated through an asynchronous write to a named pipe from IIS, the details of which we discuss in Chapter 4. These threads are drawn from the process-wide thread pool maintained for every .NET application. By default, these pools are initialized with 25 threads per CPU on the machine, which is generally a sufficient number of threads to keep the CPU utilization high. If for some reason the requests to your application end up doing a lot of waiting (for external resources, perhaps), limiting the process to 25 threads may be too constraining, in which case you could increase the number to anything less than 100. Be advised, however, that it is generally uncommon for this to be the case, and leaving the thread pools at their default of 25 should almost always be adequate.

[8] This changes in Windows Server 2003 with IIS 6.0. Because ASP.NET is directly integrated into IIS 6.0, there is no longer any need to dispatch requests to ASP.NET over named pipes, so requests are processed on worker threads instead of I/O threads.

The remaining attributes in the processModel element are related to security and are discussed further in Chapter 11.

1 Accessing Process Information

In addition to controlling various aspects of the process model, you can access information about the worker processes on a machine programmatically. The ProcessModelInfo class provides a pair of static methods to retrieve information about the current worker process and past worker processes that may have terminated recently. Each of these functions returns a reference to a ProcessInfo class populated with information about the worker process, including its age, the maximum amount of memory it has used, its process ID, how many requests it has serviced, when it was started, its status, and why it was shut down (if it was). Listing 3-6 shows the ProcessModelInfo and ProcessInfo classes. Figure shows sample output from calling ProcessModelInfo.GetHistory(10).

-6 ProcessModelInfo and ProcessInfo Classes
Public Class ProcessModelInfo
  Public Shared Function GetCurrentProcessInfo() _
                As ProcessInfo
  Public Shared Function GetHistory(num As Integer) _
                As ProcessInfo()
End Class

Public Class ProcessInfo
  Public ReadOnly Property Age As TimeSpan
  Public ReadOnly Property PeakMemoryUsed As Integer
  Public ReadOnly Property ProcessID As Integer
  Public ReadOnly Property RequestCount As Integer
  Public ReadOnly Property ShutdownReason _
                  As ProcessShutdownReason
  Public ReadOnly Property StartTime As DateTime
  Public ReadOnly Property Status As ProcessStatus
End Class
Sample ProcessModelInfo Output

graphics/03fig03.gif

2 IIS 6.0 Process Model Changes

With the release of IIS 6.0 in Windows Server 2003, the process model changes dramatically. To begin with, the processModel element in machine.config is ignored because it is replaced with equivalent settings in the IIS metabase, which is now stored in XML format in the metabase.xml file. ASP.NET is no longer hosted in aspnet_wp.exe but in one or more instances of w3wp.exe. Even more significantly, you are no longer constrained to just one worker process per CPU on a particular machine. Instead, you can configure what are called application pools, which contain collections of virtual directories that all share the same worker process. The properties of each application pool control how that particular worker process behaves, including even more settings than are available in the processModel element. Some of the new process model settings include the ability to set specific times of the day when the process should recycle; separate memory limits for virtual memory and actual used memory; CPU usage monitoring with the ability to recycle the process if utilization is too high; rapid-fail protection by disabling the application pool if it encounters a fixed number of failures within a particular time limit; and start-up and shutdown time limits.

The other significant change is that HTTP requests are now handled in kernel mode through the http.sys service. This service listens for HTTP requests and places them in the appropriate application queue. This means that inetinfo.exe is no longer the front end for HTTP requests, so the advantage of servicing requests in-process is gone. All requests are routed through the kernel-mode HTTP listener and dispatched to some process for servicing. Moving HTTP request queuing into the kernel means that faults in user-mode processes cannot adversely affect the HTTP listener, and even if a crash occurs in the user-mode request processing infrastructure, the kernel service will continue to accept and queue up requests until either the queues completely fill up or the service is shut down.

If you are moving an ASP.NET application to IIS 6.0, but you still want to use the process model and configuration settings of IIS 5.0, you can set a backward-compatibility flag in IIS 6.0 that causes it to run in IIS 5.0 isolation mode. This must be applied at the machine level, because it affects how all requests are processed on a given machine.


     Python   SQL   Java   php   Perl 
     game development   web development   internet   *nix   graphics   hardware 
     telecommunications   C++ 
     Flash   Active Directory   Windows