引言 java
Jetty相較於Tomcat更加輕便,雖然架構更加簡單,可是看起來可並不輕鬆。Spring是設計初衷是用來管理應用中的實例Bean,於是是基於Bean的架構;Jetty則更傾向於流程和組件的管理,採用了基於handler的架構。handler的嵌套和鏈式結構,LifeCycle和doStart、doHandler模式無不印證了這點。 web
本文主要從基本架構、LifeCycle結構、Handler體系結構、Jetty啓動過程、接受並處理請求的流程和與Tomcat的比較來簡要介紹下Jetty,細節部分後面的博文會有分析。 設計模式
Jetty的基本架構 服務器
前面的博文談及應用服務期的架構已經說過了幾個基本模塊的概念,connection、Threadpool等~拷貝了許令波畫的圖(文中關於基本架構的描述挺詳細的,參考了其目錄結構哈~不過對於有些知識點有本身的見解,所以總結該文): session
該博文中談到「Jetty 中還有一些無關緊要的組件,咱們能夠在它上作擴展。如 JMX,咱們能夠定義一些 Mbean 把它加到 Server 中,當 Server 啓動的時候,這些 Bean 就會一塊兒工做。」個人理解是,Jetty中的JMX是提供給server的Container,使得註冊到server的Handler同時註冊到JMX上,以便於運行時的監控和管理,應該是先有server再有JMX,而不是反過來的。 架構
LifeCycle體系結構 app
Jetty是基於Handler的架構模式,對於組件化的概念很容易理解,那Jetty又是如何管理流程和Handler的生命週期的呢,這就須要從下節的Handler的體系架構來解釋,本節主要分析LifeCycle。 webapp
寫文檔最討厭的就是畫圖,無奈有些圖無法copy~ 組件化
上圖包含四層涵義: 性能
一、每一個Handler都是一個LifeCycle
二、AggregateLifeCycle正如起名,彙集在一塊兒的生命週期。Jetty把Handler生命週期所關聯的一些subHandler註冊在Hahdler上,eg:server->deployManager正是如此。
三、監聽器的概念就是一個觀察者模式的應用,觸發於Handler的doStart,doStop,doFail等事件。
四、Jetty的LifeCycle結構主要影響Jetty的初始化,而Handler結構影響Jetty的處理功能。
Handler體系結構
既然Jetty是基於Handler的架構,那麼Handler體系關乎着Jetty的方方面面:
上圖有幾層涵義:
一、紅色的server即Jetty的核心Handler,它依賴的幾個類雖然不是Handler,也在圖中標出以方便理解,server須要Deploy部署,須要Connector,天然須要inner Handler,這裏的紅色的虛線是默認的依賴關係,嵌入式的Jetty或自定義狀況下是能夠變的,好比換成ResourceHandler,WebAppContext等~
二、AbatractHandlerContainer提供對嵌套Handler獲取Childs的方法支持,所以位於很頂層。
三、ContextHandlerCollection不一樣於普通的HandlerCollection的區別在於,提供了對於Context的支持,即依據生產的app創建app與name的映射關係並對於url請求依據該映射關係分發到指定的app中。
四、HandlerWrapper僅僅提供了簡單的對於Wapper的handler等操做,其實handler操做並非主要的,Jetty中主要是用它來建立Handler的嵌套結構,就如ScopedHander同樣,而handler操做大多數時候無用。
五、ScopedHandler這個真是折騰我很久,這樣設計的意圖着實很差理解,後面有專題解釋,爲理解本文,你能夠將實現了繼承了該類的Handler理解成已是一個完整的嵌套Handler便可。
六、ContextHandler從圖中能夠看到,由DeployManager生產,並和ServletHandler等構成了嵌套Handler。ContextHandler的本質可理解爲ServletContext,取到ServletContext,因爲嵌套Handler的構造繼而會調用ServletHandler等初始化和相關操做,最後走到web應用中處理業務代碼。其實這個嵌套關係是能夠修改的,好比應用中用不到sessionHandler,徹底能夠將其刪除掉,但問題在與這種關係寫在了代碼中,爲何就不能留在配置文件中呢?也許配置文件也能夠,沒有驗證過。
Jetty的啓動過程
實際流程比較複雜,上面的時序圖是個簡化版本。啓動的時序圖有幾點須要注意:
一、紅線部分的第一次其實並無handler,由於沒有生產webappcontext,第二次再次調用start的時候才真的運做
二、藍線部分描述的就是app的生產到contextHandler的生產的過程,後面的contextHandler的初始化是因爲deployManager註冊了事件監聽器觸發的。
三、最後打開Http鏈接,監聽請求的到來
接受請求
因爲Jetty默認採用NIO的方式接受請求,本文基於NIO的方式簡單介紹下實現原理,由於NIO內容比較多,會在下面的文章中給出總結。
處理請求
主要介紹jetty接收到請求後如何生產並解析Request,Response等屬性並最終走到handler方法體內。
這裏面涉及到的connection有多個,SelectorChannelConnector、SelectorChannelEndPoint、AsyncHttpConnection,功能各不相同,下面NIO章節會詳細總結。
Jetty與Tomcat的區別
因爲沒有研究過Tomcat,因此區別很差說,這裏暫時就網上的一些言論和本身所瞭解到的一些總結下(摘自於許令波)。
Jetty 的架構從前面的分析可知,它的全部組件都是基於 Handler 來實現,固然它也支持 JMX。可是主要的功能擴展均可以用 Handler 來實現。能夠說 Jetty 是面向 Handler 的架構,就像 Spring 是面向 Bean 的架構,iBATIS 是面向 statement 同樣,而 Tomcat 是以多級容器構建起來的,它們的架構設計必然都有一個「元神」,全部以這個「元神「構建的其它組件都是肉身。
從設計模板角度來看 Handler 的設計實際上就是一個責任鏈模式,接口類 HandlerCollection 能夠幫助開發者構建一個鏈,而另外一個接口類 ScopeHandler 能夠幫助你控制這個鏈的訪問順序。另一個用到的設計模板就是觀察者模式,用這個設計模式控制了整個 Jetty 的生命週期,只要繼承了 LifeCycle 接口,你的對象就能夠交給 Jetty 來統一管理了。因此擴展 Jetty 很是簡單,也很容易讓人理解,總體架構上的簡單也帶來了無比的好處,Jetty 能夠很容易被擴展和裁剪。
相比之下,Tomcat 要臃腫不少,Tomcat 的總體設計上很複雜,前面說了 Tomcat 的核心是它的容器的設計,從 Server 到 Service 再到 engine 等 container 容器。做爲一個應用服務器這樣設計無口厚非,容器的分層設計也是爲了更好的擴展,這是這種擴展的方式是將應用服務器的內部結構暴露給外部使用者,使得若是想擴展 Tomcat,開發人員必需要首先了解 Tomcat 的總體設計結構,而後才能知道如何按照它的規範來作擴展。這樣無形就增長了對 Tomcat 的學習成本。不只僅是容器,實際上 Tomcat 也有基於責任鏈的設計方式,像串聯 Pipeline 的 Vavle 設計也是與 Jetty 的 Handler 相似的方式。要本身實現一個 Vavle 與寫一個 Handler 的難度不相上下。表面上看,Tomcat 的功能要比 Jetty 強大,由於 Tomcat 已經幫你作了不少工做了,而 Jetty 只告訴,你能怎麼作,如何作,有你去實現。
單純比較 Tomcat 與 Jetty 的性能意義不是很大,只能說在某種使用場景下,它表現的各有差別。由於它們面向的使用場景不盡相同。從架構上來看 Tomcat 在處理少數很是繁忙的鏈接上更有優點,也就是說鏈接的生命週期若是短的話,Tomcat 的整體性能更高。
而 Jetty 恰好相反,Jetty 能夠同時處理大量鏈接並且能夠長時間保持這些鏈接。例如像一些 web 聊天應用很是適合用 Jetty 作服務器,像淘寶的 web 旺旺就是用 Jetty 做爲 Servlet 引擎。
另外因爲 Jetty 的架構很是簡單,做爲服務器它能夠按需加載組件,這樣不須要的組件能夠去掉,這樣無形能夠減小服務器自己的內存開銷,處理一次請求也是能夠減小產生的臨時對象,這樣性能也會提升。另外 Jetty 默認使用的是 NIO 技術在處理 I/O 請求上更佔優點,Tomcat 默認使用的是 BIO,在處理靜態資源時,Tomcat 的性能不如 Jetty。