日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > asp.net >内容正文

asp.net

聊聊ASP.NET Core默认提供的这个跨平台的服务器——KestrelServer

發(fā)布時(shí)間:2023/12/4 asp.net 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 聊聊ASP.NET Core默认提供的这个跨平台的服务器——KestrelServer 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

跨平臺(tái)是ASP.NET Core一個(gè)顯著的特性,而KestrelServer是目前微軟推出了唯一一個(gè)能夠真正跨平臺(tái)的Server。KestrelServer利用一個(gè)名為KestrelEngine的網(wǎng)絡(luò)引擎實(shí)現(xiàn)對(duì)請(qǐng)求的監(jiān)聽、接收和響應(yīng)。KetrelServer之所以具有跨平臺(tái)的特質(zhì),源于KestrelEngine是在一個(gè)名為libuv的跨平臺(tái)網(wǎng)絡(luò)庫(kù)上開發(fā)的。


目錄

一、libuv

二、KestrelServer

三、KestrelServerOptions

四、ApplicationLifetime

五、設(shè)置監(jiān)聽地址


一、libuv

image說起libuv,就不得不談?wù)刲ibev,后者是Unix系統(tǒng)上一個(gè)事件循環(huán)和事件模型的網(wǎng)絡(luò)庫(kù)。libev因其具有的高性能成為了繼lievent和Event perl module之后一套最受歡迎的網(wǎng)絡(luò)庫(kù)。由于Libev不支持Windows,有人在libev之上創(chuàng)建了一個(gè)抽象層以屏蔽平臺(tái)之間的差異,這個(gè)抽象層就是libuv。libuv在Windows平臺(tái)上是采用IOCP的形式實(shí)現(xiàn)的,右圖揭示了libuv針對(duì)Unix和Windows的跨平臺(tái)實(shí)現(xiàn)原理。到目前為止,libuv支持的平臺(tái)已經(jīng)不限于Unix和Windows了,包括Linux(2.6)、MacOS和Solaris (121以及之后的版本)在內(nèi)的平臺(tái)在libuv支持范圍之內(nèi)。


二、KestrelServer

如下所示的代碼片段體現(xiàn)了KestrelServer這個(gè)類型的定義。除了實(shí)現(xiàn)接口IServer定義的Features屬性之外,KestrelServer還具有一個(gè)類型為KestrelServerOptions的只讀屬性O(shè)ptions。這個(gè)屬性表示對(duì)KestrelServer所作的相關(guān)設(shè)置,我們?cè)谡{(diào)用構(gòu)造函數(shù)時(shí)通過輸入?yún)?shù)options所代表的IOptions<KestrelServerOptions>對(duì)象對(duì)這個(gè)屬性進(jìn)行初始化。構(gòu)造函數(shù)還具有另兩個(gè)額外的參數(shù),它們的類型分別是IApplicationLifetime和ILoggerFactory,后者用于創(chuàng)建記錄日志的Logger,前者與應(yīng)用的生命周期管理有關(guān)。


? ?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: }


我們一般通過調(diào)用WebHostBuilder的擴(kuò)展方法UseKestrel方法來完成對(duì)KestrelServer的注冊(cè)。如下面的代碼片段所示,UseKestrel方法具有兩個(gè)重載,其中一個(gè)具有同一個(gè)類型為Action<KestrelServerOptions>的參數(shù),我們可以利用這個(gè)參數(shù)直接完成對(duì)KestrelServerOptions的設(shè)置。


? ?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負(fù)責(zé)請(qǐng)求的監(jiān)聽、接收和響應(yīng),所以Server是影響整個(gè)Web應(yīng)用響應(yīng)能力和吞吐量最大的因素之一,為了更加有效地使用Server,我們往往針對(duì)具體的網(wǎng)絡(luò)負(fù)載狀況對(duì)其作針對(duì)性的設(shè)置。對(duì)于KestrelServer來說,在構(gòu)造函數(shù)中作為參數(shù)指定的KestrelServerOptions對(duì)象代表針對(duì)它所做的設(shè)置。我們針對(duì)KestrelServer所做的設(shè)置主要體現(xiàn)在KestrelServerOptions類型的如下5個(gè)屬性上。


