ASP.NET Core Web服务器 Kestrel和Http.sys 特性详解
1.1. 名詞解釋
內(nèi)核態(tài):?CPU可以訪問內(nèi)存所有數(shù)據(jù), 包括外圍設(shè)備, 例如硬盤, 網(wǎng)卡. CPU也可以將自己從一個程序切換到另一個程序。
用戶態(tài):?只能受限的訪問內(nèi)存, 且不允許訪問外圍設(shè)備. 占用CPU的能力被剝奪, CPU資源可以被其他程序獲取。
1.2. Kestrel基本工作原理
Kestrel是進程內(nèi)服務(wù)器,以一個包形式提供,自身不能單獨運行,必須HOST在一個.NET的WEB應(yīng)用程序中。它內(nèi)部封裝了對libuv的調(diào)用,但不是libuv庫簡單的封裝庫。Kestrel是個精簡的,高效的Http Server。
1.2.1. Kestrel的基本架構(gòu)
Kestrel遵循以下架構(gòu)原則:
libuv中使用單線程的事件循環(huán)模型。
Kestrel支持多事件循環(huán)以支持更多的I/O。
Kestrel僅在libuv的事件循環(huán)中做I/O工作。
所有非I/O工作,包括HTTP解析,請求幀處理等等都在標(biāo)準(zhǔn)的托管線程中進行。
更少的系統(tǒng)調(diào)用。
對應(yīng)的架構(gòu)圖如下:
Libuv
作為I/O底層,屏蔽各系統(tǒng)底層實現(xiàn)差異,為windows下,通過IOCP實現(xiàn)異步;linux下通過epoll實現(xiàn)異步。提供一個主程序和主循環(huán)。
I/O事件隊列
對應(yīng)Libuv的工作隊列,為了利用現(xiàn)代服務(wù)器的多核處理器,適當(dāng)?shù)年犃袛?shù)量將提高更大的I/O吞吐能力。Kestrel默認(rèn)為每兩個CPU核心設(shè)置一個I/O事件隊列,但至少有一個I/O事件隊列。每個隊列對應(yīng)一個托管線程,該線程不屬于線程池。用戶可以設(shè)置隊列個數(shù),通過設(shè)置KestrelServerOptions.ThreadCount即可,最多設(shè)置16個。
Kestrel線程
事件隊列對應(yīng)的托管線程,主要控制讀取事件的循環(huán)機制:每次事件循環(huán)處理8個事件,然后等待下一次循環(huán)。
非托管內(nèi)存池
這是在.net運行環(huán)境分配的非托管內(nèi)存池,申請的比較大塊的堆內(nèi)存,僅在首次請求或者池剩余空間不足時分配,后續(xù)請求可以復(fù)用,不受GC管理。內(nèi)存被分為n片,每片大小是128K,每頁大小4k,管理內(nèi)存頁的數(shù)據(jù)結(jié)構(gòu)采用鏈表方式。以獲取大塊連續(xù)空間的方式增長。遵循讀完后立即釋放的處理原則。
TCP監(jiān)聽器
這個監(jiān)聽器不同于套接字的監(jiān)聽器,而是Libuv的Socket類型的連接事件監(jiān)聽器。監(jiān)聽TCP連接事件,對每一個TCP請求產(chǎn)生一個連接對象。連接對象包括暫停,繼續(xù),終止。
連接管理
負(fù)責(zé)異步結(jié)束連接對象。
HTTP協(xié)議模塊
該模塊包括HTTP幀的創(chuàng)建工廠,工廠在監(jiān)聽器監(jiān)聽到一個連接時產(chǎn)生一個HTTP幀。一個HTTP幀處理一次HTTP請求和返回。
更為詳細(xì)的結(jié)構(gòu)
1.2.2. Kestrel的工作原理
1.2.2.1. 處理Request和Response
按照請求流轉(zhuǎn)方向會有以下處理過程:
1. 請求進入libuv
將請求事件放入事件隊列,隨后的事件循環(huán)中,監(jiān)聽器回調(diào)函數(shù)執(zhí)行。
2. 監(jiān)聽器創(chuàng)建連接
根據(jù)請求信息創(chuàng)建一個連接對象,此時Http幀工廠被調(diào)用,產(chǎn)生一個Http幀對象;用于讀取Request的SocketInput、用于返回Response的SocketOutput對象被創(chuàng)建,二者會被Http幀使用。
3. 連接管理監(jiān)控連接
連接管理器跟蹤連接的狀態(tài),收集待關(guān)閉連接,然后異步關(guān)閉。
4. Http幀處理
一個Http負(fù)責(zé)構(gòu)建Http上下文的Request對象和Response對象。讀取Request數(shù)據(jù)和返回Response數(shù)據(jù)都要經(jīng)過內(nèi)存池。高效的內(nèi)存讀寫和與和Libuv的讀寫事件協(xié)調(diào),確保Request數(shù)據(jù)到達(dá)就能讀到內(nèi)存池,到達(dá)內(nèi)存池就能及時被讀;Response數(shù)據(jù)寫入內(nèi)存池就能被套接字及時發(fā)出去,體現(xiàn)了Kestreld強大的異步處理能力。
1.2.2.2. 內(nèi)存池讀寫
讀取內(nèi)存池數(shù)據(jù)時可讀取后續(xù)到達(dá)的數(shù)據(jù),不需要重新等待事件,此時對應(yīng)讀取Request數(shù)據(jù)情形:
frameborder="0" scrolling="no" style="border-width: initial;border-style: none;width: 601px;height: 153px;">
寫數(shù)據(jù)到內(nèi)存池時,libuv連續(xù)讀出并發(fā)送數(shù)據(jù),也不需要重新等待時間,此時對應(yīng)發(fā)送Response數(shù)據(jù)情形:
frameborder="0" scrolling="no" style="border-width: initial;border-style: none;width: 625px;height: 155px;">
1.2.2.3. Libuv線程和托管線程通信
二者的通信機制保證Libuv線程永遠(yuǎn)不會被阻塞:比如libuv線程在通知事件時會很小心嘗試獲取隊線程私有鎖,如果成功獲取就這在事件隊列線程上異步處理,否則這一通信過程在線程池里重復(fù)執(zhí)行直到成功,如圖:
1.3. Http.sys基本工作原理
1.3.1. Http.sys基本構(gòu)成
1. 監(jiān)聽器
監(jiān)聽TCP請求,允許端口共享。TCP攜帶的HTTP報文會被Http Parser解析,名稱映射首先會根據(jù)url確定對應(yīng)的web app,然后把請求放入該app的消息隊列中。
2. 消息隊列
Http.sys給每個注冊的web app一個消息隊列。
3. 響應(yīng)緩存
請求的靜態(tài)資源和GET請求會緩存起來一段時間,如果請求url能匹配這直接返回緩存數(shù)據(jù)。
4. 響應(yīng)模塊
將數(shù)據(jù)返回給用戶代理,如果返回的是可以緩存的資源,則會放入響應(yīng)緩存中。
1.3.2. Http.sys工作原理
下圖表示在ASP.NET Core應(yīng)用中接受一個http請求到返回數(shù)據(jù)的過程:
這里的TCPIP.sys也是windows內(nèi)核驅(qū)動,提供了TCPIP協(xié)議棧。
Http.sys的處理如在“基本構(gòu)成”做所述。
ASP.NET Core應(yīng)用程序里面HttpSys模塊代表了Http.sys,它與應(yīng)用程序代碼交流,交流的載體是HTTP上下文。
1.3.3. 總結(jié)
Kestrel服務(wù)器運行在Asp.net core應(yīng)用程序中,能高效的處理網(wǎng)絡(luò)請求,且跨平臺。Http.sys運行在內(nèi)核態(tài)中,極大減少了系統(tǒng)調(diào)用次數(shù),運行效率很高;自帶生存環(huán)境的安全,魯棒性等特點;它也可以作為反向代理,因此它的功能更加強大,主要問題是只能運行在windows下。Kestrel應(yīng)用在生產(chǎn)環(huán)境中需要運行在代理服務(wù)器后面,以獲取安全性,負(fù)載均衡等能力。
| 平臺支持 | Windows | Windows/Linux/Mac |
| 靜態(tài)文件 | Yes | Yes |
| HTTP訪問日志 | Yes | No |
| 端口共享/多應(yīng)用程序 | Yes | No |
| SSL證書 | Yes | Internal* |
| Windows 授權(quán) | Yes | No |
| 過濾請求&限制 | Yes | No |
| IP&域名約束 | Yes | No |
| HTTP重定向規(guī)則 | Yes | No |
| WebSocket 協(xié)議 | Yes | Middleware |
| 緩存Response | Yes | No |
| 壓縮 | Yes | Yes |
| FTP服務(wù)器 | Yes | No |
| 運行態(tài) | 內(nèi)核態(tài) | 用戶態(tài) |
* Internal:https通信僅僅工作在反向代理服務(wù)器后面與ASP.NET程序之間,如果要想外暴露https服務(wù)這需要用到反向代理,比如IIS,nginx,apached。
參考文章
http://www.cnblogs.com/yxmx/articles/1652128.html
http://www.cnblogs.com/arbin98/archive/2010/09/03/1816847.html
https://stackify.com/kestrel-web-server-asp-net-core-kestrel-vs-iis/
原文地址:http://www.cnblogs.com/vipyoumay/p/7525478.html
.NET社區(qū)新聞,深度好文,微信中搜索dotNET跨平臺或掃描二維碼關(guān)注
總結(jié)
以上是生活随笔為你收集整理的ASP.NET Core Web服务器 Kestrel和Http.sys 特性详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Centos7 amp;amp; Doc
- 下一篇: asp.net core 2.0 web