写在前面

ASP.NET Core 的 Web 服务器默认采用Kestrel,这是一个基于libuv(一个跨平台的基于Node.js的异步I/O库)的跨平台、轻量级的Web服务器。

在开始之前,先回顾一下.NET Core 3.0默认的main()方法模板中,我们会调用Host.CreateDefaultBuilder方法,该方法的主要功能是配置应用主机及设置主机的属性,设置Kestrel 服务器配置为 Web 服务器,另外还包括日志功能、应用配置加载等等,此处不做展开。

作为一个轻量级的Web Server,它并没有IIS、Apache那些大而全的功能,但它依然可以单独运行,也可以搭配IIS、Apache等反向代理服务器结合使用。

本文将从源码角度讨论ASP.NET Core应用在Kestrel的相关知识点。

Kestrel

Kestrel的存在意义

了解这个问题,首先需要强调的是.NET Core应用的目标就是跨平台,既然要跨平台那么就需要适用各个平台上的Web服务器,各个服务器的启动、配置等等都是不尽相同的,如果每个服务器提供一套实现出来,如果未来出现了一个新的Web Server,然后又要增加新的实现,这会导致.NET Core应用的适用性滞后,也会很消耗人力,无法很好的达到跨平台的目标。

我们可以把Kestrel视作一个中间件,一个适配的功能,它抽象了各个服务器的特性,使得各个应用只需要调用同样的接口,即可最大限度的在各个平台上运行。

运行方式

.NET Core 3.0下,Kestrel的集成已经相当成熟了,也提供了相应的自定义配置,以使得Kestrel的使用更加具有灵活性和可配性。它可以独立运行,也可以与反向代理服务器结合使用。

Kestrel本身是不支持多个应用共享同一个端口的,但是我们可以通过反向代理服务器来实现统一对外的相同的端口的共享。

以下是其单独运行示意图:

以下是其结合反向代理使用示意图:

Microsoft.AspNetCore.Server.Kestrel.Core

该类库是Kestrel的核心类库,里面包含了该功能的多个逻辑实现,以下简称改类库为Kestrel.Core。

Kestrel适配逻辑

如前文所说,Kestrel起到了抽象服务器的功能,那么在适配其他服务器的过程中,必然涉及到的是,输入、输出、数据交互方式以及Trace功能。在Kestrel.Core中,该功能主要由AdaptedPipeline类来实现,该类继承自IDuplexPipe,并通过构造函数获取到了Pipe对象。IDuplexPipe和Pipe均位于System.IO.Pipelines命名空间下,详细信息可以点击查看。

AdaptedPipeline有两个公共方法:

RunAsync():用于读取(读取后会有Flush操作)和写入数据,并分别装载到Task中

CompleteAsync():完成读取和写入操作,并取消基础流的读取

另外还包括四个公共属性,如下所示:

它定义了可从中读取并写入数据的双工管道的对象。IDuplexPipe有两个属性,System.IO.Pipelines.PipeReader Input { get; }和System.IO.Pipelines.PipeReader Output { get; }。AdaptedPipeline还通过构造函数获取到了Pipe对象。

RawStream类继承自Stream,并重写了Stream的关键属性及方法,主要目标是提供适合于Kestrel读写数据方式的内部封装。

LoggingStream类也同样继承自Stream,和RawStream不同的是,里面增加操作过程的日志记录,主要用于记录在连接适配过程中的信息,不过需要启用日志才能把日志信息记录下来,以下是其对外的使用方式:

Kestrel特性抽象

该模块下的 Kestrel特性,比较重要的有连接超时设置(包括设置超时时间、重置超时时间以及取消超时限制。这个特性使得我们的连接变得更加可控,比如,在某些特殊场景下,特性条件下,我们需要取消超时限制或者动态重置超时时间),TLS应用程序协议功能,基于Http2.0的StreamId记录功能,用于停止连接计数的功能。

以下是连接超时接口的源代码:

Kestrel选项及限制功能

Kestrel的选项控制包括监听、Kestrel服务器、HTTPS连接适配。

1、监听选项功能在ListenOptions中实现,该类继承自IConnectionBuilder,ListenOptions的主要作用是描述Kestrel中已经打开的套接字,包括Unix域套接字路径、文件描述符、ipendpoint。ListenOptions内部会维护一个只读的List<Func<ConnectionDelegate, ConnectionDelegate>>()对象,并通过Use()方法加载新的Func<ConnectionDelegate, ConnectionDelegate>对象,然后通过Build方式返回最后加入的Func<ConnectionDelegate, ConnectionDelegate对象,源码如下所示:

需要注意的是ListenOptions在该类库内部还有两个子类,AnyIPListenOptions和LocalhostListenOptions,以用于特定场景的监听使用。

2、Kestrel服务器选项是在KestrelServerOptions中实现的,该类用于提供Kestrel特定功能的编程级别配置,该类内部会维护ListenOptions的列表对象,该类将ListenOptions的功能进一步展开,并加入了HTTPS、证书的默认配置与应用,这个类比较大,这里就不贴出源码了,有兴趣的同学可以自己去翻阅。

3、HTTPS连接适配选项在HttpsConnectionAdapterOptions实现,这个类用于设置Kestrel如何处理HTTPS连接,这里引入了证书功能、SSL协议、HTTP协议、超时功能,同时还可以自定义HTTPS连接时的证书处理模式(AllowCertificate、RequireCertificate等),以下是HttpsConnectionAdapterOptions的构造函数:

可以看到,在默认情况下,是无证书模式,其SSL协议包括Tls12 和Tls11以及指定允许进行TLS/SSL握手的最大时间是十秒钟。

