徹底吃透Web服務器,Web容器,Web應用程序服務器與反向代理
我們知道,不同膚色的人外貌差別很大,而雙胞胎的辨識很難。有意思的是 Web 服務器/Web 容器/Web 應用程序服務器/反向代理有點像四胞胎,在網絡上經常一起出現。本文將對這四個概念進行區(qū)分。
Web 服務器概念與基本原理
Web 服務器的歷史
1989 年,互聯(lián)網之父 Berners-Lee 向其雇主 CERN 提出了一個新項目,目的是通過使用超文本系統(tǒng)來緩解科學家之間的信息交流。
該項目導致 Berners-Lee 在 1990 年編寫了兩個方案:
- 一個名為 World Wide Web 的瀏覽器。
- 網絡服務器后來被稱為 CERN httpd,它運行在 NeXTSTEP 上在 1991 年至 1994 年期間,用于通過萬維網沖浪和交換數據的早期技術的簡單性和有效性有助于將其移植到許多不同的操作系統(tǒng),并將其用于科學組織和大學,然后傳播到行業(yè)。
1994 年,Berners-Lee 決定組建萬維網聯(lián)盟(W3C),通過標準化過程來管理涉及的許多技術(HTTP,HTML 等)的進一步發(fā)展。
就是這臺服務器:
Web 服務器的主要功能是存儲,處理和傳遞網頁給客戶??蛻舳撕头掌髦g的通信使用超文本傳輸協(xié)議(HTTP)進行。
交付的頁面最常見的是 HTML 文檔,除了文本內容之外,還可能包含圖像,樣式表和腳本。
一個用戶代理,通常是 Web 瀏覽器或 Web 爬蟲,通過發(fā)起一個 HTTP 請求以獲取服務器資源,服務器根據請求返回該資源或由于某種原因響應錯誤消息。
該資源通常是服務器輔助存儲上的真實文件,但這不一定是這種情況,取決于 Web 服務器的實現方式。
雖然主要功能是提供內容,但 HTTP 的完整實現還包括從客戶端接收內容的方式。此功能用于提交 Web 表單,包括上傳文件。
許多通用 Web 服務器還支持使用 Active Server Pages(ASP),PHP 或其他腳本語言的服務器端腳本。
這意味著 Web 服務器的行為可以在單獨的文件中腳本化,而實際的服務器軟件保持不變。
通常,此函數用于動態(tài)生成 HTML 文檔(“即時”),而不是返回靜態(tài)文檔。前者主要用于從數據庫檢索或修改信息;后者通??斓枚?,并且更容易被緩存,但不能提供動態(tài)內容。
Web 服務器不僅用于為萬維網服務。它們也可以被嵌入到諸如打印機,路由器,網絡攝像機等設備中,并且僅服務于本地網絡。
然后,Web 服務器可以用于監(jiān)視或管理所討論的設備的系統(tǒng)的一部分。
這通常意味著客戶端計算機上不需要安裝其他軟件,因為只需要一個網絡瀏覽器(現在大多數操作系統(tǒng)都包含在內)。
Web 服務器工作原理
HTTP 協(xié)議基于 TCP 協(xié)議上,是一個應用層協(xié)議,用于用戶代理和 Web 服務器進行通信。
Web 服務器通常采用一問一答的方式進行工作:
- 在用戶代理上用戶發(fā)起資源請求,請求內容包括但不限于:指定資源的標識 URI,指明動作類型(GET/POST/DELETE/PUT…)
- 用戶代理解析用戶輸入 URI 并從中獲取目標域名,交由 DNS 服務器解析。如果 URI 中指定某 IP 地址,就無需這步。
- 如果與服務器的會話還沒建立,此時先建立 TCP 連接,并完成 HTTP 協(xié)商(確定雙方均可接受的處理方式,包括協(xié)議版本,是否加密,內容格式等等)。
- 用戶代理把請求內容封裝成 HTTP 數據包向服務器發(fā)送。
- 服務器接收到資源請求并以之前協(xié)商好的方式解包并處理。
- 服務器請求的資源封裝成 HTTP 數據包并返回給用戶代理。
接下來重點說說服務器端的工作原理,如下圖:
TCP 監(jiān)聽模塊:服務器監(jiān)聽某個端口(一般默認是 8080 端口,用戶可以設置其他端口),以建立和用戶代理之間的連接。一旦建立連接,用戶代理的后續(xù) HTTP 請求將不用再進入監(jiān)聽模塊。
預處理:此處主要做三件事,從 TCP 報文中獲取 HTTP 請求報文,根據和用戶代理的協(xié)商進行解密,解壓,安全處理等等。根據服務器自身的配置進行安全處理,建立會話狀態(tài)等等。
UR 路由:解析 URL 字符串和動作以確定用戶代理請求的資源,根據匹配規(guī)則(通常根據正則表達式+后綴)路由到靜態(tài)資源處理模塊或動態(tài)資源處理模塊。
靜態(tài)資源處理模塊:負責找到靜態(tài)資源,比如 HTML/JavaScript/CSS 文件/圖片/圖像,確定內容是字符流或者字節(jié)流,并確定對應 MIME。
比如 HTML 生成 MIME 為 text/html 的字符流,mpeg 視頻文件生成 MIME 為 video/mpeg 的字節(jié)流。
動態(tài)資源處理模塊:運行業(yè)務邏輯處理,動態(tài)決定返回的資源內容和類型,內容和類型的處理原則同上。
后處理:根據和用戶協(xié)商的協(xié)議進行加密,壓縮,安全處理等等。
資源輸出模塊:把處理好的內容和類型封裝成 HTTP 報文,往 TCP 連接另一頭的用戶代理發(fā)送 TCP 報文(內容是 HTTP 報文)。
主流 Web 服務器
包括 Apache、IIS 、Nginx 市場占有率如下圖:
還有比較多使用 Tomcat,Jetty,WebSphere,WebLogic,Kerstrel 等等。
Web 應用程序容器概念與基本原理
Web 應用程序容器的由來
Web 服務器的出現標志著 WWW 時代的到來,世界變得更加平面化。當初嘗到甜頭的開創(chuàng)者們開始不滿足于在互聯(lián)網上獲取靜態(tài)資源,于是出現了 CGI 腳本來動態(tài)獲取資源。
再后來網絡發(fā)展方向也是朝著增強 Web 服務器動態(tài)獲取資源的能力前進。以下是代表性的動態(tài)技術:
Web 應用程序容器的基本工作原理
一般情況下,Web 應用程序容器是以下構成體系:
注:淺藍色的模塊是實現業(yè)務程序的主要使用模塊
相對于 Web 服務器,該容器新增或強化了以下模塊:
- 分配線程池資源,容器為每個請求分配一個線程進行處理,通常采取線程池的方式高效率由 CPU 算資源。
- 封裝 Request 上下文,一個請求對應一個 Request 上下文,它主要封裝了用戶請求的主要構成。
URL,HTTP 請求頭,以及基于請求頭構建的 Session,Cookie 等對象,方便編程使用。
- 封裝 Response 上下文,一個請求對應一個 Response 上下文,主要用于向用戶代理返回資源??梢栽谄渲袑懭胼敵隽?,或者重定向,或者返回錯誤碼等等。
- URL 路由,在容器里,運行開發(fā)人員設置不同的路由匹配規(guī)則,比如讓 .HTM 返回 .HTML,也可以自定義 .xyz 返回 .HTML 資源。更加靈活的配置可以參考 Java MVC 或者 ASP.NET MVC 的配置方案。
- 動態(tài)資源處理模塊,通常在這里具體的容器和開發(fā)語言都有自己的高效開發(fā)模型,比如 Java 的 Servlet,ASP.NET 的 Web Form,MVC。
- 回收資源,這里會回收剛才的線程資源,為了線程復用,除非服務器空閑一般會將線程返回線程池。
可以看出,Web 容器本身具備了做為一個 Web 服務器的功能,事實上通常實現 Web 容器功能的服務器就是一個 Web 服務器。比如 Tomcat,IIS,Jetty。
主流 Web 容器
包括 Tomcat,IIS,Jetty 。還有比較多使用 WebSphere,WebLogic 等等。
Web 應用程序服務器概念及基本原理
在 Web 服務器發(fā)展的同一個時期,應用服務器已經存在并發(fā)展很長一段時間了。
一些公司為 Unix 開發(fā)了 Tuxedo(面向事務的中間件)、TopEnd、Encina 等產品,這些產品都是從類似 IMS 和 CICS 的主機應用管理和監(jiān)控環(huán)境衍生而來的。
大部分的這些產品都指定了“封閉的”產品專用通信協(xié)議來互連胖客戶機(“fat” client)和服務器。
在 90 年代,這些傳統(tǒng)的應用服務器產品開始嵌入 HTTP 通信功能,剛開始要利用網關來實現。不久后它們之間的界線開始變得模糊了。
同時,Web 服務器越來越成熟,可以處理更高的負載、更多的并發(fā)和擁有更好的特性;應用服務器開始添加越來越多的基于 HTTP 的通信功能。所有的這些導致了 Web 服務器與應用服務器的界限變得更窄了。
目前,“應用服務器”和“Web 服務器”之間的界限已經變得模糊不清了。但是人們還把這兩個術語區(qū)分開來,作為強調使用。
當有人說到“Web 服務器”時,你通常要把它認為是以 HTTP 為核心、Web UI 為向導的應用。
當有人說到“應用服務器”時,你可能想到“高負載、企業(yè)級特性、事務和隊列、多通道通信(HTTP 和更多的協(xié)議)”。但現在提供這些需求的基本上都是同一個產品。
下圖描述一個典型的 Web 應用服務器的結構圖:
從上圖中可以看到 Web 應用服務器包括了 Web 容器,同時內置了支撐企業(yè)應用的事務,安全,集成,通信,高可用等等功能。
極大地減少了重復開發(fā)量,保障了業(yè)務系統(tǒng)快速開發(fā)和部署,而它本身也是一個 Web 服務器。
Web 應用服務器可以選擇使用大廠的 WebLogic 和 WebSphere 這種重量級產品外。
也可以使用類似與 Tomcat、Jetty 這樣的 Web Containner 再加上第三方的框架(Spring,Hibernate等)來構建自己的 Application Server;.NET Core 平臺下可以選擇 IIS,Apache,Nginx 與 ASP.NET Core 構建。
反向代理概念與基本原理
反向代理基本概念
反向代理是代理服務器的一種。它根據客戶端的請求,從后端的服務器(如Web 服務器)上獲取資源,然后再將這些資源返回給客戶端。
與前向代理不同,前向代理作為一個媒介將互聯(lián)網上獲取的資源返回給相關聯(lián)的客戶端,而反向代理是在服務器端(如 Web 服務器)作為代理使用,而不是客戶端。
客戶端通過前向代理可以訪問很多不同的資源,反向代理是很多客戶端都通過它訪問不同后端服務器上的資源,而不需要知道這些后端服務器的存在,以為所有資源都來自于這個反向代理服務器。
互聯(lián)網中的請求發(fā)送給反向代理,反向代理把請求轉發(fā)到內網中的服務器。
反向代理的主要作用為:
- 加密和SSL加速
- 負載均衡
- 緩存靜態(tài)內容
- 壓縮
- 減速上傳
- 安全防火墻
- 外網發(fā)布
- 突破互聯(lián)網封鎖
- 解決跨域問題
反向代理基本工作原理
一個反向代理服務器的構成和處理過程如下圖:
左邊功能模塊對外網報文進行處理,右邊灰色功能模塊針對內網報文進行處理。
TCP 監(jiān)聽模塊
監(jiān)聽 TCP 請求,這里的請求是指報文內容是某應用層協(xié)議(比如 HTTP,FTP,Email 等應用層協(xié)議)的請求。
至于這里是否會單獨產生一個線程來開始處理,這個由服務器自己決定,先入消息隊列然后異步處理,這樣能極大提高代理的吞吐量和穩(wěn)定性。
匹配被代理服務器
代理服務器根據一個表(存放外網 URI 和內網服務器的對應關系,通常需人工進行設置),如果匹配到則繼續(xù)處理,否則依據外網協(xié)議返回錯誤信息,比如 HTTP 協(xié)議這返回 404。
應用負載均衡策略
如果比較大型的互聯(lián)網應用,為了整體系統(tǒng)穩(wěn)定性,解決單點問題,需要根據自定義策略合理的轉發(fā)報文給被代理服務器。簡單的策略是哈希分發(fā)或者隨機分發(fā),一般可以由用戶進行配置和選擇。
預處理
這里依據協(xié)商好的外網應用協(xié)議進行解密,安全,會話,解壓等處理。
新生成網絡報文
這里依據協(xié)商好的內網應用協(xié)議生成網絡報文,這里可能會進行加密,安全,會話,壓縮等處理。
轉發(fā)給被代理服務器
把新生成的網絡報文發(fā)送給內網服務器(可能是否 Web 服務器,FTP 服務器,郵件服務器)。
接受網絡報文
接受內網服務器反饋的網絡報文。
預處理
這里依據協(xié)商好的外網應用協(xié)議進行加密,安全,會話,壓縮等處理。
資源輸出模塊
這時生成滿足外網應用協(xié)議要求的報文,并發(fā)送到外網連接的另一端(用戶代理)。
常用的反向代理服務器
它們的名字您一定記得,分別是:Ngnix,IIS,Apache。
總結
從概念上講:
- Web 服務器是提供 WWW 服務的程序。
- Web 容器是提供給開發(fā)者的框架。
- Web 應用程序服務器內容豐富得多,既可由各廠商通常遵循一定的工業(yè)標準并自定義擴展功能而成,也可以利用開源組件輕量級拼裝打造。
- 反向代理服務器在企業(yè)級應用中表現突出,具有解決集中式安全,負載均衡等等優(yōu)點。
如今這四個概念的邊界越來模糊,看看這個表就知道了
關于 Kerstrel 是否是 Web 容器,有兩種觀點:
- 由于 Kerstrel 不提供編寫應用的框架,所以它不是容器;ASP.NET Core 才是容器,因為它提供了開發(fā)應用的框架并提供 Web 應用(MVC,Web API)運行環(huán)境。
- Kerstrel 提供了運行環(huán)境。
非常歡迎大家提出自己的有力觀點,幫助我們清晰化這個 ASP.NET Core 容器概念。
參考資料:
- https://en.wikipedia.org/wiki/Web_server
- http://www.cnblogs.com/vipyoumay/p/5853694.html
- https://zh.wikipedia.org/wiki/%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86