Changing the HTTP.sys Kernel Queue Limit When Using .Net HttpListener?

I have an application that uses the HttpListener class in .Net 4.0 to serve HTTP requests.

Under load, I noticed that I was getting 503 - QueueFull - errors reported in the log. A search for this error assumes that this occurs when the maximum number of requests that http.sys will queue is exceeded.

The default queue length is 1000. If you use IIS , this is apparently configured using the Queue Length parameter in the advanced settings of the application pool.

If you are NOT using IIS, is there a way to configure this value? Or is it a control of this parameter, hidden in the HttpListener class, and not subject to developers?

+4
source share
1 answer

It seems that the HttpListener does not allow you to directly change the HttpServerQueueLengthProperty property. And by default, this property is set to 1000 .

But you can try installing it manually after starting the HttpListener . It is hacked because it uses the internal RequestQueueHandle HttpListener property, so use it when you are in danger .

Hack:

 using System; using System.Linq; using System.Net; using System.Reflection; using System.Runtime.InteropServices; namespace Network.Utils { public static class HttpApi { public unsafe static void SetRequestQueueLength(HttpListener listener, long len) { var listenerType = typeof (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, new IntPtr((void*)&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, SetLastError = true)] internal static extern uint HttpSetRequestQueueProperty( CriticalHandle requestQueueHandle, HTTP_SERVER_PROPERTY serverProperty, IntPtr pPropertyInfo, uint propertyInfoLength, uint reserved, IntPtr pReserved); } } 

Usage example:

 using (var listener = new HttpListener()) { listener.Prefixes.Add("http://*:8080/your/service/"); listener.Start(); Network.Utils.HttpApi.SetRequestQueueLength(listener, 5000); // ... } 

After starting the application, you can check the queue length by running the following command:

 netsh http show servicestate 

Check the Max Requests property for your process. Now it should be equal to 5000.

+7
source

Source: https://habr.com/ru/post/1469331/


All Articles