ASP.NET Core Web服務器 Kestrel和Http.sys 特性詳解


1.1. 名詞解釋

內核態: CPU能夠訪問內存全部數據, 包括外圍設備, 例如硬盤, 網卡. CPU也能夠將本身從一個程序切換到另外一個程序。html

用戶態: 只能受限的訪問內存, 且不容許訪問外圍設備. 佔用CPU的能力被剝奪, CPU資源能夠被其餘程序獲取。linux

1.2. Kestrel基本工做原理

Kestrel是進程內服務器,以一個包形式提供,自身不能單獨運行,必須HOST在一個.NET的WEB應用程序中。它內部封裝了對libuv的調用,但不是libuv庫簡單的封裝庫。Kestrel是個精簡的,高效的Http Server。
nginx

1.2.1. Kestrel的基本架構

Kestrel遵循如下架構原則:web

  • libuv中使用單線程的事件循環模型。
  • Kestrel支持多事件循環以支持更多的I/O。
  • Kestrel僅在libuv的事件循環中作I/O工做。
  • 全部非I/O工做,包括HTTP解析,請求幀處理等等都在標準的託管線程中進行。
  • 更少的系統調用。

對應的架構圖以下:apache

2017-09-13-23-07-16

  • Libuvwindows

    做爲I/O底層,屏蔽各系統底層實現差別,爲windows下,經過IOCP實現異步;linux下經過epoll實現異步。提供一個主程序和主循環。緩存

  • I/O事件隊列安全

    對應Libuv的工做隊列,爲了利用現代服務器的多核處理器,適當的隊列數量將提升更大的I/O吞吐能力。Kestrel默認爲每兩個CPU核心設置一個I/O事件隊列,但至少有一個I/O事件隊列。每一個隊列對應一個託管線程,該線程不屬於線程池。用戶能夠設置隊列個數,經過設置KestrelServerOptions.ThreadCount便可,最多設置16個。服務器

  • Kestrel線程markdown

    事件隊列對應的託管線程,主要控制讀取事件的循環機制:每次事件循環處理8個事件,而後等待下一次循環。

  • 非託管內存池

    這是在.net運行環境分配的非託管內存池,申請的比較大塊的堆內存,僅在首次請求或者池剩餘空間不足時分配,後續請求能夠複用,不受GC管理。內存被分爲n片,每片大小是128K,每頁大小4k,管理內存頁的數據結構採用鏈表方式。以獲取大塊連續空間的方式增加。遵循讀完後當即釋放的處理原則。

  • TCP監聽器

    這個監聽器不一樣於套接字的監聽器,而是Libuv的Socket類型的鏈接事件監聽器。監聽TCP鏈接事件,對每個TCP請求產生一個鏈接對象。鏈接對象包括暫停,繼續,終止。

  • 鏈接管理

    負責異步結束鏈接對象。

  • HTTP協議模塊

    該模塊包括HTTP幀的建立工廠,工廠在監聽器監聽到一個鏈接時產生一個HTTP幀。一個HTTP幀處理一次HTTP請求和返回。

更爲詳細的結構視圖以下:

2017-09-13-23-23-55

1.2.2. Kestrel的工做原理

1.2.2.1. 處理Request和Response

2017-09-14-21-21-30

按照請求流轉方向會有如下處理過程:

1. 請求進入libuv

將請求事件放入事件隊列,隨後的事件循環中,監聽器回調函數執行。

2. 監聽器建立鏈接

根據請求信息建立一個鏈接對象,此時Http幀工廠被調用,產生一個Http幀對象;用於讀取Request的SocketInput、用於返回Response的SocketOutput對象被建立,兩者會被Http幀使用。

3. 鏈接管理監控鏈接

鏈接管理器跟蹤鏈接的狀態,收集待關閉鏈接,而後異步關閉。

4. Http幀處理

一個Http負責構建Http上下文的Request對象和Response對象。讀取Request數據和返回Response數據都要通過內存池。高效的內存讀寫和與和Libuv的讀寫事件協調,確保Request數據到達就能讀到內存池,到達內存池就能及時被讀;Response數據寫入內存池就能被套接字及時發出去,體現了Kestreld強大的異步處理能力。

1.2.2.2. 內存池讀寫

讀取內存池數據時可讀取後續到達的數據,不須要從新等待事件,此時對應讀取Request數據情形:

2017-09-14-23-42-10

寫數據到內存池時,libuv連續讀出併發送數據,也不須要從新等待時間,此時對應發送Response數據情形:

2017-09-14-23-42-58

1.2.2.3. Libuv線程和託管線程通訊

兩者的通訊機制保證Libuv線程永遠不會被阻塞:好比libuv線程在通知事件時會很當心嘗試獲取隊線程私有鎖,若是成功獲取就這在事件隊列線程上異步處理,不然這一通訊過程在線程池裏重複執行直到成功,如圖:

2017-09-14-23-28-33

1.3. Http.sys基本工做原理

1.3.1. Http.sys基本構成

2017-09-10-12-25-14

1. 監聽器

監聽TCP請求,容許端口共享。TCP攜帶的HTTP報文會被Http Parser解析,名稱映射首先會根據url肯定對應的web app,而後把請求放入該app的消息隊列中。

2. 消息隊列

Http.sys給每一個註冊的web app一個消息隊列。

3. 響應緩存

請求的靜態資源和GET請求會緩存起來一段時間,若是請求url能匹配這直接返回緩存數據。

4. 響應模塊

將數據返回給用戶代理,若是返回的是能夠緩存的資源,則會放入響應緩存中。

1.3.2. Http.sys工做原理

下圖表示在ASP.NET Core應用中接受一個http請求到返回數據的過程:

2017-09-10-11-29-05

  1. 這裏的TCPIP.sys也是windows內核驅動,提供了TCPIP協議棧。

  2. Http.sys的處理如在「基本構成」作所述。

  3. ASP.NET Core應用程序裏面HttpSys模塊表明了Http.sys,它與應用程序代碼交流,交流的載體是HTTP上下文。

1.3.3. 總結

Kestrel服務器運行在Asp.net core應用程序中,能高效的處理網絡請求,且跨平臺。Http.sys運行在內核態中,極大減小了系統調用次數,運行效率很高;自帶生存環境的安全,魯棒性等特色;它也能夠做爲反向代理,所以它的功能更增強大,主要問題是隻能運行在windows下。Kestrel應用在生產環境中須要運行在代理服務器後面,以獲取安全性,負載均衡等能力。

功能 Http.sys Kerstrel
平臺支持 Windows Windows/Linux/Mac
靜態文件 Yes Yes
HTTP訪問日誌 Yes No
端口共享/多應用程序 Yes No
SSL證書 Yes Internal*
Windows 受權 Yes No
過濾請求&限制 Yes No
IP&域名約束 Yes No
HTTP重定向規則 Yes No
WebSocket 協議 Yes Middleware
緩存Response Yes No
壓縮 Yes Yes
FTP服務器 Yes No
運行態 內核態 用戶態

* Internal:https通訊僅僅工做在反向代理服務器後面與ASP.NET程序之間,若是要想外暴露https服務這須要用到反向代理,好比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

相關文章
相關標籤/搜索