4、Kestrel的限制功能在KestrelServerLimits实现,主要包括:

  • 保持活动状态超时

  • 客户端最大连接数(默认情况下,最大连接数不受限制 (NULL))

  • 请求正文最大大小(默认的请求正文最大大小为 30,000,000 字节,大约 28.6 MB)

  • 请求正文最小数据速率(默认的最小速率为 240 字节/秒,包含 5 秒的宽限期)

  • 请求标头超时(默认值为 30 秒)

  • 每个连接的最大流(默认值为 100)

  • 标题表大小(默认值为 4096)

  • 最大帧大小(默认值为 2^14)

  • 最大请求标头大小(默认值为 8,192)

  • 初始连接窗口大小(默认值为 128 KB)

  • 初始流窗口大小(默认值为 96 KB)

代码如下所示:

其部分源码如下:

参考地址:https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/servers/kestrel?view=aspnetcore-3.0#maximum-streams-per-connection

.NET Core 3.0之深入源码理解Kestrel的集成与应用(一)相关推荐

  1. .NET Core 3.0之深入源码理解Kestrel的集成与应用(二)

    前言 前一篇文章主要介绍了.NET Core继承Kestrel的目的.运行方式以及相关的使用,接下来将进一步从源码角度探讨.NET Core 3.0中关于Kestrel的其他内容,该部分内容,我们无需 ...

  2. .NET Core 3.0之深入源码理解Startup的注册及运行

    开发.NET Core应用,直接映入眼帘的就是Startup类和Program类,它们是.NET Core应用程序的起点.通过使用Startup,可以配置化处理所有向应用程序所做的请求的管道,同时也可 ...

  3. .NET Core 3.0之深入源码理解HealthCheck(一)

    写在前面 我们的系统可能因为正在部署.服务异常终止或者其他问题导致系统处于非健康状态,这个时候我们需要知道系统的健康状况,而健康检查可以帮助我们快速确定系统是否处于正常状态.一般情况下,我们会提供公开 ...

  4. .NET Core 3.0之深入源码理解ObjectPool(一)

    写在前面 对象池是一种比较常用的提高系统性能的软件设计模式,它维护了一系列相关对象列表的容器对象,这些对象可以随时重复使用,对象池节省了频繁创建对象的开销. 它使用取用/归还的操作模式,并重复执行这些 ...

  5. .NET Core 3.0之深入源码理解Host(二)

    写在前面 停了近一个月的技术博客,随着正式脱离996的魔窟,接下来也正式恢复了.本文从源码角度进一步讨论.NET Core 3.0 中关于Host扩展的一些技术点,主要内容是关于创建Long Run ...

  6. .NET Core 3.0之深入源码理解Configuration(一)

    微软在.NET Core里设计出了全新的配置体系,并以非常灵活.可扩展的方式实现.从其源码来看,其运行机制大致是,根据其Source,创建一个Builder实例,并会向其添加Provider,在我们使 ...

  7. .NET Core 3.0之深入源码理解ObjectPool(二)

    写在前面 前文主要介绍了ObjectPool的一些理论基础,本文主要从源码角度理解Microsoft.Extensions.ObjectPool是如何实现的.下图为其三大核心组件图: 核心组件 Obj ...

  8. .NET Core 3.0之深入源码理解HttpClientFactory(二)

    写在前面 上一篇文章讨论了通过在ConfigureServices中调用services.AddHttpClient()方法,并基于此进一步探讨了DefaultHttpClientFactory是如何 ...

  9. .NET Core 3.0之深入源码理解HttpClientFactory(一)

    写在前面 创建HttpClient实例的时候,在内部会创建HttpMessageHandler链,我们知道HttpMessageHandler是负责建立连接的抽象处理程序,所以HttpClient的维 ...

最新文章

  1. Cisco/H3C交换机配置与管理完全手册(第2版)卓越网正式到货
  2. android java 延时函数,如何在Android中设置文本之间的延迟
  3. 用inno做setup遇到的一些问题及解决方法
  4. 多线程(同步代码块和同步函数)
  5. Android之Unexpected error while executing: am start -n “***.Activity“-a android.intent.action.MAIN
  6. Web中的鼠标自动移动
  7. linux硬链接符号,Linux — 硬链接与符号链接
  8. python-函数之命名空间作用域
  9. 2019全国大学生软件测试大赛决赛
  10. 程序员需要有多懒 ?- cocos2d-x 数学函数、常用宏粗整理
  11. 2018东北四省赛 Spell Boost DP
  12. 明解c语言答案第八章,《明解C语言》第1章初识C语言练习题答案(最新整理)
  13. Python爬虫学习总结
  14. java描述空间直线_java实验作业类的定义与描述
  15. C语言程序设计-算数运算符、赋值运算符、逗号运算符及表达式
  16. latex 中文书籍常见命令
  17. 将Windows7屏幕外的窗口拖回
  18. EDA设计(verilog)—— 七段管时钟
  19. 百度全景图片展示-20130908
  20. “无顶背离不抛盘,无底背离不抢筹”,这才是MACD的精髓

热门文章

  1. ipad和iphone切图_如何在iPhone,iPad和Mac上使消息静音
  2. 如何从Internet Explorer或Edge迁移到Chrome(以及为什么要迁移)
  3. LoadRunner+Android模所器实现抓包并调试本地服务端
  4. 你一写长文章就焦虑拖延?
  5. 设计模式 ( 十四 ) 迭代器模式Iterator(对象行为型)
  6. QT-Linux开发环境的搭建
  7. Oracle RAC 修改 IP 地址
  8. .NET+Sqlite如何支持加密
  9. Win11开始大范围推送!
  10. Blazor Server 应用程序中进行 HTTP 请求