编程语言
首页 > 编程语言> > c# – 使用.Net HttpListener时更改HTTP.sys内核队列限制?

c# – 使用.Net HttpListener时更改HTTP.sys内核队列限制?

作者:互联网

我有一个应用程序,它使用.Net 4.0中的HttpListener类来为http请求提供服务.

在负载下我注意到我在日志中报告了503 – QueueFull – 错误.搜索此错误表示当超过http.sys将排队的最大请求数时会发生此错误.

默认队列长度为1000.如果您使用的是IIS,则可以通过应用程序池上的“高级设置”中的“队列长度”参数进行调整.

如果你不使用IIS有什么方法可以调整这个值?或者这个参数的控件是隐藏在HttpListener类中的,而不是暴露给开发人员?

解决方法:

似乎HttpListener不允许直接更改HttpServerQueueLengthProperty属性.和by default this property is set to 1000.

但是你可以尝试在HttpListener启动后手动设置它.它是黑客,因为它使用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.

标签:c,httplistener,http-sys
来源: https://codeday.me/bug/20190613/1229809.html