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的實現
在啟動時,首先從 ServiceCollection 中獲取到 ITransportFactory ,使用工廠再創建一個 ITransport
SocketTransport 在初始化時創建一個調度器數組 _schedulers = PipeScheduler[]
數組大小為 ioQueueCount , ioQueueCount 從配置中讀取,默認數量為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中間件管道模式也是其性能好的原因之一