首页 > 解决方案 > 如何在 ASP.NET Kestrel 服务器中设置 TCP 积压

问题描述

ASP.NET 核心 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 ?

我问这个问题是因为客户在尝试连接到我的应用程序时偶尔会在高峰时段遇到错误。

由于目标机器主动拒绝,无法建立连接

它仅在高峰时段偶尔发生(<0.1%),我猜这是因为接受中的 TCP 积压用完。

标签: asp.net-corekestrel-http-server

解决方案


因为当前的 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[] { });
        }
    }

推荐阅读