Unlike classic ASP which runs in the same memory space as the Internet Information Server (IIS), the new ASP.NET runs as a process of its own. This gives us more flexibility, stability and power, especially when combined with the <machine.config> file. Using standard XML notation inside this file, we can attribute our process to do things that will make the Webmaster’s job a lot easier. We’ll take a close look at the ASP.NET process and the attributes available for us to play with.
The new process: aspnet_wp.exe
With classic ASP it was almost a given that memory leaks and bad software development or hardware configurations would eventually cause the Internet Information Server (IIS) to hang and finally crash. Webmasters would get calls in the middle of the night to deal with a non-servicing web server, or they would proactively reboot the server every so often to release the memory. That’s because the classic ASP process runs in the same memory space as IIS does. Things have changed though with .NET. There is now a new process that ASP.NET runs under: aspnet_wp.exe. This process can be configured through the <machine.config> file, and the settings will affect the whole server. This is a webmaster’s dream come true, as you can now configure settings through this XML file, like recycling the process after some amount of time, or requests, or memory threshold, or create as many processes as you want depending on how many chips you have on your motherboard. We’ll talk about the different settings and how to best use them, so that we can have a faster web server, with more up time.
This new process does not depend on IIS at all. It simply uses IIS to receive requests and then to send out the responses. Therefore, the ASP.NET process can be created or destroyed without affecting IIS at all. In fact, when you first start your computer the process is not created until after some ASP page is requested, even if the IIS starts automatically on reboot.
If you open your Task Manager you will be able to see the process, along with the regular information that comes with a listing here, like the Process ID number, the CPU usage and time, and total memory being used by it.
On a typical installation, the <machine.config> file is located at C:\WINNT\Microsoft.NET\Framework\v1.0.3705\CONFIG\machine.config. The way to configure the ASP.NET process is through the processModel tag in this file. The tag looks like this with its default settings:
<br /><?xml version="1.0" encoding="UTF-8"?><br /><configuration><br /> <system.web><br /> <processModel<br /> enable="true"<br /> timeout="Infinite"<br /> idleTimeout="Infinite"<br /> shutDownTimeout="00:00:05"<br /> requestLimit="Infinite"<br /> requestQueueLimit="5000"<br /> restartQueueLimit="10"<br /> memoryLimit="40"<br /> webGarden="false"<br /> cpuMask="0xffffffff"<br /> userName="System"<br /> password="autogenerate"<br /> logLevel="Errors"<br /> clientConnectedCheck="00:00:05"<br /> comAuthenticationLevel="Default"<br /> comImpersonationLevel="Default"<br /> responseDeadlockInterval="00:03:00"<br /> responseRestartDeadlockInterval="00:09:00"<br /> maxWorkerThreads="25"<br /> maxIoThreads="25"<br /> serverErrorMessageFile=""<br /> pingFrequency="00:00:30"<br /> pingTimeout="00:00:05"<br /> /><br /> </system.web><br /></configuration><br />
The complete documentation on the processModel tag can be found at Microsoft. You can take a close look at it on their site, but here is a summary of the attributes available within this tag:
|1.||enable||true | false||true|
|2.||timeout||Infinite | HH:MM:SS||Infinite|
|3.||idleTimeout||Infinite | HH:MM:SS||Infinite|
|5.||requestLimit||Infinite | int||Infinite|
|9.||webGarden||true | false||false|
|11.||userName||user | System | Machine||System|
|12.||password||autogenerate | password||autogenerate|
|13.||logLevel||All | None | Errors||Errors|
|14.||clientConnectedCheck||HH:MM:SS | Infinite||00:00:05|
|15.||comAuthenticationLevel||Default | None | Connect | Call | Pkt | PktIntegrity | PktPrivacy||Default|
|16.||comImpersonationLevel||Default | Anonymous | Identify | Impersonate | Delegate||Default|
|17.||responseDeadlockInterval||Infinite | HH:MM:SS||00:03:00|
|18.||responseRestartDeadlockInterval||Infinite | HH:MM:SS||00:09:00|
Enabling the ASP.NET process
<processModel enable="true" ...
The enable attribute is the most important one, because it decides if the ASP.NET process runs on its own or under IIS. The default is true, meaning that it runs on its own. This is the best option, as it allows us to reap the benefits of a separate configurable process. If it is set to false, then the rest of the settings here do not matter as they are ignored. Keep in mind that if you change this option either way, you will have to stop and restart IIS for it to take effect.
Recycling the process
There are 5 ways to recycle the ASP.NET process.
<processModel timeout="168:00:00" ...
The first involves the timeout attribute, which simply creates a new process after the amount of time specified as a value. For example, the above setting will automatically start a new process after 168 hours, or one week. The time clock starts right after the first request is made, because the process is actually created when the first request to the ASP.NET engine is made. This setting can be extremely useful in scenarios where there is a slow leak in memory and performance, and periodic IIS resets are needed.
<processModel requestLimit="10000" ...
A second way is to use the requestLimit attribute and give it an Integer value. A value of 10,000 like above, will start a new process after 10,000 requests have been made. This can be useful if our web server’s performance degrades after a set number of requests, instead of simply some amount of time past.
<processModel memoryLimit="50" ...
A third way is to let your system watch how much memory the process is consuming. In the above example, the attribute memoryLimit is set to 50, which means that if the process uses more than 50% of total system memory then the process is killed , a new one is created and all existing requests are reassigned to the new one. This is extemely helpful is cases where a memory leak is present, no matter how slow the leak is.
<processModel responseDeadlockInterval="00:03:00" ...
A fourth way of doing this is by using the responseDeadlockInterval attribute. The time setting above of 3 minutes will restart the process if two things happen: there are requests in the queue, but there have not been any responses for the last 3 minutes.
<processModel pingFrequency="00:00:30" pingTimeout="00:00:05" ...
The fifth and last way of recycling the process, is to use the pingFrequency and pingTimeout attributes in conjunction. The system pings the ASP.NET process at the pingFrequency interval, and restarts it if there is no response within the pingTimeout time interval.
Shutting down the process
There are 2 ways of shutting down the ASP.NET process.
<processModel idleTimeout="00:30:00" ...
The first way of doing it is by using the idleTimeout attribute. If the server has not served any requests for the amount of time that we specify here, then it automatically shuts down the process. If a new one comes in after that, a new process is started automatically. The example shown will shut down the existing process after 30 minutes of inactivity. This might be useful if you have long times of inactivity, for example during the early hours of the morning, and you want to use the system resources for other tasks during those times, such as database stored procedures, or email chunking.
<processModel shutDownTimeout="00:00:05" ...
The second way is by using the shutDownTimeout attribute. This is used as a last resort, when the ASP.NET process tries to gracefully shut down and it fails. In that case, after the time that we set here has passed, a low level kill command is called on the process to make sure it is killed. This is useful in those cases where the process has crashed and is not responding anymore. The setting above will force a kill after 5 seconds.
Reducing the queue: checking if the client is still connected
<processModel clientConnectedCheck="00:00:05" ...
Users can get impatient. If our web server is slow to respond to their requests, they might click on the same link many times. Even if only the last request is finally returned to them, the server still processes all the previous ones. That’s wasted server resources. Even worse, the user might abandon their session with our server, but the server still has a queue from that user. One way we can help our server, is to have it check requests in the queue and throw away the ones which the client is no longer connected with them. In the example above, the server will check each request every 5 seconds after it has entered the queue, to see if the user who made it is still connected. If the user is not, the server throws away that request.
We have seen how ASP.NET now works as a separate worker process, and the benefits that can give us. We’ve also seen how to best use the process by attributing it through the <machine.config> file. I encourage you to take a closer look at the rest of the other attributes not mentioned in detail here, as they might be beneficial to you depending on your circumstances.