? ?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注冊(cè)的KetrelServer在管道中會(huì)以依賴注入的方式被創(chuàng)建,并采用構(gòu)造器注入的方式提供其構(gòu)造函數(shù)的參數(shù)options,由于這個(gè)參數(shù)類型為IOptions<KestrelServerOptions>,所以我們利用Options模型以配置的方式來指定KestrelServerOptions對(duì)象承載的設(shè)置。比如我們可以將KestrelServer的相關(guān)配置定義在如下一個(gè)JSON文件中。


? ?1: {?

? ?2: ? ? "noDelay" ? ? ? ? : false,?

? ?3: ? ? "shutdownTimeout" : "00:00:10",?

? ?4: ? ? "threadCount" ? ? : 10?

? ?5: }?


為了讓應(yīng)用加載這么一個(gè)配置文件(文件名假設(shè)為“KestrelServerOptions.json”),我們只需要在啟動(dòng)類型(Startup)類的ConfigureServces方法中按照如下的方式利用ConfigurationBuilder加載這個(gè)配置文件并生成相應(yīng)的Configuration對(duì)象,最后按照Options模型的編程方式完成KestrelServerOptions類型和該對(duì)象的映射即可。


? ?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

我們將所有實(shí)現(xiàn)了IApplicationLifetime接口的所有類型及其對(duì)應(yīng)對(duì)象統(tǒng)稱為ApplicationLifetime。從命名的角度來看,ApplicationLifetime貌似是對(duì)當(dāng)前應(yīng)用生命周期的描述,而實(shí)際上它存在的目的僅僅是在應(yīng)用啟動(dòng)和關(guān)閉(只要是關(guān)閉)時(shí)對(duì)相關(guān)組件發(fā)送通知而已。如下面的代碼片段所示,IApplicationLifetime接口具有三個(gè)CancellationToken類型的屬性(ApplicationStarted、ApplicationStopping和ApplicationStopped),我們可以利用它們是否已經(jīng)被取消(Cancel)確定當(dāng)前應(yīng)用的狀態(tài)(已經(jīng)開啟、正在關(guān)閉和已經(jīng)關(guān)閉)。如果試圖關(guān)閉應(yīng)用,StopApplication方法應(yīng)該被調(diào)用以發(fā)出應(yīng)用正在被關(guān)閉的通知。對(duì)于KestrelServer來說,如果請(qǐng)求處理線程中發(fā)生未被處理異常,它會(huì)調(diào)用這個(gè)方法。


? ?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默認(rèn)使用的ApplicationLifetime是具有如下定義的一個(gè)同名類型??梢钥闯鏊鼘?shí)現(xiàn)的三個(gè)屬性返回的CancellationToken對(duì)象是通過三個(gè)對(duì)應(yīng)的CancellationTokenSource生成。除了實(shí)現(xiàn)IApplicationLifetime接口的StopApplication方法用于發(fā)送“正在關(guān)閉”通知之外,這個(gè)類型還定義了額外兩個(gè)方法(NotifyStarted和NotifyStopped)用于發(fā)送“已經(jīng)開啟/關(guān)閉”的通知。


? ?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: }


一個(gè)ASP.NET Core應(yīng)用利用管道處理請(qǐng)求,所以管道的生命周期等同于應(yīng)用自身的生命周期。當(dāng)我們調(diào)用Run方法開啟WebHost時(shí),請(qǐng)求處理管道被構(gòu)建出來。如果管道在處理請(qǐng)求時(shí)發(fā)生未被處理的異常,管道的Sever會(huì)調(diào)用ApplicationLifeTime對(duì)象的StopApplication方法向WebHost發(fā)送關(guān)閉應(yīng)用的通知以便后者執(zhí)行一些回收釋放工作。


五、設(shè)置監(jiān)聽地址

