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