4

我有一个使用HttpListener.Net 4.0 中的类来服务 http 请求的应用程序。

在负载下,我注意到我得到503 - QueueFull- 日志中报告的错误。搜索此错误表明它发生在http.sys超过将排队的最大请求数时。

默认队列长度为 1000。如果您正在使用IIS这似乎可以通过应用程序池的高级设置中的“队列长度”参数进行调整。

如果您使用 IIS,是否有任何方法可以调整此值?还是这个参数的控制隐藏在HttpListener类中,不暴露给开发者?

4

1 回答 1

7

似乎HttpListener不允许直接更改HttpServerQueueLengthProperty属性。默认情况下,此属性设置为 1000

但是你可以尝试在HttpListener启动后手动设置。这是 hack,因为它使用HttpListener的内部属性RequestQueueHandle,所以使用它需要你的风险

黑客:

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);         
    }
}

使用示例:

using (var listener = new HttpListener())
{
    listener.Prefixes.Add("http://*:8080/your/service/");
    listener.Start();

    Network.Utils.HttpApi.SetRequestQueueLength(listener, 5000);

    // ...
}

应用程序启动后,您可以通过运行以下命令检查队列长度:

netsh http show servicestate

检查您的流程的“最大请求数”属性。现在它必须等于 5000。

于 2013-05-08T10:38:36.660 回答