1. 程式人生 > >netcore高性能Web服務器Kestrel分析

netcore高性能Web服務器Kestrel分析

adp -a 環境 tco 參數設置 內存 spa 工作任務 port

Kestrel是aspnetcore中的web服務器之一,其本身有跨平臺,輕量級,高性能的特點

在 ryzen 1600 12核cpu 測試環境中,瞬間每秒處理請求數能達到2w5以上,與netty不相上下,相當於同樣環境下iis ASP.NET處理能力的3倍左右

為了了解Kestrel為什麽如此強勁,我從github上下載了源代碼進行分析,地址是:

https://github.com/aspnet/KestrelHttpServer

Kestrel端口監聽參數使用的是 EndPoint ,包含了需要監聽的IP和端口信息

對於每一個 EndPoint ,使用一個 ITransport 實例進行監聽, ITransport

ITransportFactory 工廠創建

ITransportFactory 為單實例,默認為 SocketTransportFactory ,該工廠由 UseKestrel 的啟動參數設置

Kestrel的有兩種TransportFactory的實現

Kestrel.Transport.Libuv

Kestrel.Transport.Sockets

在啟動時,首先從 ServiceCollection 中獲取到 ITransportFactory ,使用工廠再創建一個 ITransport

SocketTransport 在初始化時創建一個調度器數組 _schedulers = PipeScheduler[]

數組大小為 ioQueueCountioQueueCount 從配置中讀取,默認數量為cpu線程數,線程數不足16的情況下為16

如果指定了 ioQueueCount 的情況下,並且值為0,將會拋出異常

SocketTransport 中調度器使用的是 IOQueue 實現,其具體實現是通過 ThreadPool.QueueUserWorkItem 往線程池中工作隊列添加工作任務

SocketTransport 啟動後,將會運行一個循環任務,每次循環會循環所有調度器,通過 awit AcceptAsync 獲取請求信息,然後交給調度器執行連接

對於Socket數據處理部分,使用的是異步Socket,Scoket不同平臺的實現是不一樣的

在Windows下,Scoket是對windows socket2的簡單封裝,windows socket2是一套支持阻塞/無阻塞的win32api

對於linux下的實現,我目前還在研究中,對其理解還不夠深入

一般情況下,調度器的數量對Kestrel的處理能力影響不是很大,Kestrel對於請求的處理,都是通過往線程池添加工作任務來完成,其處理速度由線程池中的線程數量決定

總的來說,Kestrel是對異步Socket的簡單封裝,並利用線程池,內存池,實現了Actor模型,所有的請求都是無阻塞處理的,所以在處理能力上提升很大

當然,aspnetcore中間件管道模式也是其性能好的原因之一

netcore高性能Web服務器Kestrel分析