Skip to content

ClementeGao/kestrel-linux-transport

 
 

Repository files navigation

This code is no longer maintained, and won't be updated for new versions of .NET.

Introduction

The ASP.NET Core Kestrel webserver has been using libuv as a cross-platform network library. It is possible to replace libuv with another implementation thanks to the Transport abstraction.

In this repo we explore creating a Transport for Linux specifically.

Using the package

Add the myget feed to your NuGet.Config file:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <add key="rh" value="https://www.myget.org/F/redhat-dotnet/api/v3/index.json" />
  </packageSources>
</configuration>

Include a package reference in your project csproj file:

  <ItemGroup>
    <PackageReference Include="RedHat.AspNetCore.Server.Kestrel.Transport.Linux" Version="3.1.0-*" />
  </ItemGroup>

Call UseLinuxTransport when creating the WebHost in your Program.cs:

public static IWebHost BuildWebHost(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder
                        .UseLinuxTransport()
                        .UseStartup<Startup>();
                });

note: It's safe to call UseLinuxTransport on non-Linux platforms, it will no-op.

Repo structure

There are 5 projects in this repository:

  • src/RedHat.AspNetCore.Server.Kestrel.Transport.Linux: managed library implementing Transport
  • samples/KestrelSample: Kestrel app for benchmarking
  • test/RedHat.AspNetCore.Server.Kestrel.Transport.Linux.Test: xunit test projects, has access to internals of managed library
  • test/RedHat.AspNetCore.Server.Kestrel.Transport.Linux.TestApp: empty application to use during development, has access to internals of managed library

The library can be packaged by running the dotnet pack on src/RedHat.AspNetCore.Server.Kestrel.Transport.Linux.

$ dotnet pack src/RedHat.AspNetCore.Server.Kestrel.Transport.Linux --configuration Release

To build the library and run the tests execute dotnet test on test/RedHat.AspNetCore.Server.Kestrel.Transport.Linux.Test.

$ dotnet test test/RedHat.AspNetCore.Server.Kestrel.Transport.Linux.Test

Design

Similar to other implementations, this library makes use of the non-blocking socket and epoll. Like the corefx Socket implementation, the eventloop is implemented in managed (C#) code. This is different from the libuv loop which is part of the native libuv library.

This library does not provide a generic xplat network API. It uses the kernel primitives directly to implement the Transport API. This reduces the number of heap allocated objects (e.g. uv_buf_t, SocketAsyncEventArgs), which means there is less GC pressure. Implementations building on top of an xplat API will pool objects to achieve this.

The implementation starts a number of threads that each accept connections. This is based on SO_REUSEPORT socket option. This option allow multiple sockets to concurrently bind and listen to the same port. The kernel performs load-balancing between the listen sockets.

The Transport has these options:

  • DeferSend: This defers sends to the Transport Thread which increases chances for multiple sends to coalesce. This options defaults to true.

  • ThreadCount: Specifies the number of Transport Threads. This defaults to the number of logical processors in the system, maxed to 16.

  • AioSend/AioReceive: Uses Linux AIO system calls to batch send and receive calls. AioSend implies DeferSend. These options default to true.

About

Linux Transport for Kestrel

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • C# 100.0%