如何在 ASP.NET Kestrel 服务器中设置 TCP 积压
How to set TCP backlog in ASP.NET Kestrel Server
ASP.NET Core v2.2.
var builder = WebHost.CreateDefaultBuilder()
.UseConfiguration(AppConfig.Root);
_host = builder.UseKestrel(options =>
{
options.AddServerHeader = false;
options.AllowSynchronousIO = false;
options.Limits.MinResponseDataRate = null;
options.Limits.MinRequestBodyDataRate = null;
options.ListenAnyIP(AppConfig.ClientApi.ListeningPort, (listenOptions) =>
{
listenOptions.NoDelay = true;
});
})
.UseStartup<ClientApiStartup>()
.Build();
问题:如何为 Kestrel Web 服务器配置 TCP backlog?
我问这个问题是因为客户端在高峰时段尝试连接到我的应用程序时偶尔会遇到错误。
No connection could be made because the target machine actively refused it
它只偶尔在高峰时段发生 (<0.1%),我猜这是因为 运行 out of TCP backlog in accept。
因为当前 ASP .NET Core 版本 (v3.0) 硬编码 TCP 积压,我通过利用 Easyhook.
解决了这个问题
class WinsocksHook
{
/// <summary>
/// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-listen
/// </summary>
/// <param name="backlog"></param>
/// <returns></returns>
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
[return: MarshalAs(UnmanagedType.I4)]
delegate int ListenDelegate(IntPtr socket, [MarshalAs(UnmanagedType.I4)] int backlog);
[DllImport("kernel32.dll", EntryPoint = "LoadLibraryA", CharSet = CharSet.Ansi)]
static extern IntPtr LoadLibrary(string dllToLoad);
[DllImport("Ws2_32.dll", EntryPoint = "listen")]
static extern int Listen(IntPtr socket, uint uType);
static int SocketListen(IntPtr socket, int backlog)
{
return Listen(socket, 2048);
}
private static LocalHook _hook;
public static void Install()
{
LoadLibrary("Ws2_32.dll");
_hook = LocalHook.Create( LocalHook.GetProcAddress("Ws2_32.dll", "listen"), new ListenDelegate(SocketListen), null);
_hook.ThreadACL.SetExclusiveACL(new int[] { });
}
}
ASP.NET Core v2.2.
var builder = WebHost.CreateDefaultBuilder()
.UseConfiguration(AppConfig.Root);
_host = builder.UseKestrel(options =>
{
options.AddServerHeader = false;
options.AllowSynchronousIO = false;
options.Limits.MinResponseDataRate = null;
options.Limits.MinRequestBodyDataRate = null;
options.ListenAnyIP(AppConfig.ClientApi.ListeningPort, (listenOptions) =>
{
listenOptions.NoDelay = true;
});
})
.UseStartup<ClientApiStartup>()
.Build();
问题:如何为 Kestrel Web 服务器配置 TCP backlog?
我问这个问题是因为客户端在高峰时段尝试连接到我的应用程序时偶尔会遇到错误。
No connection could be made because the target machine actively refused it
它只偶尔在高峰时段发生 (<0.1%),我猜这是因为 运行 out of TCP backlog in accept。
因为当前 ASP .NET Core 版本 (v3.0) 硬编码 TCP 积压,我通过利用 Easyhook.
解决了这个问题class WinsocksHook
{
/// <summary>
/// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-listen
/// </summary>
/// <param name="backlog"></param>
/// <returns></returns>
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
[return: MarshalAs(UnmanagedType.I4)]
delegate int ListenDelegate(IntPtr socket, [MarshalAs(UnmanagedType.I4)] int backlog);
[DllImport("kernel32.dll", EntryPoint = "LoadLibraryA", CharSet = CharSet.Ansi)]
static extern IntPtr LoadLibrary(string dllToLoad);
[DllImport("Ws2_32.dll", EntryPoint = "listen")]
static extern int Listen(IntPtr socket, uint uType);
static int SocketListen(IntPtr socket, int backlog)
{
return Listen(socket, 2048);
}
private static LocalHook _hook;
public static void Install()
{
LoadLibrary("Ws2_32.dll");
_hook = LocalHook.Create( LocalHook.GetProcAddress("Ws2_32.dll", "listen"), new ListenDelegate(SocketListen), null);
_hook.ThreadACL.SetExclusiveACL(new int[] { });
}
}