Browse Source

Merge pull request #539 from MalcolmEvershed/windows-errors

Fix Windows errors by boosting HTTP.SYS and IIS queues
Brian Hauer 11 years ago
parent
commit
8ebe23e19b
2 changed files with 57 additions and 0 deletions
  1. 53 0
      HttpListener/HttpListener/Program.cs
  2. 4 0
      toolset/setup/windows/installer.ps1

+ 53 - 0
HttpListener/HttpListener/Program.cs

@@ -12,6 +12,8 @@ using System.Web.Script.Serialization;
 using MongoDB.Driver.Builders;
 
 using Benchmarks.AspNet.Models;
+using System.Reflection;
+using System.Runtime.InteropServices;
 
 namespace HttpListener
 {
@@ -111,6 +113,10 @@ namespace HttpListener
             {
                 listener.Start();
 
+                // Increase the HTTP.SYS backlog queue from the default of 1000 to 65535.
+                // To verify that this works, run `netsh http show servicestate`.
+                Network.Utils.HttpApi.SetRequestQueueLength(listener, 65535);
+
                 for (;;)
                 {
                     HttpListenerContext context = null;
@@ -401,3 +407,50 @@ namespace HttpListener
         }
     }
 }
+
+// Adapted from:
+// http://stackoverflow.com/questions/15417062/changing-http-sys-kernel-queue-limit-when-using-net-httplistener
+namespace Network.Utils
+{
+    public static class HttpApi
+    {
+        public static void SetRequestQueueLength(System.Net.HttpListener listener, uint len)
+        {
+            var listenerType = typeof(System.Net.HttpListener);
+            var requestQueueHandleProperty = listenerType.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance).First(p => p.Name == "RequestQueueHandle");
+
+            var requestQueueHandle = (CriticalHandle)requestQueueHandleProperty.GetValue(listener);
+            var result = HttpSetRequestQueueProperty(requestQueueHandle, HTTP_SERVER_PROPERTY.HttpServerQueueLengthProperty, ref len, (uint)Marshal.SizeOf(len), 0, IntPtr.Zero);
+
+            if (result != 0)
+            {
+                throw new HttpListenerException((int)result);
+            }
+        }
+
+        internal enum HTTP_SERVER_PROPERTY
+        {
+            HttpServerAuthenticationProperty,
+            HttpServerLoggingProperty,
+            HttpServerQosProperty,
+            HttpServerTimeoutsProperty,
+            HttpServerQueueLengthProperty,
+            HttpServerStateProperty,
+            HttpServer503VerbosityProperty,
+            HttpServerBindingProperty,
+            HttpServerExtendedAuthenticationProperty,
+            HttpServerListenEndpointProperty,
+            HttpServerChannelBindProperty,
+            HttpServerProtectionLevelProperty,
+        }
+
+        [DllImport("httpapi.dll", CallingConvention = CallingConvention.StdCall)]
+        internal static extern uint HttpSetRequestQueueProperty(
+            CriticalHandle requestQueueHandle,
+            HTTP_SERVER_PROPERTY serverProperty,
+            ref uint pPropertyInfo,
+            uint propertyInfoLength,
+            uint reserved,
+            IntPtr pReserved);
+    }
+}

+ 4 - 0
toolset/setup/windows/installer.ps1

@@ -74,6 +74,10 @@ appcmd set config -section:httpProtocol /allowKeepAlive:true | Out-Null
 appcmd set config -section:httpLogging /dontLog:True | Out-Null
 # Enable detailed error pages
 #appcmd set config -section:system.webServer/httpErrors -errorMode:Detailed | Out-Null
+# Increase queue length for DefaultAppPool to avoid HTTP 503 errors coming from HTTP.SYS
+appcmd set apppool DefaultAppPool /queueLength:65535
+# Increase appConcurrentRequestLimit to avoid HTTP 503.2 errors from IIS http://support.microsoft.com/kb/943891
+appcmd set config -section:system.webServer/serverRuntime /appConcurrentRequestLimit:65535
 
 # URL Rewrite
 $rewrite_url = "http://download.microsoft.com/download/6/7/D/67D80164-7DD0-48AF-86E3-DE7A182D6815/rewrite_2.0_rtw_x64.msi"