咱們直到Servlet是處理每一個HTTP請求的最小單元,而這些Servlet又被web容器所管理,不一樣的web容器有不一樣的特性和應用特色,好比常見的web 容器Tomcat和Jetty。前端
(另外咱們還知道一些高性能web框架好比netty,和tomcat的區別是什麼呢?web
本文旨在探究web容器組織管理servlet的機制,和web容器怎麼去處理不一樣的線程請求。設計模式
Tomcat的系統結構:tomcat
Tomcat是一系列層級容器組成的web容器,其中最頂層的容器是Server,表明着整個服務器,從上圖中能夠看出,一個Server能夠包含至少一個Service,用於具體提供服務;服務器
Service容器包含的來個主要組件是Connetctor和Container;這是Tomcat最重要的兩個組件:網絡
這種設計模式是網絡I/O常見的設計,爲了可以併發處理大量鏈接,通常會採起一個線程方式監聽客戶端請求;另外一個線程採用NIO的形式select已經接收到數據的channel信道,處理請求,這樣的形式;多線程
Tomcat7提供了三種Connector:Java Blocking Connector,Java Nio Blocking Connector,APR/native Connector。架構
在容器等級中的最底層就是Context容器,負責直接管理Servlet,一個Context對應一個Web工程;併發
Tomcat的啓動邏輯是基於觀察者設計的,先來看看啓動的時序圖:app
容器的配置屬性由web.xml制定;
Tomcat處理一次http請求的時序圖:
有了一個總體的瞭解後,讓咱們再來看看Tomcat是如何分發請求,以及處理多用戶同時請求和管理多級容器的;
Tomcat中使用Connector處理多線程的鏈接請求:
先看看Connector的主要類圖:其中處理Socket的是HttpProcessor
容器的整體設計: Container是容器的父接口,全部子容器都必須實現這個接口,其中用到的設計模式是責任鏈模式
Engine -> Host -> Context -> Wrapper 這四個容器是個分別包含的父子關係(參見上幾個圖)
四個容器的關係類圖:
Jetty相較於Tomcat更加輕便,雖然架構更加簡單,可是看起來可並不輕鬆。Spring是設計初衷是用來管理應用中的實例Bean,於是是基於Bean的架構;Jetty則更傾向於流程和組件的管理,採用了基於handler的架構。handler的嵌套和鏈式結構,LifeCycle和doStart、doHandler模式無不印證了這點
Jetty基礎架構:
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。