Orcas SP1 Improvement: Asynchronous WCF HTTP Module/Handler for IIS7 for Better Server Scalability


Introduction


As mentioned in my last blog entry, for IIS-hosted WCF services, WCF holds the worker thread coming from ASP.NET until the whole request is completed to avoid a Denial of Service (DOS) attack. I also mentioned that on Windows 2008 Server, IIS7 has introduced the following registry setting to provide request throttling for all incoming requests:


[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ASP.NET\2.0.50727.0]


“MaxConcurrentRequestsPerCpu”=dword:0000000c


Based on this, in Orcas SP1 (.NET 3.5 SP1), WCF has implemented the asynchronous HTTP Module/Handler to allow better server scalability for high latency requests.


Asynchronous WCF HTTP Module/Handler


Besides the existing synchronous WCF HTTP Module/Handler types, WCF introduced the asynchronous versions. Together, WCF has the following four types implemented:


·        Synchronous Module:


System.ServiceModel.Activation.HttpModule, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089


·        Asynchronous Module (new):


System.ServiceModel.Activation.ServiceHttpModule, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089


·        Synchronous Handler:


System.ServiceModel.Activation.HttpHandler, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089


·        Asynchronous Handler (new):


System.ServiceModel.Activation.ServiceHttpHandlerFactory, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089


Asynchronous HTTP Module


The new type ServiceHttpModule implements the System.Web.IHttpModule and it registers the async event HttpApplication.AddOnPostAuthenticateRequestAsync with a pair of async handlers:


static public IAsyncResult BeginProcessRequest(object sender, EventArgs e, AsyncCallback cb, object extraData)


static public void EndProcessRequest(IAsyncResult ar)


When a request comes in, WCF does some validation and returns from BeginProcessRequest immediately after passing the request up to internal processing logic. In this way, the worker process is immediately released.


If the service operation is asynchronous and it is waiting for slow I/O operations, the whole stack does not hold any thread. The only performance concern would be the memory usage to hold objects used to process the request. This allows many concurrent requests to be served by WCF without using a lot of threads and thus greatly improves the scalability of the service. This is very helpful when completing each request takes significant amount of time and many clients are served. In some private testing, WCF can easily support more than 10K concurrent slow requests, which is not possible with the synchronous HttpModule.


Asynchronous HTTP Handler Factory


You might have already noticed that WCF implements the Handler Factory instead of the asynchronous Handler directly. This allows more flexibility in the future to support different types of  HTTP Handlers. The ServiceHttpHandlerFactory creates a stateless asynchronous HTTP handler of the following type which implements System.Web.IHttpAsyncHandler:


System.ServiceModel.Activation.ServiceHttpHandler


It implements the pair of asynchronous request handlers:


public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)


public void EndProcessRequest(IAsyncResult result)


Default Installation – Synchronous Version


Though the asynchronous version of HTTP Module/Handler is added in this release, the default installation is still the synchronous version. Why is this?


First of all, you should not use asynchronous version of HTTP Module/Handler on Windows 2003 Server (with IIS6) without knowing the risk. If you have many clients, the service would be easily DOS attacked by too much memory usage due to huge amount of pending requests queued up in WCF transport layer without the throttling inside IIS/ASP.NET.


Because of the limitation on IIS6, WCF did not change the setup to switch to purely asynchronous due to the ramifications between IIS6 and IIS7 for this quick release. This means that in order to use the asynchronous version, you have to perform some manual registration.


Don’t worry, I have provided a private tool to do this registration for you.


WCF Module/Handler Registration Tool


You can find the simple tool called WcfAsyncWebUtil.exe attached in this blog. Here is the usage:


Usage: WcfAsyncWebUtil <options>


Options:


  /is


    Install WCF Synchronous HTTP module and handler into IIS7 configuration


    in Integrated Mode.


  /ia


    Install WCF Asynchronous HTTP module and handler into IIS7 configuration


    in Integrated Mode.


  /l


    List WCF HTTP module and handler registered into IIS7 configuration in


    Integrated Mode.


  /t [ <throttle> ]


    Configure the throttling registry MaxConcurrentRequestsPerCpu for the ASP.NET


    integrated pipeline to the value <throttle>. Default is 100. This argument is


used together with /ia only


For example, if you want to register asynchronous HTTP Module/Handler with the ASP.NET throttling to be 1000, you can run the following command:


WcfAsyncWebUtil.exe /ia /t 1000


To list the installed WCF HTTP Module/Handler, you can run:


WcfAsyncWebUtil.exe /l


 


 

WcfAsyncWebUtil.zip

Comments (11)

  1. We just announced the release of Service Pack 1 for VS 2008 and .NET FX 3.5 . A major push for this release

  2. We just announced the release of Service Pack 1 for VS 2008 and .NET FX 3.5 . A major push for this release

  3. Couldn’t get better than this. Wenlong has pretty much detailed out to the core on understanding WCF

  4. WCF Development Improvements .NET 3.5 SP1 and VS 2008 SP1 include several enhancements for WCF development.

  5. To make your configuration tool work on 2k8 and IIS7,  I also had to add a 2k8 "feature."  Specifically:

    .NET Framework 3.0 Feautures ->

    WCF Activation ->

    HTTP Activation

    After that, your config tool worked.

    Still, your comments seem to suggest that the asynchronous handler can also be installed and configured on 2K3 and IIS 6, even if it is not adviseable. All the same, I’d like to know how that configuration could be accomplished on that platform.

  6. WCF is a framework that is asynchronous inside out. Internally, asynchronous patterns are used to achieve

  7. WCF is a framework that is asynchronous inside out. Internally, asynchronous patterns are used to achieve

  8. jimiscott says:

    Wenlong, would there be any reason why I wouldn’t be able to see either the synchronous or the asynchronous handlers in the System.ServiceModel.Activation namespace?

  9. Lars Wilhelmsen says:

    What's the story for .NET 4.0 + IIS7? Is the async module/handler used per default?

    –larsw

  10. Alex says:

    Works with WCF 4 on IIS6 as well:

     <system.web>

       <httpHandlers>

         <remove verb="*" path="*.svc" />

         <add path="*.svc" verb="*" type="System.ServiceModel.Activation.ServiceHttpHandlerFactory, System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="False"/>

       </httpHandlers>

       <httpModules>

         <remove name="ServiceModel" />

         <add name="ServiceModel" type="System.ServiceModel.Activation.ServiceHttpModule, System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />

       </httpModules>