kestral (红隼)

kestral (红隼)

kestral (红隼)_第1张图片
image

kestral server

源码 https://github.com/aspnet/KestrelHttpServer

1.微软为啥要做kestral 聊聊微软做kestral的背景和历史

在2000年之前的ASP.NET开发之初,Microsoft创建了容器来托管ASP.NET WebForms应用程序

  • Cassini,后来成为Visual Studio中的ASP.NET开发服务器。它是一个用C#编写的完全托管的Web服务器HttpListener

  • IIS上的ASP.NET支持


  • iis5 请求模型
kestral (红隼)_第2张图片
image.png
  • iis6 请求模型


    kestral (红隼)_第3张图片
    image.png
  • iis7 请求模型


    kestral (红隼)_第4张图片
    image.png

IIS7中对asp.net的请求不再是分两条处理管道,而是将asp.net和IIS集成起来。这样做的好处有很多,包括统一了请求验证工作,加强了asp.net对于请求的控制能力等等。在IIS7中,asp.net不再像IIS6一样只限定于aspnet_isapi.dll中,而是被解放出来,从IIS接收到HTTP请求开始,即进入asp.net的控制范围,as.net可以存在于一个请求在IIS中各个处理阶段。甚至可以为部署在IIS7中的PHP应用提供基于asp.net的验证身份验证功能


发展方向

1 ASP.NET变得更加复杂
2 与IIS集成更加紧密
3 IIS Express(用户模式精简版IIS) 取代了Cassini

Kestrel

2014年11月,ASP.NET 5(后来改名为ASP.NET Core)宣布成为跨平台技术。
显然,微软需要一种新的设计来支持Windows,macOS和Linux。而iis和window的强耦合基本上是无法移植到其他平台上的。
kestral应该说是微软为了托管跨平台的asp.net core定制的一款应用服务器容器。

1. 简介

kestral 是一款进程内web服务器(自托管),不同于asp.net需要把网站托管到iis上才能运行。
kestral 设计上大量“借鉴”了nodejs的设计思想,kestral I/O底层和nodejs 一样使用了Libuv,屏蔽了不通操作系统的I/O差异。nodejs 的中间件也在asp.net mvc core中找得到影子。和nodejs的express服务器一样,kestral也是应用内服务器容器。
kestral运行效率很高,Libuv有很大的功劳!

2.架构

kestral (红隼)_第5张图片

Libuv

作为I/O底层,屏蔽各系统底层实现差异,为windows下,通过IOCP实现异步;linux下通过epoll实现异步。提供一个主程序和主循环。

I/O事件队列

对应Libuv的工作队列,为了利用现代服务器的多核处理器,适当的队列数量将提高更大的I/O吞吐能力。Kestrel默认为每两个CPU核心设置一个I/O事件队列,但至少有一个I/O事件队列。每个队列对应一个托管线程,该线程不属于线程池。用户可以设置队列个数,通过设置KestrelServerOptions.ThreadCount即可,最多设置16个。

Kestrel线程

事件队列对应的托管线程,主要控制读取事件的循环机制:每次事件循环处理8个事件,然后等待下一次循环。

非托管内存池

这是在.net运行环境分配的非托管内存池,申请的比较大块的堆内存,仅在首次请求或者池剩余空间不足时分配,后续请求可以复用,不受GC管理。内存被分为n片,每片大小是128K,每页大小4k,管理内存页的数据结构采用链表方式。以获取大块连续空间的方式增长。遵循读完后立即释放的处理原则。

TCP监听器

这个监听器不同于套接字的监听器,而是Libuv的Socket类型的连接事件监听器。监听TCP连接事件,对每一个TCP请求产生一个连接对象。连接对象包括暂停,继续,终止。

连接管理

负责异步结束连接对象。

HTTP协议模块

该模块包括HTTP帧的创建工厂,工厂在监听器监听到一个连接时产生一个HTTP帧。一个HTTP帧处理一次HTTP请求和返回。

kestral (红隼)_第6张图片
image.png

Kestrel Web Server的工作原理

通常编写应用程序以响应人类行为。通过事件驱动编程,有一个监听事件的循环。然后它会触发回调函数。要减少SYS调用的数量,所有其他工作都在标准.NET工作线程的托管代码中执行。

Kestrel提供事件循环和基于回调的I / O通知。Libuv负责管理从操作系统收集和监控事件。此外,用户可以在事件发生时注册回调。因此,Kestrel使用libuv进行I / O工作,并支持运行多个事件循环。

由于它非常轻巧,因此Kestrel不允许您进行SSL终止,URL重写或GZip压缩,但相同的轻量级设计可以使其他Web服务器看起来比较慢。它建立得很快; 事实上,对于静态和纯文本操作,它比node.js快六倍。

Kestrel 的优点

Kestrel支持.NET Core支持的所有平台和版本。此外,它默认包含在ASP.NET Core新项目模板中,可以提供更好的请求处理性能。在Visual Studio中创建新项目时,您的项目将自动配置为在Kestrel中运行。

如前所述,它不是一个功能齐全的Web服务器,但这正是它快速的原因。

