Jetty 目前的是一個比較被看好的 Servlet 引擎晰韵,它的架構(gòu)比較簡單吨些,也是一個可擴展性和非常靈活的應(yīng)用服務(wù)器鹏倘,它有一個基本數(shù)據(jù)模型,這個數(shù)據(jù)模型就是 Handler嘹害,所有可以被擴展的組件都可以作為一個 Handler撮竿,添加到 Server 中,Jetty 就是幫你管理這些 Handler笔呀。
基本架構(gòu)
下圖是 Jetty 的基本架構(gòu)圖幢踏,整個 Jetty 的核心組件由 Server 和 Connector 兩個組件構(gòu)成。
Server 組件是基于 Handler 容器工作的许师,它類似與 Tomcat 的 Container 容器
Connector房蝉,它負責(zé)接受客戶端的連接請求,并將請求分配給一個處理隊列去執(zhí)行
Jetty 的主要組件的類圖
從上圖可以看出整個 Jetty 的核心是圍繞著 Server 類來構(gòu)建微渠,Server 類繼承了 Handler搭幻,關(guān)聯(lián)了 Connector 和 Container。Container 是管理 Mbean 的容器逞盆。Jetty 的 Server 的擴展主要是實現(xiàn)一個個 Handler 并將 Handler 加到 Server 中檀蹋,Server 中提供了調(diào)用這些 Handler 的訪問規(guī)則。
整個 Jetty 的所有組件的生命周期管理是基于觀察者模板設(shè)計云芦,它和 Tomcat 的管理是類似的俯逾。下面是 LifeCycle 的類關(guān)系圖
每個組件都會持有一個觀察者(在這里是 Listener 類贸桶,這個類通常對應(yīng)到觀察者模式中常用的 Observer 角色)集合,當 start桌肴、fail 或 stop 等事件觸發(fā)時刨啸,這些 Listener 將會被調(diào)用,這是最簡單的一種設(shè)計方式识脆,相比 Tomcat 的 LifeCycle 要簡單的多设联。
Jetty 主要提供了兩種 Handler 類型,
一種是 HandlerWrapper灼捂,它可以將一個 Handler 委托給另外一個類去執(zhí)行离例,如我們要將一個 Handler 加到 Jetty 中,那么就必須將這個 Handler 委托給 Server 去調(diào)用悉稠。配合 ScopeHandler 類我們可以攔截 Handler 的執(zhí)行宫蛆,在調(diào)用 Handler 之前或之后,可以做一些另外的事情的猛,類似于 Tomcat 中的 Valve耀盗;
另外一個 Handler 類型是 HandlerCollection,這個 Handler 類可以將多個 Handler 組裝在一起卦尊,構(gòu)成一個 Handler 鏈叛拷,方便我們做擴展。
Jetty 的啟動過程
Jetty 的入口是 Server 類岂却,Server 類啟動完成了忿薇,就代表 Jetty 能為你提供服務(wù)了。它到底能提供哪些服務(wù)躏哩,就要看 Server 類啟動時都調(diào)用了其它組件的 start 方法署浩。從 Jetty 的配置文件我們可以發(fā)現(xiàn),配置 Jetty 的過程就是將那些類配置到 Server 的過程扫尺。下面是 Jetty 的啟動時序圖:
因為 Jetty 中所有的組件都會繼承 LifeCycle筋栋,所以 Server 的 start 方法調(diào)用就會調(diào)用所有已經(jīng)注冊到 Server 的組件,Server 啟動其它組件的順序是:首先啟動設(shè)置到 Server 的 Handler正驻,通常這個 Handler 會有很多子 Handler弊攘,這些 Handler 將組成一個 Handler 鏈。Server 會依次啟動這個鏈上的所有 Handler拨拓。接著會啟動注冊在 Server 上 JMX 的 Mbean肴颊,讓 Mbean 也一起工作起來,最后會啟動 Connector渣磷,打開端口婿着,接受客戶端請求,啟動邏輯非常簡單。
建立連接的時序圖
Jetty 創(chuàng)建接受連接環(huán)境需要三個步驟:
- 創(chuàng)建一個隊列線程池竟宋,用于處理每個建立連接產(chǎn)生的任務(wù)提完,這個線程池可以由用戶來指定,這個和 Tomcat 是類似的丘侠。
- 創(chuàng)建 ServerSocket徒欣,用于準備接受客戶端的 socket 請求,以及客戶端用來包裝這個 socket 的一些輔助類蜗字。
- 創(chuàng)建一個或多個監(jiān)聽線程打肝,用來監(jiān)聽訪問端口是否有連接進來。
處理連接時序圖
Accetptor 線程將會為這個請求創(chuàng)建 ConnectorEndPoint挪捕。HttpConnection 用來表示這個連接是一個 HTTP 協(xié)議的連接粗梭,它會創(chuàng)建 HttpParse 類解析 HTTP 協(xié)議,并且會創(chuàng)建符合 HTTP 協(xié)議的 Request 和 Response 對象级零。接下去就是將這個線程交給隊列線程池去執(zhí)行了断医。
基于 NIO 方式工作
前面所描述的 Jetty 建立客戶端連接到處理客戶端的連接都是基于 BIO 的方式,它也支持另外一種 NIO 的處理方式奏纪,其中 Jetty 的默認 connector 就是 NIO 方式鉴嗤。
Jetty 的 NIO 處理方式和 Tomcat 的幾乎一樣,唯一不同的地方是在如何把監(jiān)聽到事件分配給對應(yīng)的連接的處理方式序调。從測試效果來看 Jetty 的 NIO 處理方式更加高效醉锅。下面是 Jetty 的 NIO 處理時序圖:
執(zhí)行原理
核心類:org.mortbay.jetty.Server
核心接口:org.mortbay.component.LifeCycle
核心線程池封裝:org.mortbay.thread.QueuedThreadPool
核心IO處理類:org.mortbay.jetty.nio.SelectChannelConnector
核心Servlet處理類:org.mortbay.jetty.servlet.ServletHandler