IIS 7.0 : Managing Application Pools (part 3) – Advanced Application Pool Configuration, Monitoring Application Pool Recycling Events

Advanced Application Pool Configuration

Though IIS 7.0 application pool configuration is similar to IIS 6.0, the configuration UI has been reorganized together with the new IIS Manager. All settings are now visible and configurable in the UI. Most configuration settings are the same as in IIS 6.0, such as application recycle options and rapid failed protection. This section discusses some key configurations that are new to IIS 7.0.

Enabling User Profile Loading

A typical Web application includes both reading and writing data in the application logic, and typically Web applications require read and write access to the Windows temporary directory, %Temp%. Consider, for example, an ASP application uses a Microsoft Access database. In IIS 6.0, by design, the operating system grants read and write access to the temporary directory to all users, including the worker processes account, regardless of the process identity. Although this default behavior in IIS 6.0 enables Web applications to run perfectly without any issues, it has security implications, because all worker processes are sharing the same temporary directory.

To better address the security risk, IIS 7.0 grants you the ability to load the user account profile during worker process startup. This provides a separate environment with different temporary folders for each process identity. However, by default, the temporary directory of the process identity is only accessible by the process account. For a Web application that requires access to a temporary directory, you need to grant access to those related user accounts. By default, user profile loading is disabled in IIS 7.0, so it behaves like IIS 6.0. When user profile is enabled, it may break some applications such as those that use the Microsoft Access databases. This is because the default application pool identity, NetworkService, does not have access to the Temp directory that the Access database engine requires.

Note

By design, user profile loading is enabled in Windows Vista, but the setting is disabled in Windows Server 2008 and Windows Vista Service Pack 1 (SP1). It is also important to remember that user profile loading is configurable per application pool.

After installing Windows Vista SP1 and reinstalling IIS 7.0, the loadUserProfile setting is disabled by default.

To use IIS Manager to enable user profiles in IIS 7.0, expand the IIS computer node in the Connections pane and navigate to the Application Pools node. In the Application Pools display pane, select the application pool for which you want to change user profile loading and then click Advanced Settings in the Actions pane. In the Process Model section of the Advanced Settings dialog box, click the Load User Profile property and select True in the drop-down list, as shown in Figure 4.

Figure 4. Enabling user profiles by using IIS Manager.

After you have enabled the load user profile setting, you need to grant relevant user accounts access to the account profile’s temporary directory, because by default, only the process identity has access to its profile directories. By default, the built-in accounts profile folder is stored in the %systemRoot%\ServiceProfiles\ directory. For the default worker process identity (NetworkService), the folder is located under %systemRoot%\ServiceProfiles\NetworkService\AppData\Local\Temp. For more information on granting access permissions for the temporary directory, see the Microsoft Knowledge Base article at http://support.microsoft.com/kb/926939/.

Use the following Appcmd syntax and the parameters listed in Table 5 to enable user profile loading for an application pool.

appcmd set apppool "apppool name"
/processModel.loadUserProfile:Boolean

Table 5. Syntax for Appcmd to Enable User Profile Loading

Parameter Description
apppool name The string represents the application pool name.
processModel.loadUserProfile Specifies if the worker process should load the user profile during startup.

The following code turns on user profile loading for the DefaulAppPool application pool.

appcmd set apppool /apppool.name:"DefaultAppPool"
/processModel.loadUserProfile:true

Upon successfully executing the command syntax, you will see the output shown in the following code. After enabling the user profile, do not forget to grant relevant account access, as discussed previously.

APPPOOL object "DefaultAppPool" changed

Like the other changes to an application pool, the user profile setting is defined together with the application pool definition in the <applicationPools> section of the applicationHost.config file. The attribute value loadUserProfile is declared with the processModel element. The following shows the <applicationPools> configuration for the DefaulAppPool user profile loading setting.

<applicationPools>
<add name="DefaultAppPool">
         <processModel loadUserProfile="true" />
    </add>
    <add name="Classic .NET AppPool" managedPipelineMode="Classic" />
    ...
    <applicationPoolDefaults>
        <processModel identityType="NetworkService" />
    </applicationPoolDefaults>
</applicationPools>

Monitoring Application Pool Recycling Events

Effective monitoring of application pool recycling events allows you to have a good understanding of the application pool’s health status. It also gives you a detailed description of the event and further helps you when troubleshooting application availability. In IIS 6.0, similar event loggings are configurable via a command line tool only, and not all application pool events are captured. For example, the application pool idle shutdown event is not captured. For more information about IIS 6.0 application pool recycling events, see the Microsoft Knowledge Base article at http://support.microsoft.com/kb/332088/. In IIS 7.0, recycling event monitoring is now configurable using IIS Manager, including all recycling events for application pools. Table 6 shows the event log ID and details of each recycling event.

Table 6. Application Pool Recycling Events

Event/Attribute Value Description Event ID
Application Pool Configuration Changed (ConfigChange) The worker processes serving application pool ‘%1’ are being recycled due to one or more configuration changes in the application pool properties. These changes necessitate a restart of the processes. System

5080