你要做的就是在一个功能完善的Web服务器比如IIS、Nginx上运行它。你可以在IIS上或者Visual Studio上的IIS Express上通过HttpPlatformHandler类来运行。

现在不仅仅可以跨平台运行,直接通过命令行都可以让ASP.NET在Web服务器上运行。

kestrel+http.sys

nuget包 Microsoft.AspNetCore.Server.HttpSys

HttpSys实现仅适用于Windows平台。

在早期版本的 ASP.NET Core 的中,HTTP.sys 被命名为 [WebListener]

HTTP.sys 是一项成熟的技术,可以抵御多种攻击,并提供可靠、安全、可伸缩的全功能 Web 服务器。 IIS 本身作为 HTTP.sys 之上的 HTTP 侦听器运行。

http.sys和ASP.NET Core Module 不兼容,所以不能和iis express/iis一起使用。

image.png

下图是Http.sys 实现端口共享的方式


kestral (红隼)_第7张图片
image.png

下图显示了http.sys与应用程序之间的关系。


kestral (红隼)_第8张图片
image.png

下图显示的是kestral和http.sys功能对比


kestral (红隼)_第9张图片
image.png

3.运行方式

Kestrel直接与Internet通信,无需反向代理服务器

Kestrel通过反向代理服务器(如IIS,Nginx或Apache)间接与Internet通信

4.编码

启用kestral

kestral (红隼)_第10张图片
image.png
kestral (红隼)_第11张图片
image.png

kestral (红隼)_第12张图片
image.png

配置URL
方式1


kestral (红隼)_第13张图片
image.png

方式2


kestral (红隼)_第14张图片
image.png

方式3

kestral (红隼)_第15张图片
image.png

URL前缀

默认情况下,ASP.NET Core项目绑定了http://localhost:5000。通过使用UseUrls扩展方法——编辑urls命令行参数,或者是通过ASP.NET Core配置系统,你可以为Ketrel配置URL前缀和端口号以用来侦听请求。关于这些方法更多的信息,请参考Hosting。有关于当你使用IIS作为反向代理时,URL绑定是如何工作的信息,请参考ASP.NET Core 模块。

Kestrel URL前缀可以是以下格式中的任一种。

· IPv4 地址和端口号

http://65.55.39.10:80/

https://65.55.39.10:443/

· IPv6 地址和端口号

http://[0:0:0:0:0:ffff:4137:270a]:80/

https://[0:0:0:0:0:ffff:4137:270a]:443/

IPv6中的 [::] 等价于 IPv4 0.0.0.0。

· 主机名和端口号

http://contoso.com:80/

http://*:80/

https://contoso.com:443/

https://*:443/

主机名称,*,以及+,都不是特殊的。任何没有公认的IP 或是“localhost”的地址将绑定到所有的IPv4和IPv6的IP上。如果你需要为不同的ASP.NET Core应用在同一端口上绑定不同的主机名,请使用WebListener或者诸如IIS,Nginx或Apache这样的反向代理服务器。

* "Localhost" 名称和端口号或回送IP地址和端口号

http://localhost:5000/

http://127.0.0.1:5000/

http://[::1]:5000/

当localhost被指定时,Kestrel会尝试去绑定到IPv4和IPv6的环回接口。如果被请求的端口号正在任一环回接口上被其他服务所使用,Kestrel将会启动失败。如果任一环回接口出于各种原因而不可用(最通常的情况是因为IPv6暂不被支持),Kestrel将记录下一个警告信息。

· Unix socket

http://unix:/run/dan-live.sock

如果你指定了端口号0,Kestrel将动态地绑定到合适的端口号。除了localhost名称,绑定到0端口号被其他任何主机名称或IP地址所允许。

当你指定了端口号0,你可以使用IServerAddressesFeature接口去决定运行时Kestrel实际绑定到哪个端口。下列示例用于获取绑定端口并且在console上显示出来。

public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)

{

loggerFactory.AddConsole();

var serverAddressesFeature = app.ServerFeatures.Get();

app.UseStaticFiles();

app.Run(async (context) =>

{

context.Response.ContentType = "text/html";

await context.Response

.WriteAsync("

Hosted by Kestrel

");

if (serverAddressesFeature != null)

{

await context.Response

.WriteAsync("

Listening on the following addresses: " +

string.Join(", ", serverAddressesFeature.Addresses) +

"

");

}

await context.Response.WriteAsync($"

Request URL: {context.Request.GetDisplayUrl()}

");

});

}

SSL的URL 前缀

如果你调用UseSSL扩展方法,请确保在https:中包含URL前缀,如下所示:

var host = new WebHostBuilder()

.UseKestrel(options =>

{

options.UseHttps("testCert.pfx", "testPassword");

})

.UseUrls("http://localhost:5000", "https://localhost:5001")

.UseContentRoot(Directory.GetCurrentDirectory())

.UseStartup()

.Build();

Note

HTTPS和HTTP不能在同一端口上被托管。

正向代理 反向代理

kestral (红隼)_第16张图片
image.png
kestral (红隼)_第17张图片
image.png

反向代理服务器(Reverse Proxy Server)是通过在WEB服务器和Internet之间增加一个缓冲认证服务器来保障内部服务器的安全和可控访问。

你可能感兴趣的:(kestral (红隼))