如何配置 asp.net kestrel 以实现低延迟?

Yur*_*y L 6 c# linux low-latency kestrel .net-core

我正在尝试实现一个 asp.net 2.2 应用程序,以尽可能低的延迟来处理 HTTP 请求(不是吞吐量,它不是用于生产,而是用于某种竞争)。该应用程序应该在具有 4 个内核的 Linux docker 容器环境中运行,并且我的处理程序在每个 0.2..3 毫秒时受到 CPU 限制。连接是预先创建的并保持活动状态,但我目前为空处理程序获得大约 0.6..0.8 毫秒的处理时间(回复 200 OK),有明显的抖动,偶尔会出现 20-50 毫秒的峰值,我不能解释。

是否有任何特定的 Kestrel/Sockets/Threads/CLR 设置可以帮助最小化每个请求的响应时间?或者,如果我想将其降低到 0.1..0.2 毫秒,使用 EPOLL 的 C/C++ 路线是我唯一的选择?

Sve*_*vek 7

使用 ASP.NET Core / Kestrel 当然可以实现低延迟。

这是一个微型网络应用程序来演示这一点......

using System.Net;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;

public static void Main(string[] args)
{
    IWebHost host = new WebHostBuilder()
        .UseKestrel()
        .Configure(app =>
        {
            // notice how we don't have app.UseMvc()?
            app.Map("/hello", SayHello);  // <-- ex: "http://localhost/hello"
        })
        .Build();

    host.Run();
}

private static void SayHello(IApplicationBuilder app)
{
    app.Run(async context =>
    {
        // implement your own response
        await context.Response.WriteAsync("Hello World!");
    });
}
Run Code Online (Sandbox Code Playgroud)

我在这里这里之前已经多次回答过这种类似的问题。

如果您希望将 ASP.NET Core 框架与其他框架进行比较,这是一个很好的视觉效果https://www.techempower.com/benchmarks/#section=data-r16&hw=ph&test=plaintext。如您所见,ASP.NET Core 具有出色的结果,并且是 C# 的领先框架。

在我上面的代码块中,我注意到缺少app.UseMvc(). 如果您确实需要它,我在这个答案中做了一个关于获得更好延迟的非常详细的答案:AddMvc() 和 AddMvcCore() 之间有什么区别?


.NET 核心运行时 (CoreRT)

如果您仍然需要更高的性能,我鼓励您查看.Net Core Runtime (CoreRT)

请注意,在撰写本文时,可能需要更详细地查看此选项,然后再针对生产系统执行此操作。

“CoreRT 带来了本机编译的大部分性能和所有部署优势,同时保留了用您最喜欢的 .NET 编程语言编写的能力。”

CoreRT 提供了对许多应用程序至关重要的巨大优势。

  • 本机编译器生成一个单一文件,包括应用程序、托管依赖项和 CoreRT。
  • 本机编译的应用程序启动速度更快,因为它们执行已编译的代码。它们不需要在运行时生成机器代码,也不需要加载 JIT 编译器。
  • 本机编译的应用程序可以使用优化编译器,从而提高质量代码的吞吐量(C++ 编译器优化)。LLILLC 和 IL 到 CPP 编译器都依赖于优化编译器。

这些好处为 .NET 开发人员开辟了一些新的场景

  • 从一台机器复制单个文件可执行文件并在另一台(同类)上运行,而无需安装 .NET 运行时。
  • 创建并运行包含单个文件可执行文件(例如,除了 Ubuntu 14.04 之外的一个文件)的 docker 映像。

特定于 Linux 的优化

有一个很好的库,试图处理非常特殊的情况。特别是对于 Linux(但此代码对于其他操作系统是安全的)。这种优化背后的原理是libuv用另一个特定于 Linux 的优化替换传输库(ASP.NET Core 使用的)。

它直接使用内核原语来实现传输 API。这减少了堆分配对象的数量(例如uv_buf_tSocketAsyncEventArgs),这意味着 GC 压力较小。构建在 xplat API 之上的实现将汇集对象来实现这一点。

using RedHat.AspNetCore.Server.Kestrel.Transport.Linux; // <--- note this !

public static IWebHost BuildWebHost(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseLinuxTransport()     // <--- and note this !!!
        .UseStartup()
        .Build();

// note: It's safe to call UseLinuxTransport on non-Linux platforms, it will no-op
Run Code Online (Sandbox Code Playgroud)

您可以在 GitHub 上查看该中间件的存储库https://github.com/redhat-developer/kestrel-linux-transport

在此处输入图片说明

在此处输入图片说明

来源:https : //developers.redhat.com/blog/2018/07/24/improv-net-core-kestrel-performance-linux/