從Jetty、Tomcat和Mina中提煉NIO構架網路伺服器的經典模式(一)
阿新 • • 發佈:2019-01-25
如何正確使用NIO來構架網路伺服器一直是最近思考的一個問題,於是乎分析了一下Jetty、Tomcat和Mina有關NIO的原始碼,發現大夥都基於類似的方式,我感覺這應該算是NIO構架網路伺服器的經典模式,並基於這種模式寫了個小小網路伺服器,壓力測試了一下,效果還不錯。廢話不多說,先看看三者是如何使用NIO的。
Jetty Connector的實現
先看看有關類圖:
其中:
SelectChannelConnector負責組裝各元件
SelectSet負責偵聽客戶端請求
SelectChannelEndPoint負責IO的讀和寫
HttpConnection負責邏輯處理
在整個服務端處理請求的過程可以分為三個階段,時序圖如下所示:
階段一:監聽並建立連線
這一過程主要是啟動一個執行緒負責accept新連線,監聽到後分配給相應的SelectSet,分配的策略就是輪詢。
階段二:監聽客戶端的請求
這一過程主要是啟動多個執行緒(執行緒數一般為伺服器CPU的個數),讓SelectSet監聽所管轄的channel佇列,每個SelectSet維護一個Selector,這個Selector監聽佇列裡所有的channel,一旦有讀事件,從執行緒池裡拿執行緒去做處理請求
階段三:處理請求
這一過程就是每次客戶端請求的資料處理過程,值得注意的是為了不讓後端的業務處理阻礙Selector監聽新的請求,就多執行緒來分隔開監聽請求和處理請求兩個階段。
由此可以大致總結出Jetty有關NIO使用的模式,如下圖所示:
最核心就是把三件不同的事情隔離開,並用不同規模的執行緒去處理,最大限度地利用NIO的非同步和通知特性