Thursday, June 24, 2010

ASP.NET Pipeline Optimization

There are several ASP.NET default HttpModules which sit in the request
pipeline and intercept each and every request. For example,
SessionStateModule intercepts each request, parses the session cookie
and then loads the proper session in the HttpContext. Not all of these
modules are always necessary. For example, if you aren't using
Membership and Profile provider, you don't need FormsAuthentication
module. If you aren't using Windows Authentication for your users, you
don't need WindowsAuthentication. These modules are just sitting in
the pipeline, executing some unnecessary code for each and every
request.

The default modules are defined in machine.config file (located in the
$WINDOWS$\Microsoft.NET\Framework\$VERSION$\CONFIG directory).

<httpModules>
  <add name="OutputCache" type="System.Web.Caching.OutputCacheModule" /

  <add name="Session"
type="System.Web.SessionState.SessionStateModule" />
  <add name="WindowsAuthentication"
        type="System.Web.Security.WindowsAuthenticationModule" />
  <add name="FormsAuthentication"
        type="System.Web.Security.FormsAuthenticationModule" />
  <add name="PassportAuthentication"
        type="System.Web.Security.PassportAuthenticationModule" />
  <add name="UrlAuthorization"
type="System.Web.Security.UrlAuthorizationModule" />
  <add name="FileAuthorization"
type="System.Web.Security.FileAuthorizationModule" />
  <add name="ErrorHandlerModule"
type="System.Web.Mobile.ErrorHandlerModule,
                             System.Web.Mobile, Version=1.0.5000.0,
                             Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a" />
</httpModules>
You can remove these default modules from your Web application by
adding <remove> nodes in your site's web.config. For example:
<httpModules>
         <!-- Remove unnecessary Http Modules for faster pipeline -->
         <remove name="Session" />
         <remove name="WindowsAuthentication" />
         <remove name="PassportAuthentication" />
         <remove name="AnonymousIdentification" />
         <remove name="UrlAuthorization" />
         <remove name="FileAuthorization" />
</httpModules>
The above configuration is suitable for websites that use database
based Forms Authentication and do not need any Session support. So,
all these modules can safely be removed.
ASP.NET Process Configuration Optimization

ASP.NET Process Model configuration defines some process level
properties like how many number of threads ASP.NET uses, how long it
blocks a thread before timing out, how many requests to keep waiting
for IO works to complete and so on. The default is in many cases too
limiting. Nowadays hardware has become quite cheap and dual core with
gigabyte RAM servers have become a very common choice. So, the process
model configuration can be tweaked to make ASP.NET process consume
more system resources and provide better scalability from each server.

A regular ASP.NET installation will create machine.config with the
following configuration:

<system.web>
    <processModel autoConfig="true" />
You need to tweak this auto configuration and use some specific values
for different attributes in order to customize the way ASP.NET worker
process works. For example:
Collapse
<processModel
   enable="true"
   timeout="Infinite"
   idleTimeout="Infinite"
   shutdownTimeout="00:00:05"
   requestLimit="Infinite"
   requestQueueLimit="5000"
   restartQueueLimit="10"
   memoryLimit="60"
   webGarden="false"
   cpuMask="0xffffffff"
   userName="machine"
   password="AutoGenerate"
   logLevel="Errors"
   clientConnectedCheck="00:00:05"
   comAuthenticationLevel="Connect"
   comImpersonationLevel="Impersonate"
   responseDeadlockInterval="00:03:00"
   responseRestartDeadlockInterval="00:03:00"
   autoConfig="false"
   maxWorkerThreads="100"
   maxIoThreads="100"
   minWorkerThreads="40"
   minIoThreads="30"
   serverErrorMessageFile=""
   pingFrequency="Infinite"
   pingTimeout="Infinite"
   asyncOption="20"
   maxAppDomains="2000"
/>

Here all the values are default values except for the following ones:

    * maxWorkerThreads - This is default to 20 per process. On a dual
core computer, there'll be 40 threads allocated for ASP.NET. This
means at a time ASP.NET can process 40 requests in parallel on a dual
core server. I have increased it to 100 in order to give ASP.NET more
threads per process. If you have an application which is not that CPU
intensive and can easily take in more requests per second, then you
can increase this value. Especially if your Web application uses a lot
of Web service calls or downloads/uploads a lot of data which does not
put pressure on the CPU. When ASP.NET runs out of worker threads, it
stops processing more requests that come in. Requests get into a queue
and keeps waiting until a worker thread is freed. This generally
happens when site starts receiving much more hits than you originally
planned. In that case, if you have CPU to spare, increase the worker
threads count per process.
    * maxIOThreads - This is default to 20 per process. On a dual core
computer, there'll be 40 threads allocated for ASP.NET for I/O
operations. This means at a time ASP.NET can process 40 I/O requests
in parallel on a dual core server. I/O requests can be file read/
write, database operations, web service calls, HTTP requests generated
from within the Web application and so on. So, you can set this to 100
if your server has enough system resource to do more of these I/O
requests. Especially when your Web application downloads/uploads data,
calls many external webservices in parallel.
    * minWorkerThreads - When a number of free ASP.NET worker threads
fall below this number, ASP.NET starts putting incoming requests into
a queue. So, you can set this value to a low number in order to
increase the number of concurrent requests. However, do not set this
to a very low number because Web application code might need to do
some background processing and parallel processing for which it will
need some free worker threads.
    * minIOThreads - Same as minWorkerThreads but this is for the I/O
threads. However, you can set this to a lower value than
minWorkerThreads because there's no issue of parallel processing in
case of I/O threads.
    * memoryLimit - Specifies the maximum allowed memory size, as a
percentage of total system memory, that the worker process can consume
before ASP.NET launches a new process and reassigns existing requests.
If you have only your Web application running in a dedicated box and
there's no other process that needs RAM, you can set a high value like
80. However, if you have a leaky application that continuously leaks
memory, then it's better to set it to a lower value so that the leaky
process is recycled pretty soon before it becomes a memory hog and
thus keep your site healthy. Especially when you are using COM
components and leaking memory. However, this is a temporary solution,
you of course need to fix the leak.

0 comments:

Post a Comment