在演示的實(shí)例中,我們實(shí)際上并不曾為注冊(cè)的KestrelServer指定一個(gè)監(jiān)聽地址,從運(yùn)行的效果我們不難看出,WebHost在這種情況下會(huì)指定“http://localhost:5000”為默認(rèn)的監(jiān)聽地址,Server的監(jiān)聽地址自然可以顯式指定。在介紹如何通過編程的方式為Server指定監(jiān)聽地址之前,我們有先來認(rèn)識(shí)一個(gè)名為ServerAddressesFeature的特性。


我們知道表示Server的接口IServer中定義了一個(gè)類型為IFeatureCollection 的只讀屬性Features,它表示用于描述當(dāng)前Server的特性集合,ServerAddressesFeature作為一個(gè)重要的特性,就包含在這個(gè)集合之中。我們所說的ServerAddressesFeature對(duì)象是對(duì)所有實(shí)現(xiàn)了IServerAddressesFeature接口的所有類型及其對(duì)應(yīng)對(duì)象的統(tǒng)稱,該接口具有一個(gè)唯一的只讀屬性返回Server的監(jiān)聽地址列表。ASP.NET Core默認(rèn)使用的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: }


對(duì)于WebHost在通過依賴注入的方式創(chuàng)建的Server,由它的Features屬性表示的特性集合中會(huì)默認(rèn)包含這么一個(gè)ServerAddressesFeature對(duì)象。如果沒有一個(gè)合法的監(jiān)聽地址被添加到這個(gè) ServerAddressesFeature對(duì)象的地址列表中,WebHost會(huì)將顯式指定的地址(一個(gè)或者多個(gè))添加到該列表中。我們顯式指定的監(jiān)聽地址實(shí)際上是作為WebHost的配置保存在一個(gè)Configuration對(duì)象上,配置項(xiàng)對(duì)應(yīng)的Key為“server.urls”,WebHostDefaults的靜態(tài)只讀屬性ServerUrlsKey返回的就是這么一個(gè)Key。


? ?1: new WebHostBuilder()

? ?2: ? ? .UseSetting(WebHostDefaults.ServerUrlsKey, "http://localhost:3721/")

? ?3: ? ? .UseMyKestrel()

? ?4: ? ? .UseStartup<Startup>()

? ?5: ? ? .Build()

? ?6: ? ? ?.Run();


WebHost的配置最初來源于創(chuàng)建它的WebHostBuilder,后者提供了一個(gè)UseSettings方法來設(shè)置某個(gè)配置項(xiàng)的值,所以我們可以采用如下的方式來指定監(jiān)聽地址(“http://localhost:3721/”)。不過,針對(duì)監(jiān)聽地址的顯式設(shè)置,最直接的編程方式還是調(diào)用WebHostBuilder的擴(kuò)展方法UseUrls,如下面的代碼片段所示,該方法的實(shí)現(xiàn)邏輯與上面完全一致。


? ?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: }


  • 通過一個(gè)Hello World程序來認(rèn)識(shí)一下ASP.NET Core的請(qǐng)求處理管道

  • 創(chuàng)建一個(gè)“迷你版”的管道模擬ASP.NET Core管道對(duì)HTTP請(qǐng)求的處理流程

  • 通過模擬管道為你演示ASP.NET Core管道是如何處理HTTP請(qǐng)求的

  • ASP.NET Core的HTTP請(qǐng)求處理管道是如何一步步建立起來的?


  • 學(xué)習(xí)ASP.NET Core,你必須知道“中間件”是什么?中間件如何注冊(cè)?請(qǐng)求處理管道是如何通過中間件構(gòu)建的?

  • ASP.NET Core 管道= 服務(wù)器+ HttpApplication,HttpApplication是個(gè)什么玩意兒?



請(qǐng)掃描此二維碼或者搜索“大內(nèi)老A”關(guān)注蔣金楠(Artech)微信公眾帳號(hào),你將會(huì)得到及時(shí)的高質(zhì)量技術(shù)文章推送信息。

內(nèi)容轉(zhuǎn)載自公眾號(hào)

大內(nèi)老A 了解更多

總結(jié)

以上是生活随笔為你收集整理的聊聊ASP.NET Core默认提供的这个跨平台的服务器——KestrelServer的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。