Jetty9原始碼剖析 - 總體架構
轉載自ph0ly:http://www.ph0ly.com
一、概述
Jetty作為高效能Web伺服器,它的架構相比於Tomcat要簡單很多,元件抽象更簡潔,接下來我們就來看下
二、架構
上圖中,綠色部分是Jetty開放給開發者使用的;淺橙色表示JDK或Servlet規範定義的(或開發者實現的),不屬於Jetty自身實現;藍色部分表示Jetty內部實現的一些元件,不對外暴露
上圖基本展示了資料互動的整體流向,我們下面從元件的生命週期來分析這些操作的互動
1. 啟動
我們首先看下Jetty官方給我們的例子
開發者首先建立一個Server,然後建立ServerConnector作為通訊層,並關聯到Server,再建立ServletContextHandler作為Handler來處理業務,可以看到這裡加了2個Servlet,然後把這2個Servlet放到一個集合傳給Server,最後呼叫Server.start啟動伺服器
可以看到所有的元件最終都被關聯到了Server,其實Server就是一個大容器,將容器內的所有具有生命週期的元件全部逐層啟動(start),另一些不具有生命週期的元件仍然可以把Server看成一個IOC容器,後續可以直接獲取到例項物件
從架構圖中可以看到Server觸發Connector、Handler元件啟動,而Connector又會觸發SelectorManager、ManagedSelector啟動,這樣其實是逐級啟動,Server是一個大容器,而Handler也可能是一個大容器(例如WebAppContext,感興趣的讀者可以跳到後續文章),這個啟動過程其實是LifeCycle元件定義的,如果這裡不明白,可以看下後續LifeCycle的文章
2. 連線
當client與Jetty伺服器建立連線時,連線會直接打到SelectorManager提供的ServerSocketChannel,accept後,拿到這個client對應的SocketChannel後,會選擇一個ManagedSelector來執行IO事件檢測,並建立好這條連線對應的EndPoint以及Connection
3. 請求
當client向剛才建立的連線中寫入請求資料時,ManagedSelector對應的事件檢測迴圈(感興趣的讀者可以跳到後續Connector元件閱讀)會探測到讀事件,會觸發SelectChannelEndPoint觸發讀回撥,從而呼叫到HttpConnection.onFillable,onFillable裡面藉助於ByteBufferPool、HttpParser完成資料讀取及解析,將解析後的元資料放入Request,直接觸發HttpChannel.handle,這會打到Server.handle方法,Server會找到之前關聯到自身的Handler,執行這個Handler的handle方法,這樣就開啟了Handler執行鏈(感興趣的讀者可以提前跳到Handler元件閱讀),層層呼叫,最後呼叫到應用層Filter、Servlet,完成業務操作
4. 響應
當應用層完成業務操作後,呼叫Response.getWriter或Response.getOutputStream,最終會呼叫到HttpOutput.write方法,觸發資料回寫,這時呼叫到HttpChannel.write,這裡會觸發HttpConnection.send,而HttpConnection會利用HttpGenerator生成響應報文,然後觸發SelectChannelEndPoint向SocketChannel刷資料,這樣就完成了響應(當然真實的細節還有很多,例如一次刷不完,下一次哪裡刷?感興趣的讀者可以跳到後續Connection閱讀)