ISAPI Reported Unhealthy (IsapiUnhealthy) ISAPI ‘%1’ reported itself as unhealthy for the following reason: ‘%2’.

ISAPI ‘%1’ reported itself as unhealthy. No reason was given by the ISAPI.

Application

2262

Application

2263

Module Reported Unhealthy (ReportUnhealthy) An application has reported being unhealthy. The worker process will now request a recycle. Reason given: %1. The data is the error. Application

2299

Manual Recycle (OnDemand) An administrator has requested a recycle of all worker processes in application pool ‘%1’. System

5079

Private Memory Limit Exceeded (PrivateMemory) A worker process with process ID of ‘%1’ serving application pool ‘%2’ has requested a recycle because it reached its private bytes memory limit. System

5117

Regular Time Interval (Time) A worker process with process ID of ‘%1’ serving application pool ‘%2’ has requested a recycle because it reached its allowed processing time limit. System

5074

Request Limit Exceeded (Requests) A worker process with process ID of ‘%1’ serving application pool ‘%2’ has requested a recycle because it reached its allowed request limit. System

5075

Specific Time (Schedule) A worker process with process ID of ‘%1’ serving application pool ‘%2’ has requested a recycle because it reached its scheduled recycle time. System

5076

Virtual Memory Limit Exceeded (Memory) A worker process with process ID of ‘%1’ serving application pool ‘%2’ has requested a recycle because it reached its virtual memory limit. System

5077

In the case of worker process idle shutdown (default is 20 minutes), WAS writes the following event log.

Event ID: 5186
Detail: A worker process with process id of '%1' serving application
pool '%2' was shutdown due to inactivity. Application Pool
timeout configuration was set to %3 minutes. A new worker process will be
started when needed.

By default, the following recycling events are turned on:

  • Private Memory Limit Exceeded (default value 0 [kb], no limit)
  • Regular Time Interval (default value 1740 [minutes], 29 hours)
  • Virtual Memory Limit Exceeded (default value 0 [kb], no limit)

To enable more application pool recycling events by using IIS Manager, expand the IIS computer node in the Connections pane and then navigate to the Application Pools node. In the Application Pools display pane, select the application pool for which you want to enable recycling events. Then click Advanced Settings in the Actions pane. In the Advanced Settings dialog box, scroll down to the Recycling section, expand the Generate Recycle Event Log Entry node, click the appropriate event log entry option, and select True in the drop-down list to enable logging for that event .

Note

You need to configure all relevant properties to capture the recycling event log. For example, if you enable the Request Limit Exceeded option, you must specify a limit for the Request Limit property. Otherwise, the default value of 0 indicates there is no request limit configured for the application pool, and an event log will not be generated, because there is no limit to check against.

Use the following Appcmd syntax and the parameters in Table 7 to configure logging for various application pool recycling events.

appcmd set apppool "ApppoolName"
/recycling.logEventOnRecycle:flags

Table 7. Syntax for Appcmd to Configure Logging for Recycling Events

Parameter Description
ApppoolName The string represents the application pool name.
recycling.logEventOnRecyle Specifies the recycling event options. The flags include Time, Requests, Schedule, Memory, IsapiUnhealthy, OnDemand, ConfigChange, and PrivateMemory.

Figure 5. Enabling application recycling events by using IIS Manager.

The following syntax enables all recycling event logs for the DefaulAppPool application pool.

appcmd set apppool "DefaultAppPool"
/recycling.logEventOnRecycle:"Time, Requests, Schedule, Memory,
IsapiUnhealthy, OnDemand, ConfigChange, PrivateMemory"

To disable all event logging, simply remove all attribute flag values. For example, the following command disables all recycling events for the Test application pool.

appcmd set apppool "Test" /recycling.logEventOnRecycle:""

As noted previously, it is important that you configure relevant settings when you are enabling application pool recycling event logging. For example, you must limit the number of requests for a particular application pool so that you can generate an event log when worker processes for the application pool recycle after hitting the request limit. The following syntax sets the request limit to 500 and enables Request Limit Exceeded event logging for the Test application pool.

appcmd set apppool "Test"
/recycling.periodicRestart.requests:500
/recycling.logEventOnRecycle:"Requests"

Notice the /recycling.periodicRestart parameter. All application pool recycling options are configured under this element. It includes the following nodes for setting the application pool recycling options: .memory for virtual memory limits, .privateMemory for private memory limits, .schedule for regular time intervals, and .time for specific time intervals.

Similar to the other changes in an application pool, application pool recycling event loggings are defined with the application pool definition in the <applicationPools> section in the applicationHost.config file. The event log entry type is declared in the <recycling> element, and limits or restrictions for each setting are defined in the <periodicRestart> subelement. The following shows the <applicationPools> configuration that results from the previous example.

<applicationPools>
<add name="DefaultAppPool">
        <recycling logEventOnRecycle="Requests">
            <periodicRestart request="500" />
        </recycling>
    </add>
    <add name="Classic .NET AppPool" managedPipelineMode="Classic" />
    <applicationPoolDefaults>
        <processModel identityType="NetworkService" />
    </applicationPoolDefaults>
</applicationPools>