|
1.1 Web server
Web server 用來解析HTTP協(xié)議。當(dāng)web服務(wù)器接收到一個HTTP請求時,會返回一個HTTP響應(yīng),例如送回一個HTML頁面。為了處理一個請求,web服務(wù)器可以響應(yīng)一個靜態(tài)頁面或者圖片。進行頁面跳轉(zhuǎn),或者把動態(tài)響應(yīng)的產(chǎn)生委托給一些其它的程序完成,比如CGI, JSP, Servlets, ASP.NET,php腳本。
當(dāng)用戶訪問一個網(wǎng)站時,首先用戶通過查詢DNS服務(wù)器,得到該域名對應(yīng)的IP地址,然后使用這個IP地址來進行訪問。用戶的請求是一個url地址,在web服務(wù)器端,url地址對應(yīng)web服務(wù)器上的文件系統(tǒng)中的某個網(wǎng)站文件的路徑。Web server的作用就是解析HTTP協(xié)議,通過用戶發(fā)來請求的url地址從web服務(wù)器的文件系統(tǒng)中找到用戶需要的HTML頁面、靜態(tài)文件,然后返回給用戶。如果用戶訪問的是動態(tài)頁面,則將請求轉(zhuǎn)發(fā)到應(yīng)用服務(wù)器來執(zhí)行。
1.1.1 FastCGI
1.1.1.1 CGI
CGI(Common Gateway Interface) ,指運行在服務(wù)器上,提供同客戶端HTML頁面的接口。多數(shù)CGI程序被用來解釋處理來自表單的輸入信息,并在服務(wù)器產(chǎn)生相應(yīng)的處理,或?qū)⑾鄳?yīng)的信息反饋給瀏覽器。
1.1.1.2 FastCGI
FastCGI是語言無關(guān)的、可伸縮架構(gòu)的CGI開放擴展,其主要行為是將CGI解釋器進程保持在內(nèi)存中并因此獲得較高的性能。而CGI解釋器的反復(fù)加載是CGI性能低下的主要原因。如果CGI解釋器保持在內(nèi)存中并接受FastCGI進程管理器的調(diào)度,則可以提供良好的性能、伸縮性能和Fail-over特性等。
FastCGI的工作原理如下:
(1) FastCGI進程管理器自身初始化,啟動多個CGI解釋器進程(多php-cgi進程)并等待來自web server的連接。啟動php-cgi FastCGI進程時,可以配置以TCP和UNIX套接字兩種方式啟動。
(2) 當(dāng)客戶端請求到達(dá)web服務(wù)器時,web服務(wù)器將請求采用TCP協(xié)議或者UNIX套接字方式轉(zhuǎn)發(fā)到FastCGI主進程,F(xiàn)astCGI主進程選擇并連接到一個CGI解釋器(子進程)。Web服務(wù)器將CGI環(huán)境變量和標(biāo)準(zhǔn)輸入法發(fā)送到FastCGI子進程php-cgi。
(3) FastCGI子進程完成處理后,將標(biāo)準(zhǔn)輸出和錯誤信息從同一連接返回web服務(wù)器。當(dāng)FastCGI子進程關(guān)閉連接時,請求便告知處理完成。FastCGI子進程接著等待并處理來自FastCGI進程管理器的下一個連接。
FastCGI的優(yōu)點如下:
(1) 穩(wěn)定性。FastCGI是以獨立的進程池運行CGI,單獨一個進程死掉,系統(tǒng)可以輕松的丟棄,然后重新分配新的進程。
(2) 安全性。FastCGI和宿主Server完全獨立,F(xiàn)astCGI如果down了,不會影響到Server的性能。
(3) 高性能。FastCGI和宿主Server分開,大負(fù)荷的IO處理留給web server進行,比如大量圖片、CSS等靜態(tài)文件的IO操作,完全由web server處理完成。[2]
1.1.1.3 Lighttpd服務(wù)器
Lighttpd是一個具有非常低的內(nèi)存開銷,CPU占用率低,性能好的輕量級Web Server。支持FastCGI, CGI, 輸出壓縮,URL重寫,Alias等重要功能。
Lighttpd使用FastCGI方式運行php。
1.1.1.4 Apache服務(wù)器
Apache是世界上使用最多的web服務(wù)器,市場占有率50%以上。Apache支持SSL技術(shù),支持多個虛擬主機。Apache是以進程為基礎(chǔ)結(jié)構(gòu),進程相對線程消耗更多系統(tǒng)資源。相對Lighttpd和Nginx,Apache是一款重量級的web服務(wù)器。總體來講,Apache web 服務(wù)器具有以下特性:
(1) 支持HTTP1.1通信協(xié)議。
(2) 支持通用網(wǎng)關(guān)接口。
(3) 支持基于ip、域名、端口的虛擬主機。
(4) 支持服務(wù)器端包含指令(ssl)。
(5) 支持FastCGI。
(6) 支持url重寫。
1.1.1.5 Nginx服務(wù)器
Nginx是俄羅斯人Igor Sysoev編寫的一款高性能HTTP和反向代理服務(wù)器。Nginx能夠選擇高效的epoll(Linux 2.6內(nèi)核)、kqueue(FreeBSD)、eventport(Solaris 10)作為網(wǎng)絡(luò)I/O模型,在高連接并發(fā)的情況下,Nginx是Apache服務(wù)器很好的替代者,因為在同樣并發(fā)連接的情況下,Nginx相對Apache占用更少的系統(tǒng)資源。[3]
1.1.1.6 Lighttpd、Apache、Nginx比較
Lighttpd是一個單進程模型的web server,內(nèi)存使用量很小。Nginx在內(nèi)存分配方面,表現(xiàn)良好。它使用多線程來處理請求,這使得多個線程之間可以共享內(nèi)存資源,從而使它的內(nèi)存使用量大大減少。此外,Nginx使用分階段的內(nèi)存分配策略,按需分配,及時釋放,所以總體占用內(nèi)存很小。可以支持較大的并發(fā)連接數(shù)。Apache在運行時使用較大的內(nèi)存,Apache是多進程模型。Apache使用基于內(nèi)存池策略的內(nèi)存管理方法,這種方法使得Apache在運行開始時便一次性申請大片內(nèi)存作為內(nèi)存池,這樣在隨后需要的時候只在內(nèi)存池中直接獲取,不需要再分配。顯然,Apache很占用內(nèi)存。根據(jù)國內(nèi)金山技術(shù)經(jīng)理、系統(tǒng)架構(gòu)師張宴給出的統(tǒng)計信息,2009年的web server使用情況如表4-1-1-5所示。
表4-1-1-5 各種web server市場占有率排名
Web server | 2008.12使用數(shù) | 占有率 | 2009.01使用數(shù) | 占有率 | 占有率變化 |
Apache | 95678052 | 51.24% | 96947298 | 52.26% | +1.02% |
IIS | 63126940 | 33.81% | 61038371 | 32.91% | -0.90% |
10455103 | 5.60% | 9868819 | 5.32% | -0.28 | |
Nginx | 3354329 | 1.80% | 3462551 | 1.87% | +0.07% |
Lighttpd | 3046333 | 1.63% | 2989416 | 1.61% | -0.02% |
1.2 緩存
在計算機系統(tǒng)中,緩存有很多種。比如CPU內(nèi)部的一級緩存、二級緩存。文件系統(tǒng)的緩存,磁盤的緩存。在大型網(wǎng)站的后臺部署過程中,也靈活運用了各級緩存。主要有客戶端的瀏覽器緩存,服務(wù)器端的web server自身緩存,代理緩存,分布式緩存,數(shù)據(jù)庫自身的緩存等。本節(jié)主要分析一下代理緩存和分布式緩存。
1.2.1 代理緩存
在網(wǎng)站后臺架構(gòu)中,代理緩存主要部署在web server之上,當(dāng)用戶對網(wǎng)站后臺發(fā)起連接請求時,用戶請求先到代理緩存中去查找,如果命中,則將請求返回給用戶,如果沒有命中,則代理緩存將請求發(fā)到web server,然后web sever將請求復(fù)制一份到代理緩存中,同時把請求返回給客戶。
常用的代理緩存有varnish和squid。如圖4-2-1所示。
圖4-2-1 代理緩存(黃色部分)
1.2.1.1 Squid
Squid是一個高性能的代理緩存服務(wù)器,可以用來加快瀏覽網(wǎng)頁的速度,提高客戶機的訪問命中率。Squid不僅支持HTTP協(xié)議,還支持FTP、SSL、WAIS等協(xié)議。Squid用一個單獨的、非模塊化的、I/O驅(qū)動的進程來處理所有的客戶端請求。
Squid的原理如下:
(1) 每一臺Squid代理服務(wù)器上存有若干個顆磁盤。每顆磁盤又分割成多個分區(qū),每一個分區(qū)又可建立很多目錄,目錄下存放著具體的文件(object)。
(2) Squid通過查詢表的方式來定位某個資源的位置。所查詢的表有兩種,一種是Hash table,一種是Digest table。Hash table記錄著所有Digest table表信息,所以Hash table可以稱之為目錄或者提綱。而Digest table記錄了磁盤上每個分區(qū)、每個目錄里存放的緩存摘要,所以Digest table可以稱之為摘要或者索引。所以,Squid接到請求后先查詢Hashtable,根據(jù)Hash table所指向的Digest table,再查詢所需要的文件。
(3) Squid服務(wù)器存在兩種工作關(guān)系,一種為Child-Parent,當(dāng)Child Squid Server沒有用戶需要的數(shù)據(jù)時,就向Parent squid Server發(fā)送請求,并持續(xù)等待,直到Parent Squid Server回應(yīng)為止;另一種為Sibling,當(dāng)本地Squid Server沒有用戶請求的數(shù)據(jù)時,會向Sibling Server發(fā)送請求,如果Sibling Server沒有資料則會向上級Sibling或者InterNET發(fā)送數(shù)據(jù)請求。
所以,綜上所述,Squid運行模式如下:
當(dāng)Squid Server沒有資料時,先向Sibling的Squid Server查詢數(shù)據(jù),如果Sibling沒有,則跳過它直接向Parent查詢,直到Parent提供資料為止(如果Parent沒有資料,則到后端的web server上獲取,當(dāng)獲取到數(shù)據(jù)后返回給用戶的同時,保留一份在自身的緩存中)。如果不存在Parent,則Squid Server自身到后端的web server上獲取數(shù)據(jù),當(dāng)獲取到數(shù)據(jù)后返回給用戶的同時,保留一份在自身的緩存中。如果還是不能得到數(shù)據(jù),則向用戶端回復(fù)不能得到數(shù)據(jù)。
1.2.1.2 Varnish
Varnish是一款高性能的開源HTTP加速器,挪威最大的在線報紙Verdens Gang使用3臺Varnish代替了原來的12臺Squid,性能比以前更好。
Varnish的作者Poul-Henning Kamp是FreeBSD內(nèi)核開發(fā)者之一,他認(rèn)為現(xiàn)在的計算機比起1975年已經(jīng)復(fù)雜很多。在1975年時,存儲媒介只有兩種:內(nèi)存與硬盤。但現(xiàn)在計算機系統(tǒng)的內(nèi)存除了主存外,還包括了CPU內(nèi)的L1/L2/L3等cache。因此Squid Cache自行處理物件替換的架構(gòu)不可能得知這些情況而做到最佳化,但操作系統(tǒng)可以。所以這部分的工作應(yīng)該交給操作系統(tǒng)處理,這就是Varnish cache設(shè)計架構(gòu)[4]。Varnish將所有的HTTP object存于一個單獨的大文件中,該文件在工作進程初始化的時候,將其整個映射到內(nèi)存中。這樣Varnish在該塊內(nèi)存中實現(xiàn)一個簡單的文件系統(tǒng),具有分配、釋放、修剪、合并內(nèi)存等功能。
Varnish文件緩存的工作流程:
Varnish與一般服務(wù)器軟件類似,分為master進程和child進程。其中master進程負(fù)責(zé)管理,child進程負(fù)責(zé)cache工作。Master進程讀入命令,進行一些初始化,然后fork并監(jiān)控child進程。Child進程分配若干線程進行工作,主要包括管理線程和worker線程。如圖4-2-1-2所示。
圖4-2-1-2
主進程fork子進程,主進程等待子進程的信號,子進程退出后,主進程重新啟動子進程,子進程生成若干線程:
(1) Accept線程:接受請求,將請求掛在overflow隊列上。
(2) Work線程:有多個,負(fù)責(zé)從overflow隊列上摘除請求,對請求進行處理,直到完成,然后處理下一個請求。
(3) Epoll線程:一個請求處理稱為一個session,在session周期內(nèi),處理完請求后,會交給Epoll處理,監(jiān)聽是否還在事件發(fā)生。
(4) Expire線程:對于緩存的object,根據(jù)過期時間,組織成二叉堆,該線程周期檢查該堆得根,處理過期的文件。對過期的數(shù)據(jù)進行刪除或重取操作。
Varnish分配緩存機制:
根據(jù)所讀到的object大小,創(chuàng)建相應(yīng)大小的緩存文件。為了讀寫方便,程序?qū)⒚總€object的大小,轉(zhuǎn)變?yōu)樽罱咏浯笮〉膬?nèi)存頁面倍數(shù)。然后從現(xiàn)有的空閑存儲結(jié)構(gòu)體中查找,找到最合適的大小的空閑存儲塊,分配給它。如果空閑塊沒有用完,則把多余的內(nèi)存再組成一個空閑存儲塊,掛接到管理結(jié)構(gòu)體上。如果緩存已滿,則根據(jù)LRU算法,把舊的object釋放掉。
Varnish釋放緩存機制:
Expire線程負(fù)責(zé)檢測緩存中所有object的生存期(TTL)。如果超過了設(shè)定的TTL,該object沒有被訪問,則刪除該object,并釋放內(nèi)存。釋放的過程會考慮內(nèi)存的合并等操作。
1.2.2 分布式緩存
1.2.2.1 Memcached
Memcached是以LiveJournal旗下Danga Interactive公司的Brad Fitzpatric為首開發(fā)的一款軟件。現(xiàn)在Memcached已成為mixi、hatena、Facebook等公司提高web應(yīng)用擴展性的重要緩存軟件。許多web應(yīng)用都將數(shù)據(jù)保存到RDBMS中,應(yīng)用服務(wù)器從中讀取數(shù)據(jù)并返回給用戶。但隨著數(shù)據(jù)量的增大,訪問的集中性,讀寫比例的增大,會使RDBMS增加其系統(tǒng)開銷,相應(yīng)速度下降,網(wǎng)絡(luò)延遲增大。Memcached通過緩存數(shù)據(jù)庫查詢結(jié)果,減少數(shù)據(jù)庫讀的訪問次數(shù),提高動態(tài)網(wǎng)站的響應(yīng)速度。此外,電子商務(wù)網(wǎng)站的客戶端cookie和服務(wù)器端session機制也可以利用Memcached解決,比如典型的購物車跟蹤記錄訪問行為、購買問題等。也可以將其信息記錄在后端的Memcached中。典型的應(yīng)用如圖4-2-2-1-1所示。
圖 4-2-2-1-1
如圖所示,當(dāng)用戶第一次訪問數(shù)據(jù)庫時,應(yīng)用服務(wù)器從數(shù)據(jù)庫中查詢數(shù)據(jù)返回給用戶,并且在memcached中存儲一份數(shù)據(jù)。當(dāng)?shù)诙危?a href=/pingce/yingyong/ target=_blank class=infotextkey>應(yīng)用服務(wù)器需要從數(shù)據(jù)庫中查詢數(shù)據(jù)時,首先從memcached查詢數(shù)據(jù),如果有則得到數(shù)據(jù),返回給用戶,如果沒有,則再從數(shù)據(jù)庫中查找數(shù)據(jù)。返回給用戶,并拷貝一份數(shù)據(jù)到memcached中。
Memcached默認(rèn)情況下采用名為Slab Allocator的機制分配、管理內(nèi)存。Slab Allocator的基本原理是按照預(yù)先規(guī)定的大小,將分配的內(nèi)存分割成特定長度的塊,以完全解決內(nèi)存碎片問題。
Slab Allocator原理,將分配的內(nèi)存分割成各種尺寸的塊(chunk),并將尺寸相同的塊分成組(chunk的集合)。如圖4-2-2-1-2所示。
圖 4-2-2-1-2
如圖所示,memcached根據(jù)收到的數(shù)據(jù)的大小,選擇最適合數(shù)據(jù)大小的slab。Memcached中保存著slab內(nèi)空閑chunk的列表,根據(jù)該列表選擇chunk,然后將數(shù)據(jù)緩存在其中。如圖4-2-2-1-3所示。
圖4-2-2-1-3
同squid、varnish一樣,memcached同樣使用LRU機制來分配內(nèi)存,刪除最近最少未使用的數(shù)據(jù)。
1.3 本文小結(jié)
本章主要分析了FastCGI的運行機制,簡單介紹了三種常用的web server —— Lighttpd、Apache、Nginx,對三款常用web server進行了對比。然后又分別介紹了代理緩存Squid和Varnish。最后簡單分析了分布式緩存Memcached。總體而言,這些緩存的應(yīng)用可以極大加快網(wǎng)站的訪問速度。提升用戶體驗。緩存的應(yīng)用,在高可用的大型網(wǎng)站中,處處可見。
it知識庫:大型網(wǎng)站后臺架構(gòu)的Web Server與緩存,轉(zhuǎn)載需保留來源!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。