KestrelServer
KestrelServer
跨平台是ASP.NET Core一个显著的特性,而KestrelServer是目前微软推出了唯一一个能够真正跨平台的Server。KestrelServer利用一个名为KestrelEngine的网络引擎实现对请求的监听、接收和响应。KetrelServer之所以具有跨平台的特质,源于KestrelEngine是在一个名为libuv的跨平台网络库上开发的。
目录
一、libuv
二、KestrelServer
三、KestrelServerOptions
四、ApplicationLifetime
五、设置监听地址
一、libuv
说起libuv,就不得不谈谈libev,后者是Unix系统上一个事件循环和事件模型的网络库。libev因其具有的高性能成为了继lievent和Event perl module之后一套最受欢迎的网络库。由于Libev不支持Windows,有人在libev之上创建了一个抽象层以屏蔽平台之间的差异,这个抽象层就是libuv。libuv在Windows平台上是采用IOCP的形式实现的,右图揭示了libuv针对Unix和Windows的跨平台实现原理。到目前为止,libuv支持的平台已经不限于Unix和Windows了,包括Linux(2.6)、MacOS和Solaris (121以及之后的版本)在内的平台在libuv支持范围之内。
二、KestrelServer
如下所示的代码片段体现了KestrelServer这个类型的定义。除了实现接口IServer定义的Features属性之外,KestrelServer还具有一个类型为KestrelServerOptions的只读属性Options。这个属性表示对KestrelServer所作的相关设置,我们在调用构造函数时通过输入参数options所代表的IOptions<KestrelServerOptions>对象对这个属性进行初始化。构造函数还具有另两个额外的参数,它们的类型分别是IApplicationLifetime和ILoggerFactory,后者用于创建记录日志的Logger,前者与应用的生命周期管理有关。
1: public class KestrelServer : IServer
2: {
3: public IFeatureCollection Features { get; }
4: public KestrelServerOptions Options { get; }
5:
6: public KestrelServer(IOptions<KestrelServerOptions> options,IApplicationLifetime applicationLifetime, ILoggerFactory loggerFactory);
7: public void Dispose();
8: public void Start<TContext>(IHttpApplication<TContext> application);
9: }
我们一般通过调用WebHostBuilder的扩展方法UseKestrel方法来完成对KestrelServer的注册。如下面的代码片段所示,UseKestrel方法具有两个重载,其中一个具有同一个类型为Action<KestrelServerOptions>的参数,我们可以利用这个参数直接完成对KestrelServerOptions的设置。
1: public static class WebHostBuilderKestrelExtensions
2: {
3: public static IWebHostBuilder UseKestrel(this IWebHostBuilder hostBuilder);
4: public static IWebHostBuilder UseKestrel(this IWebHostBuilder hostBuilder, Action<KestrelServerOptions> options);
5: }
三、KestrelServerOptions
由于Server负责请求的监听、接收和响应,所以Server是影响整个Web应用响应能力和吞吐量最大的因素之一,为了更加有效地使用Server,我们往往针对具体的网络负载状况对其作针对性的设置。对于KestrelServer来说,在构造函数中作为参数指定的KestrelServerOptions对象代表针对它所做的设置。我们针对KestrelServer所做的设置主要体现在KestrelServerOptions类型的如下5个属性上。
1: public class KestrelServerOptions
2: {
3: //省略其他成员
4: public int MaxPooledHeaders { get; set; }
5: public int MaxPooledStreams { get; set; }
6: public bool NoDelay { get; set; }
7: public TimeSpan ShutdownTimeout { get; set; }
8: public int ThreadCount { get; set; }
9: }
KestrelServerOptions注册的KetrelServer在管道中会以依赖注入的方式被创建,并采用构造器注入的方式提供其构造函数的参数options,由于这个参数类型为IOptions<KestrelServerOptions>,所以我们利用Options模型以配置的方式来指定KestrelServerOptions对象承载的设置。比如我们可以将KestrelServer的相关配置定义在如下一个JSON文件中。
1: {
2: "noDelay" : false,
3: "shutdownTimeout" : "00:00:10",
4: "threadCount" : 10
5: }
为了让应用加载这么一个配置文件(文件名假设为“KestrelServerOptions.json”),我们只需要在启动类型(Startup)类的ConfigureServces方法中按照如下的方式利用ConfigurationBuilder加载这个配置文件并生成相应的Configuration对象,最后按照Options模型的编程方式完成KestrelServerOptions类型和该对象的映射即可。
1: public class Startup
2: {
3: //其他成员
4: public void ConfigureServices(IServiceCollection services)
5: {
6: IConfiguration configuration = new ConfigurationBuilder()
7: .AddJsonFile("KestrelServerOptions.json")
8: .Build();
9: services.Configure<KestrelServerOptions>(configuration);
10: }
11: }
四、ApplicationLifetime
我们将所有实现了IApplicationLifetime接口的所有类型及其对应对象统称为ApplicationLifetime。从命名的角度来看,ApplicationLifetime貌似是对当前应用生命周期的描述,而实际上它存在的目的仅仅是在应用启动和关闭(只要是关闭)时对相关组件发送通知而已。如下面的代码片段所示,IApplicationLifetime接口具有三个CancellationToken类型的属性(ApplicationStarted、ApplicationStopping和ApplicationStopped),我们可以利用它们是否已经被取消(Cancel)确定当前应用的状态(已经开启、正在关闭和已经关闭)。如果试图关闭应用,StopApplication方法应该被调用以发出应用正在被关闭的通知。对于KestrelServer来说,如果请求处理线程中发生未被处理异常,它会调用这个方法。
1: public interface IApplicationLifetime
2: {
3: CancellationToken ApplicationStarted { get; }
4: CancellationToken ApplicationStopping { get; }
5: CancellationToken ApplicationStopped { get; }
6:
7: void StopApplication();
8: }
ASP.NET Core默认使用的ApplicationLifetime是具有如下定义的一个同名类型。可以看出它实现的三个属性返回的CancellationToken对象是通过三个对应的CancellationTokenSource生成。除了实现IApplicationLifetime接口的StopApplication方法用于发送“正在关闭”通知之外,这个类型还定义了额外两个方法(NotifyStarted和NotifyStopped)用于发送“已经开启/关闭”的通知。
1: public class ApplicationLifetime : IApplicationLifetime
2: {
3: private readonly CancellationTokenSource _startedSource = new CancellationTokenSource();
4: private readonly CancellationTokenSource _stoppedSource = new CancellationTokenSource();
5: private readonly CancellationTokenSource _stoppingSource = new CancellationTokenSource();
6:
7: public CancellationToken ApplicationStarted
8: {
9: get { return this._startedSource.Token; }
10: }
11: public CancellationToken ApplicationStopped
12: {
13: get { return this._stoppedSource.Token; }
14: }
15: public CancellationToken ApplicationStopping
16: {
17: get { return this._stoppingSource.Token; }
18: }
19:
20: public void NotifyStarted()
21: {
22: this._startedSource.Cancel(false);
23: }
24: public void NotifyStopped()
25: {
26: this._stoppedSource.Cancel(false);
27: }
28: public void StopApplication()
29: {
30: this._stoppingSource.Cancel(false);
31: }
32: }
一个ASP.NET Core应用利用管道处理请求,所以管道的生命周期等同于应用自身的生命周期。当我们调用Run方法开启WebHost时,请求处理管道被构建出来。如果管道在处理请求时发生未被处理的异常,管道的Sever会调用ApplicationLifeTime对象的StopApplication方法向WebHost发送关闭应用的通知以便后者执行一些回收释放工作。
五、设置监听地址
在演示的实例中,我们实际上并不曾为注册的KestrelServer指定一个监听地址,从运行的效果我们不难看出,WebHost在这种情况下会指定“http://localhost:5000”为默认的监听地址,Server的监听地址自然可以显式指定。在介绍如何通过编程的方式为Server指定监听地址之前,我们有先来认识一个名为ServerAddressesFeature的特性。
我们知道表示Server的接口IServer中定义了一个类型为IFeatureCollection 的只读属性Features,它表示用于描述当前Server的特性集合,ServerAddressesFeature作为一个重要的特性,就包含在这个集合之中。我们所说的ServerAddressesFeature对象是对所有实现了IServerAddressesFeature接口的所有类型及其对应对象的统称,该接口具有一个唯一的只读属性返回Server的监听地址列表。ASP.NET Core默认使用的ServerAddressesFeature是具有如下定义的同名类型。
1: public interface IServerAddressesFeature
2: {
3: ICollection<string> Addresses { get; }
4: }
5:
6: public class ServerAddressesFeature : IServerAddressesFeature
7: {
8: public ICollection<string> Addresses { get; }
9: }
对于WebHost在通过依赖注入的方式创建的Server,由它的Features属性表示的特性集合中会默认包含这么一个ServerAddressesFeature对象。如果没有一个合法的监听地址被添加到这个 ServerAddressesFeature对象的地址列表中,WebHost会将显式指定的地址(一个或者多个)添加到该列表中。我们显式指定的监听地址实际上是作为WebHost的配置保存在一个Configuration对象上,配置项对应的Key为“server.urls”,WebHostDefaults的静态只读属性ServerUrlsKey返回的就是这么一个Key。
1: new WebHostBuilder()
2: .UseSetting(WebHostDefaults.ServerUrlsKey, "http://localhost:3721/")
3: .UseMyKestrel()
4: .UseStartup<Startup>()
5: .Build()
6: .Run();
WebHost的配置最初来源于创建它的WebHostBuilder,后者提供了一个UseSettings方法来设置某个配置项的值,所以我们可以采用如下的方式来指定监听地址(“http://localhost:3721/”)。不过,针对监听地址的显式设置,最直接的编程方式还是调用WebHostBuilder的扩展方法UseUrls,如下面的代码片段所示,该方法的实现逻辑与上面完全一致。
1: public static class WebHostBuilderExtensions
2: {
3: public static IWebHostBuilder UseUrls(this IWebHostBuilder hostBuilder, params string[] urls)
4: =>hostBuilder.UseSetting(WebHostDefaults.ServerUrlsKey, string.Join(ServerUrlsSeparator, urls)) ;
5: }
KestrelServer的更多相关文章
- 聊聊ASP.NET Core默认提供的这个跨平台的服务器——KestrelServer
跨平台是ASP.NET Core一个显著的特性,而KestrelServer是目前微软推出了唯一一个能够真正跨平台的Server.KestrelServer利用一个名为KestrelEngine的网络 ...
- asp.net core mvc剖析:KestrelServer
KestrelServer是基于Libuv开发的高性能web服务器,那我们现在就来看一下它是如何工作的.在上一篇文章中提到了Program的Main方法,在这个方法里Build了一个WebHost,我 ...
- .NET CORE学习笔记系列(6)——KestrelServer
原文:http://www.cnblogs.com/artech/p/KestrelServer.html 跨平台是ASP.NET Core一个显著的特性,而KestrelServer是目前微软推出了 ...
- .NET Core开发日志——从ASP.NET Core Module到KestrelServer
ASP.NET Core程序现在变得如同控制台(Console)程序一般,同样通过Main方法启动整个应用.而Main方法要做的事情很简单,创建一个WebHostBuilder类,调用其Build方法 ...
- .NET 云原生架构师训练营(KestrelServer源码分析)--学习笔记
目录 目标 源码 目标 理解 KestrelServer 如何接收网络请求,网络请求如何转换成 http request context(C# 可识别) 源码 https://github.com/d ...
- KestrelServer详解[1]:注册监听终结点(Endpoint)
具有跨平台能力的KestrelServer是最重要的服务器类型.针对KestrelServer的设置均体现在KestrelServerOptions配置选项上,注册的终结点是它承载的最重要的配置选项. ...
- KestrelServer详解[2]: 网络链接的创建
<注册监听终结点(Endpoint)>已经详细讲述了如何使用KestrelServer,现在我们来简单聊聊这种处理器的总体设计和实现原理.当KestrelServer启动的时候,注册的每个 ...
- KestrelServer详解[3]: 自定义一个迷你版的KestrelServer
和所有的服务器一样,KestrelServer最终需要解决的是网络传输的问题.在<网络连接的创建>,我们介绍了KestrelServer如何利用连接接听器的建立网络连接,并再次基础上演示了 ...
- 如何远程关闭一个ASP.NET Core应用?
在<历数依赖注入的N种玩法>演示系统自动注册服务的实例中,我们会发现输出的列表包含两个特殊的服务,它们的对应的服务接口分别是IApplicationLifetime和IHostingEnv ...
随机推荐
- Oracle行转列实例
行转列之前的数据: select * from tbname; 行转列之后的数据: select pud, listagg(ud, ',') within group(order by null) a ...
- Cocos2d-x win7 + vs2010 配置图文详解(亲测)
下载最新版的cocos2d-x.打开浏览器,输入cocos2d-x.org,然后选择Download,本教程写作时最新版本为cocos2d-1.01-x-0.9.1,具体下载位置如下图: 下载完之后, ...
- Laravel OAuth2 (一) ---简单获取用户信息
前言 本来要求是使用微信进行第三方登陆,所以想着先用 github 测试成功再用微信测试,可是最近拖了好久都还没申请好微信开放平台的 AppID ,所以就只写 github 的第三方登陆吧,估计微信的 ...
- Sublime Text 2使用技巧汇总
一.下载链接: Windows-64bit: http://pan.baidu.com/s/1o6QdKYu 其它版本请移步官网: http://www.sublimetext.com/ 二.破解Li ...
- win7 VMware Workstation Centos6.5虚机桥接上网设置 详解(靠谱)
1.VMware Workstation 设置 2. vim /etc/sysconfig/network-scripts/ifcfg-eth0 NAME="System eth0" ...
- synapse socket总结三:心跳(Heartbeat)
首先转载一篇关于心跳的博文解释: 所谓的心跳包就是客户端定时发送简单的信息给服务器端告诉它我还在而已.代码就是每隔几分钟发送一个固定信息给服务端,服务端收到后回复一个固定信息如果服务端几分钟内没有收到 ...
- BZOJ 1613: [Usaco2007 Jan]Running贝茜的晨练计划
题目 1613: [Usaco2007 Jan]Running贝茜的晨练计划 Time Limit: 5 Sec Memory Limit: 64 MB Description 奶牛们打算通过锻炼来 ...
- A. Liserious战队
Liserious战队是一支活跃在京沪地区的著名密室逃脱战队,在优秀的队长Liserious和芳姐的带领下,打遍天下大大小小的密室逃脱,攻无不克,战无不胜,上天入地无所不能. 世界密室逃脱委员会以IS ...
- 搭建你的持续集成server - CruiseControl step by step(1)
CruiseControl是CIserver的老者,诞生已是多年,在很多方面,CruiseControlserver已经成为持续集成实践的同义词.而如今,CruiseControl已发展成为一个家族式 ...
- Eclipse快捷键 10个最有用的快捷键(转载)
现在很多开发人员都在用eclipse.用开发工具,就是为了方便,方便你开发你的软件,方便你管理你的工程,而开发工具提供各种功能大部分会有对应的快捷键,下面就列出了eclipse的快捷键. Ecli ...