我有一个使用HttpListener
.Net 4.0 中的类来服务 http 请求的应用程序。
在负载下,我注意到我得到503 - QueueFull
- 日志中报告的错误。搜索此错误表明它发生在http.sys
超过将排队的最大请求数时。
默认队列长度为 1000。如果您正在使用IIS
这似乎可以通过应用程序池的高级设置中的“队列长度”参数进行调整。
如果您不使用 IIS,是否有任何方法可以调整此值?还是这个参数的控制隐藏在HttpListener类中,不暴露给开发者?
我有一个使用HttpListener
.Net 4.0 中的类来服务 http 请求的应用程序。
在负载下,我注意到我得到503 - QueueFull
- 日志中报告的错误。搜索此错误表明它发生在http.sys
超过将排队的最大请求数时。
默认队列长度为 1000。如果您正在使用IIS
这似乎可以通过应用程序池的高级设置中的“队列长度”参数进行调整。
如果您不使用 IIS,是否有任何方法可以调整此值?还是这个参数的控制隐藏在HttpListener类中,不暴露给开发者?
似乎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。