2023大型網(wǎng)站技術(shù)架構(gòu)核心原理與案例分析_第1頁
2023大型網(wǎng)站技術(shù)架構(gòu)核心原理與案例分析_第2頁
2023大型網(wǎng)站技術(shù)架構(gòu)核心原理與案例分析_第3頁
2023大型網(wǎng)站技術(shù)架構(gòu)核心原理與案例分析_第4頁
2023大型網(wǎng)站技術(shù)架構(gòu)核心原理與案例分析_第5頁
已閱讀5頁,還剩156頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)

文檔簡介

大型網(wǎng)站技術(shù)架構(gòu)核心原理與案例分析第1篇 概 述2 大型網(wǎng)站架構(gòu)模式3 大型網(wǎng)站核心架構(gòu)要素第2篇 架 構(gòu)5 萬無一失:網(wǎng)站的高可用架構(gòu)6 永無止境:網(wǎng)站的伸縮性架構(gòu)7 隨需應(yīng)變:網(wǎng)站的可擴展架構(gòu)8 固若金湯:網(wǎng)站的安全架構(gòu)第3篇 案 例10 維基百科的高性能架構(gòu)設(shè)計分析11 海量分布式存儲系統(tǒng)Doris的高可用架構(gòu)設(shè)計分析12 網(wǎng)購秒殺系統(tǒng)架構(gòu)設(shè)計案例分析13 大型網(wǎng)站典型故障案例分析第4篇 架構(gòu)師15 網(wǎng)站架構(gòu)師職場攻略16 漫話網(wǎng)站架構(gòu)師附錄A 大型網(wǎng)站架構(gòu)技術(shù)一覽附錄B 開發(fā)技術(shù)發(fā)展歷程后 記第1篇概述大型網(wǎng)站架構(gòu)演化如果把上世紀(jì)90年代初CERN正式發(fā)布Web標(biāo)準(zhǔn)和第一個Web服務(wù)的出現(xiàn)當(dāng)做互聯(lián)網(wǎng)站的開始,那么互聯(lián)網(wǎng)站的發(fā)展只經(jīng)歷了短短20多年的時間。在20多年的時間里,互聯(lián)網(wǎng)的世界發(fā)生了巨大變化,今天,全球有近一半的人口使用互聯(lián)網(wǎng),人們的生活因為互聯(lián)網(wǎng)而產(chǎn)生了巨大改變。從信息檢索到即時通信,從電子購物到文化娛樂,互聯(lián)網(wǎng)滲透到生活的每個角落,而且這種趨勢還在加速。因為互聯(lián)網(wǎng),我們的世界正變得越來越小。同時我們也看到,在互聯(lián)網(wǎng)跨越式發(fā)展的進程中,在電子商務(wù)火熱的市場背后卻是不堪重負(fù)的網(wǎng)站架構(gòu),某些B2C網(wǎng)站逢促銷必宕機幾乎成為一種規(guī)律,而鐵道部電子客票官方購票網(wǎng)站的頻繁故障和操作延遲更將這一現(xiàn)象演繹得淋漓盡致。一邊是企業(yè)在網(wǎng)站技術(shù)上的大量投入,一邊卻是網(wǎng)站在關(guān)鍵時刻的頻繁宕機;一邊是工程師夜以繼日地加班工作,一邊卻是網(wǎng)站故障頻發(fā)新功能上線緩慢;一邊是互聯(lián)網(wǎng)業(yè)務(wù)快速發(fā)展多領(lǐng)域挑戰(zhàn)傳統(tǒng)行業(yè),一邊卻是網(wǎng)站安全漏洞頻發(fā)讓網(wǎng)民膽戰(zhàn)心驚怨聲載道。如何打造一個高可用、高性能、易擴展、可伸縮且安全的網(wǎng)站?如何讓網(wǎng)站隨應(yīng)用所需靈活變動,即使是山寨他人的產(chǎn)品,也可以山寨的更高、更快、更強,一年時間用戶數(shù)從零過億呢?大型網(wǎng)站軟件系統(tǒng)的特點與傳統(tǒng)企業(yè)應(yīng)用系統(tǒng)相比,大型互聯(lián)網(wǎng)應(yīng)用系統(tǒng)有以下特點。高并發(fā),大流量:需要面對高并發(fā)用戶,大流量訪問。Google日均PV數(shù)35億,日均IP訪問數(shù)3億;騰訊QQ的最大在線用戶數(shù)1.4億(2011年數(shù)據(jù))2012年“雙十一”天交易額超過191億,活動開始第一分鐘獨立訪問用戶達1000萬。高可用:系統(tǒng)7×24小時不間斷服務(wù)。大型互聯(lián)網(wǎng)站的宕機事件通常會成為新聞焦點,例如2010年百度域名被黑客劫持導(dǎo)致不能訪問,成為重大新聞熱點。海量數(shù)據(jù):需要存儲、管理海量數(shù)據(jù),需要使用大量服務(wù)器。Facebook每周上傳的照片數(shù)目接近10億,百度收錄的網(wǎng)頁數(shù)目有數(shù)百億,Google有近百萬臺服務(wù)器為全球用戶提供服務(wù)。用戶分布廣泛,網(wǎng)絡(luò)情況復(fù)雜:許多大型互聯(lián)網(wǎng)都是為全球用戶提供服務(wù)的,用戶分布范圍廣,各地網(wǎng)絡(luò)情況千差萬別。在國內(nèi),還有各個運營商網(wǎng)絡(luò)互通難的問題。而中美光纜的數(shù)次故障,也讓一些對國外用戶依賴較大的網(wǎng)站不得不考慮在海外建立數(shù)據(jù)中心。安全環(huán)境惡劣:由于互聯(lián)網(wǎng)的開放性,使得互聯(lián)網(wǎng)站更容易受到攻擊,大型網(wǎng)站幾乎每天都會被黑客攻擊。2011年國內(nèi)多個重要網(wǎng)站泄露用戶密碼,讓普通用戶也直面一次互聯(lián)網(wǎng)安全問題。需求快速變更,發(fā)布頻繁:和傳統(tǒng)軟件的版本發(fā)布頻率不同,互聯(lián)網(wǎng)產(chǎn)品為快速適應(yīng)市場,滿足用戶需求,其產(chǎn)品發(fā)布頻率是極高的。Office的產(chǎn)品版本以年為單位發(fā)布,而一一天會發(fā)布幾十次。漸進式發(fā)展:與傳統(tǒng)軟件產(chǎn)品或企業(yè)應(yīng)用系統(tǒng)一開始就規(guī)劃好全部的功能和非功能需求不同,幾乎所有的大型互聯(lián)網(wǎng)站都是從一個小網(wǎng)站開始,漸進地發(fā)展起來的。Facebook是伯克扎克同學(xué)在哈佛大學(xué)的宿舍里開發(fā)的;Google的第一臺服務(wù)器部署在斯坦福大學(xué)的實驗室里;阿里巴巴則是在馬云家的客廳里誕生的。好的互聯(lián)網(wǎng)產(chǎn)品都是慢慢運營出來的,不是一開始就開發(fā)好的,這也正好與網(wǎng)站架構(gòu)的發(fā)展演化過程對應(yīng)。大型網(wǎng)站架構(gòu)演化發(fā)展歷程大型網(wǎng)站的技術(shù)挑戰(zhàn)主要來自于龐大的用戶,高并發(fā)的訪問和海量的數(shù)據(jù),任何簡單的業(yè)務(wù)一旦需要處理數(shù)以P計的數(shù)據(jù)和面對數(shù)以億計的用戶,問題就會變得很棘手。大型網(wǎng)站架構(gòu)主要就是解決這類問題。初始階段的網(wǎng)站架構(gòu)大型網(wǎng)站都是從小型網(wǎng)站發(fā)展而來,網(wǎng)站架構(gòu)也是一樣,是從小型網(wǎng)站架構(gòu)逐步演化而如圖1.1所示。圖1.1 初始階段的網(wǎng)站架構(gòu)應(yīng)用程序、數(shù)據(jù)庫、文件等所有的資源都在一臺服務(wù)器上。通常服務(wù)器操作系統(tǒng)使用Linux,應(yīng)用程序使用PHP開發(fā),然后部署在Apache上,數(shù)據(jù)庫使用MySQL,匯集各種免費開源軟件及一臺廉價服務(wù)器就可以開始網(wǎng)站的發(fā)展之路了。應(yīng)用服務(wù)和數(shù)據(jù)服務(wù)分離隨著網(wǎng)站業(yè)務(wù)的發(fā)展,一臺服務(wù)器逐漸不能滿足需求:越來越多的用戶訪問導(dǎo)致性能越來越差,越來越多的數(shù)據(jù)導(dǎo)致存儲空間不足。這時就需要將應(yīng)用和數(shù)據(jù)分離。應(yīng)用和數(shù)據(jù)分離后整個網(wǎng)站使用三臺服務(wù)器:應(yīng)用服務(wù)器、文件服務(wù)器和數(shù)據(jù)庫服務(wù)器,如圖1.2所示。這三臺服務(wù)器對硬件資源的要求各不相同,應(yīng)用服務(wù)器需要處理大量的業(yè)務(wù)邏輯,因此需要更快更強大的CPU;數(shù)據(jù)庫服務(wù)器需要快速磁盤檢索和數(shù)據(jù)緩存,因此需要更快的硬盤和更大的內(nèi)存;文件服務(wù)器需要存儲大量用戶上傳的文件,因此需要更大的硬盤。圖1.2應(yīng)用服務(wù)和數(shù)據(jù)服務(wù)分離應(yīng)用和數(shù)據(jù)分離后,不同特性的服務(wù)器承擔(dān)不同的服務(wù)角色,網(wǎng)站的并發(fā)處理能力和數(shù)據(jù)存儲空間得到了很大改善,支持網(wǎng)站業(yè)務(wù)進一步發(fā)展。但是隨著用戶逐漸增多,網(wǎng)站又一次面臨挑戰(zhàn):數(shù)據(jù)庫壓力太大導(dǎo)致訪問延遲,進而影響整個網(wǎng)站的性能,用戶體驗受到影響。這時需要對網(wǎng)站架構(gòu)進一步優(yōu)化。使用緩存改善網(wǎng)站性能80%的業(yè)務(wù)訪問集中在20%的數(shù)占總用戶數(shù)目的一小部分。既然大部分的業(yè)務(wù)訪問集中在一小部分?jǐn)?shù)據(jù)上,那么如果把這一小部分?jǐn)?shù)據(jù)緩存在內(nèi)存寫入性能了呢?網(wǎng)站使用的緩存可以分為兩種:緩存在應(yīng)用服務(wù)器上的本地緩存和緩存在專門的分布式緩存服務(wù)器上的遠程緩存。本地緩存的訪問速度更快一些,但是受應(yīng)用服務(wù)器內(nèi)存限制,其緩存數(shù)據(jù)量有限,而且會出現(xiàn)和應(yīng)用程序爭用內(nèi)存的情況。遠程分布式緩存可以使用集群的方式,部署大內(nèi)存的服務(wù)器作為專門的緩存服務(wù)器,可以在理論上做到不受內(nèi)存容量限制的緩存服務(wù),如圖1.3所示。圖1.3 網(wǎng)站使用緩存使用緩存后,數(shù)據(jù)訪問壓力得到有效緩解,但是單一應(yīng)用服務(wù)器能夠處理的請求連接有限,在網(wǎng)站訪問高峰期,應(yīng)用服務(wù)器成為整個網(wǎng)站的瓶頸。使用應(yīng)用服務(wù)器集群改善網(wǎng)站的并發(fā)處理能力使用集群是網(wǎng)站解決高并發(fā)、海量數(shù)據(jù)問題的常用手段。當(dāng)一臺服務(wù)器的處理能力、存儲空間不足時,不要企圖去換更強大的服務(wù)器,對大型網(wǎng)站而言,不管多么強大的服務(wù)器,都滿足不了網(wǎng)站持續(xù)增長的業(yè)務(wù)需求。這種情況下,更恰當(dāng)?shù)淖龇ㄊ窃黾右慌_服務(wù)器分擔(dān)原有服務(wù)器的訪問及存儲壓力。對網(wǎng)站架構(gòu)而言,只要能通過增加一臺服務(wù)器的方式改善負(fù)載壓力,就可以以同樣的方式持續(xù)增加服務(wù)器不斷改善系統(tǒng)性能,從而實現(xiàn)系統(tǒng)的可伸縮性。應(yīng)用服務(wù)器實現(xiàn)集群是網(wǎng)站可伸縮集群架構(gòu)設(shè)計中較為簡單成熟的一種,如圖1.4所示。圖1.4應(yīng)用服務(wù)器集群部署通過負(fù)載均衡調(diào)度服務(wù)器,可將來自用戶瀏覽器的訪問請求分發(fā)到應(yīng)用服務(wù)器集群中的任何一臺服務(wù)器上,如果有更多的用戶,就在集群中加入更多的應(yīng)用服務(wù)器,使應(yīng)用服務(wù)器的負(fù)載壓力不再成為整個網(wǎng)站的瓶頸。數(shù)據(jù)庫讀寫分離網(wǎng)站在使用緩存后,使絕大部分?jǐn)?shù)據(jù)讀操作訪問都可以不通過數(shù)據(jù)庫就能完成,但是仍有一部分讀操作(緩存訪問不命中、緩存過期)和全部的寫操作需要訪問數(shù)據(jù)庫,在網(wǎng)站的用戶達到一定規(guī)模后,數(shù)據(jù)庫因為負(fù)載壓力過高而成為網(wǎng)站的瓶頸。目前大部分的主流數(shù)據(jù)庫都提供主從熱備功能,通過配置兩臺數(shù)據(jù)庫主從關(guān)系,可以將一臺數(shù)據(jù)庫服務(wù)器的數(shù)據(jù)更新同步到另一臺服務(wù)器上。網(wǎng)站利用數(shù)據(jù)庫的這一功能,實現(xiàn)數(shù)據(jù)庫讀寫分離,從而改善數(shù)據(jù)庫負(fù)載壓力,如圖1.5所示。圖1.5數(shù)據(jù)庫讀寫分離應(yīng)用服務(wù)器在寫數(shù)據(jù)的時候,訪問主數(shù)據(jù)庫,主數(shù)據(jù)庫通過主從復(fù)制機制將數(shù)據(jù)更新同步到從數(shù)據(jù)庫,這樣當(dāng)應(yīng)用服務(wù)器讀數(shù)據(jù)的時候,就可以通過從數(shù)據(jù)庫獲得數(shù)據(jù)。為了便于應(yīng)用程序訪問讀寫分離后的數(shù)據(jù)庫,通常在應(yīng)用服務(wù)器端使用專門的數(shù)據(jù)訪問模塊,使數(shù)據(jù)庫讀寫分離對應(yīng)用透明。使用反向代理和CDN加速網(wǎng)站響應(yīng)隨著網(wǎng)站業(yè)務(wù)不斷發(fā)展,用戶規(guī)模越來越大,由于中國復(fù)雜的網(wǎng)絡(luò)環(huán)境,不同地區(qū)的用戶訪問網(wǎng)站時,速度差別也極大。有研究表明,網(wǎng)站訪問延遲和用戶流失率正相關(guān),網(wǎng)站訪問越慢,用戶越容易失去耐心而離開。為了提供更好的用戶體驗,留住用戶,網(wǎng)站需要加速網(wǎng)站訪問速度。主要手段有使用CDN和反向代理,如圖1.6所示。CDN和反向代理的基本原理都是緩存,區(qū)別在于CDN部署在網(wǎng)絡(luò)提供商的機房,使用戶在請求網(wǎng)站服務(wù)時,可以從距離自己最近的網(wǎng)絡(luò)提供商機房獲取數(shù)據(jù);而反向代理則部署在網(wǎng)站的中心機房,當(dāng)用戶請求到達中心機房后,首先訪問的服務(wù)器是反向代理服務(wù)器,如果反向代理服務(wù)器中緩存著用戶請求的資源,就將其直接返回給用戶。圖1.6 網(wǎng)站使用反向代理和CDN加速訪問使用CDN和反向代理的目的都是盡早返回數(shù)據(jù)給用戶,一方面加快用戶訪問速度,另一方面也減輕后端服務(wù)器的負(fù)載壓力。使用分布式文件系統(tǒng)和分布式數(shù)據(jù)庫系統(tǒng)任何強大的單一服務(wù)器都滿足不了大型網(wǎng)站持續(xù)增長的業(yè)務(wù)需求。數(shù)據(jù)庫經(jīng)過讀寫分離需要使用分布式數(shù)據(jù)庫。文件系統(tǒng)也是一樣,需要使用分布式文件系統(tǒng),如圖1.7所示。分布式數(shù)據(jù)庫是網(wǎng)站數(shù)據(jù)庫拆分的最后手段,只有在單表數(shù)據(jù)規(guī)模非常龐大的時候才使在不同的物理服務(wù)器上。圖1.7 使用分布式文件和分布式數(shù)據(jù)庫系統(tǒng)使用NoSQL和搜索引擎隨著網(wǎng)站業(yè)務(wù)越來越復(fù)雜,對數(shù)據(jù)存儲和檢索的需求也越來越復(fù)雜,網(wǎng)站需要采用一些非關(guān)系數(shù)據(jù)庫技術(shù)如NoSQL和非數(shù)據(jù)庫查詢技術(shù)如搜索引擎,如圖1.8所示。圖1.8 使用NoSQL系統(tǒng)和搜索引擎NoSQL和搜索引擎都是源自互聯(lián)網(wǎng)的技術(shù)手段,對可伸縮的分布式特性具有更好的支持。應(yīng)用服務(wù)器則通過一個統(tǒng)一數(shù)據(jù)訪問模塊訪問各種數(shù)據(jù),減輕應(yīng)用程序管理諸多數(shù)據(jù)源的麻煩。業(yè)務(wù)拆分大型網(wǎng)站為了應(yīng)對日益復(fù)雜的業(yè)務(wù)場景,通過使用分而治之的手段將整個網(wǎng)站業(yè)務(wù)分成不同的產(chǎn)品線,如大型購物交易網(wǎng)站就會將首頁、商鋪、訂單、買家、賣家等拆分成不同的產(chǎn)品線,分歸不同的業(yè)務(wù)團隊負(fù)責(zé)。部署維護。應(yīng)用之間可以通過一個超鏈接建立關(guān)系(的應(yīng)用地址)圖1.9 應(yīng)用拆分分布式服務(wù)隨著業(yè)務(wù)拆分越來越小,存儲系統(tǒng)越來越龐大,應(yīng)用系統(tǒng)的整體復(fù)雜度呈指數(shù)級增加,部署維護越來越困難。由于所有應(yīng)用要和所有數(shù)據(jù)庫系統(tǒng)連接,在數(shù)萬臺服務(wù)器規(guī)模的網(wǎng)站中,這些連接的數(shù)目是服務(wù)器規(guī)模的平方,導(dǎo)致存數(shù)據(jù)庫接資源不足,拒絕服務(wù)。既然每一個應(yīng)用系統(tǒng)都需要執(zhí)行許多相同的業(yè)務(wù)操作,比如用戶管理、商品管理等,那么可以將這些共用的業(yè)務(wù)提取出來,獨立部署。由這些可復(fù)用的業(yè)務(wù)連接數(shù)據(jù)庫,提供共用業(yè)務(wù)服務(wù),而應(yīng)用系統(tǒng)只需要管理用戶界面,通過分布式服務(wù)調(diào)用共用業(yè)務(wù)服務(wù)完成具體業(yè)務(wù)操作,如圖1.10所示。圖1.10 分布式服務(wù)時數(shù)據(jù)同步和具體網(wǎng)站業(yè)務(wù)相關(guān)的問題也都可以通過組合改進現(xiàn)有技術(shù)架構(gòu)來解決。需付費,就可以使網(wǎng)站隨著業(yè)務(wù)的增長逐漸獲得更大的存儲空間和更多的計算資源。大型網(wǎng)站架構(gòu)演化的價值觀這個世界沒有哪個網(wǎng)站從誕生起就是大型網(wǎng)站;也沒有哪個網(wǎng)站第一次發(fā)布就擁有龐大的用戶,高并發(fā)的訪問,海量的數(shù)據(jù);大型網(wǎng)站都是從小型網(wǎng)站發(fā)展而來。網(wǎng)站的價值在于它能為用戶提供什么價值,在于網(wǎng)站能做什么,而不在于它是怎么做的,所以在網(wǎng)站還很小的時候就去追求網(wǎng)站的架構(gòu)是舍本逐末,得不償失的。小型網(wǎng)站最需要做的就是為用戶提供好的服務(wù)來創(chuàng)造價值,得到用戶的認(rèn)可,活下去,野蠻生長。所以我們看到,一方面是隨著互聯(lián)網(wǎng)的高速發(fā)展,越來越多新的軟件技術(shù)和產(chǎn)品從互聯(lián)網(wǎng)公司誕生,挑戰(zhàn)傳統(tǒng)軟件巨頭的江湖地位。另一方面卻是中小網(wǎng)站十幾年如一日地使用LAMP技術(shù)(Linux+Apache+MySQL+PHP)開發(fā)自己的網(wǎng)站,因為LAMP既便宜又簡單,而且對付一個中小型網(wǎng)站綽綽有余。大型網(wǎng)站架構(gòu)技術(shù)的核心價值是隨網(wǎng)站所需靈活應(yīng)對什么,不需要推翻什么,不需要劇烈的革命,就那么潤物細無聲地把一個只有一臺服務(wù)到的大型網(wǎng)站,Google,F(xiàn)acebook,Taobao,Baidu莫不遵循這樣的技術(shù)演化路線。驅(qū)動大型網(wǎng)站技術(shù)發(fā)展的主要力量是網(wǎng)站的業(yè)務(wù)發(fā)展創(chuàng)新的業(yè)務(wù)發(fā)展模式對網(wǎng)站架構(gòu)逐步提出更高要求,才使得創(chuàng)新的網(wǎng)站架構(gòu)得以發(fā)展成保持持續(xù)進步。不過我們也看到有些傳統(tǒng)企業(yè)投身互聯(lián)網(wǎng),在業(yè)務(wù)問題還沒有理清楚的時候就從外面挖來許多技術(shù)高手,仿照成功的互聯(lián)網(wǎng)公司打造技術(shù)平臺,這無疑是南轅北轍,緣木求魚。而這些技術(shù)高手離開了它們熟悉的環(huán)境和工作模式,也是張飛拿著繡花針使不上勁來。網(wǎng)站架構(gòu)設(shè)計誤區(qū)在大型網(wǎng)站架構(gòu)發(fā)展過程中有如下幾個容易出現(xiàn)的誤區(qū)。一味追隨大公司的解決方案由于大公司巨大成功的光環(huán)效應(yīng),再加上從大公司挖來的技術(shù)高手的影響,網(wǎng)站在討論架構(gòu)決策時,最有說服力的一句話就成了“淘寶就是這么搞的”或者“Facebook就是這么搞的”。大公司的經(jīng)驗和成功模式固然重要,值得學(xué)習(xí)借鑒,但如果因此而變得盲從,就失去了堅持自我的勇氣,在架構(gòu)演化的道路上遲早會迷路。為了技術(shù)而技術(shù)網(wǎng)站技術(shù)是為業(yè)務(wù)而存在的,除此毫無意義。在技術(shù)選型和架構(gòu)設(shè)計中,脫離網(wǎng)站業(yè)務(wù)發(fā)展的實際,一味追求時髦的新技術(shù),可能會將網(wǎng)站技術(shù)發(fā)展引入崎嶇小道,架構(gòu)之路越走越難。企圖用技術(shù)解決所有問題最典型的例子就是2012年年初12306故障事件后,軟件開發(fā)技術(shù)界的反應(yīng)。各路專業(yè)和非專業(yè)人士眾說紛紜地幫12306的技術(shù)架構(gòu)出謀劃策,甚至有人提議幫12306寫一個開源的網(wǎng)站,解決其大規(guī)模并發(fā)訪問的問題。12306真正的問題其實不在于它的技術(shù)架構(gòu),而在于它的業(yè)務(wù)架構(gòu):12306根本就不應(yīng)該在幾億中國人一票難求的情況下以窗口售票的模式在網(wǎng)上售票(零點開始出售若干天后的車票)。12306需要重構(gòu)的不僅是它的技術(shù)架構(gòu),更重要的是它的業(yè)務(wù)架構(gòu):調(diào)整業(yè)務(wù)需求,換一種方式賣票,而不要去搞促銷秒殺這種噱頭式的游戲。后來證明12306確實是朝這個方向發(fā)展的:在售票方式上引入了排隊機制、整點售票調(diào)整為分時段售票。其實如果能控制住并發(fā)訪問的量,很多棘手的技術(shù)問題也就不是什么問題了。技術(shù)是用來解決業(yè)務(wù)問題的,而業(yè)務(wù)的問題,也可以通過業(yè)務(wù)的手段去解決。小結(jié)時至今日,大型網(wǎng)站的架構(gòu)演化方案已經(jīng)非常成熟,各種技術(shù)方案也逐漸產(chǎn)品化。許多小型網(wǎng)站已經(jīng)慢慢不需要再經(jīng)歷大型網(wǎng)站經(jīng)歷過的架構(gòu)演化之路就可以逐步發(fā)展壯大,因為現(xiàn)在越來越多的網(wǎng)站從建立之初就是搭建在大型網(wǎng)站提供的云計算服務(wù)基礎(chǔ)之上,所需要的一切技術(shù)資源:計算、存儲、網(wǎng)絡(luò)都可以按需購買,線性伸縮,不需要自己一點一點地拼湊各種資源,綜合使用各種技術(shù)方案逐步去完善自己的網(wǎng)站架構(gòu)了。所以能親身經(jīng)歷一個網(wǎng)站從小到大的架構(gòu)演化過程的網(wǎng)站架構(gòu)師越來越少,雖然過去有這種經(jīng)歷的架構(gòu)師也很少(從小型網(wǎng)站發(fā)展成大型網(wǎng)站的機會本來就極少),但是將來可能真就沒有了。但也正因為網(wǎng)站架構(gòu)技術(shù)演化過程難以重現(xiàn),所以網(wǎng)站架構(gòu)師更應(yīng)該對這個過程深刻了能有的放矢,直擊要害。大型網(wǎng)站架構(gòu)模式關(guān)于什么是模式,這個來自建筑學(xué)的詞匯是這樣定義的:“每一個模式描述了一個在我們周圍不斷重復(fù)發(fā)生的問題及該問題解決方案的核心。這樣,你就能一次又一次地使用該方案而不必做重復(fù)工作”。模式的關(guān)鍵在于模式的可重復(fù)性,問題與場景的可重復(fù)性帶來解決方案的可重復(fù)使用。我們的現(xiàn)實生活中充斥著幾乎千篇一律的人生架構(gòu)模式:讀重點學(xué)校,選熱門專業(yè),進穩(wěn)定高收入的政府部門和企業(yè),找門當(dāng)戶對的配偶,生一個聽話的孩子繼續(xù)這個模式……但是人生不同于軟件,精彩的人生絕不會來自于復(fù)制。構(gòu)卻有一些共同的模式,這些模式已經(jīng)被許多大型網(wǎng)站一再驗證,通過對這些模式的學(xué)習(xí),我們可以掌握大型網(wǎng)站架構(gòu)的一般思路和解決方案,以指導(dǎo)我們的架構(gòu)設(shè)計。網(wǎng)站架構(gòu)模式為了解決大型網(wǎng)站面臨的高并發(fā)訪問、海量數(shù)據(jù)處理、高可靠運行等一系列問題與挑戰(zhàn),大型互聯(lián)網(wǎng)公司在實踐中提出了許多解決方案,以實現(xiàn)網(wǎng)站高性能、高可用、易伸縮、可擴展、安全等各種技術(shù)架構(gòu)目標(biāo)。這些解決方案又被更多網(wǎng)站重復(fù)使用,從而逐漸形成大型網(wǎng)站架構(gòu)模式。分層分層是企業(yè)應(yīng)用系統(tǒng)中最常見的一種架構(gòu)模式,將系統(tǒng)在橫向維度上切分成幾個部分,每個部分負(fù)責(zé)一部分相對比較單一的職責(zé),然后通過上層對下層的依賴和調(diào)用組成一個完整的系統(tǒng)。分層結(jié)構(gòu)在計算機世界中無處不在,網(wǎng)絡(luò)的7層通信協(xié)議是一種分層結(jié)構(gòu);計算機硬件、操作系統(tǒng)、應(yīng)用軟件也可以看作是一種分層結(jié)構(gòu)。在大型網(wǎng)站架構(gòu)中也采用分層結(jié)構(gòu),將網(wǎng)站軟件系統(tǒng)分為應(yīng)用層、服務(wù)層、數(shù)據(jù)層,如表2.1所示。表2.1 網(wǎng)站分層架構(gòu)通過分層,可以更好地將一個龐大的軟件系統(tǒng)切分成不同的部分,便于分工合作開發(fā)和維護;各層之間具有一定的獨立性,只要維持調(diào)用接口不變,各層可以根據(jù)具體問題獨立演化發(fā)展而不需要其他層必須做出相應(yīng)調(diào)整。但是分層架構(gòu)也有一些挑戰(zhàn),就是必須合理規(guī)劃層次邊界和接口,在開發(fā)過程中,嚴(yán)格遵循分層架構(gòu)的約束,禁止跨層次的調(diào)用(應(yīng)用層直接調(diào)用數(shù)據(jù)層)及逆向調(diào)用(數(shù)據(jù)層調(diào)用服務(wù)層,或者服務(wù)層調(diào)用應(yīng)用層)。在實踐中,大的分層結(jié)構(gòu)內(nèi)部還可以繼續(xù)分層,如應(yīng)用層可以再細分為視圖層(美工負(fù)責(zé))和業(yè)務(wù)邏輯層(工程師負(fù)責(zé))(輸出的數(shù)據(jù)格式)和邏輯處理層。分層架構(gòu)是邏輯上的,在物理部署上,三層結(jié)構(gòu)可以部署在同一個物理機器上,但是隨著網(wǎng)站業(yè)務(wù)的發(fā)展,必然需要對已經(jīng)分層的模塊分離部署,即三層結(jié)構(gòu)分別部署在不同的服務(wù)器上,使網(wǎng)站擁有更多的計算資源以應(yīng)對越來越多的用戶訪問。所以雖然分層架構(gòu)模式最初的目的是規(guī)劃軟件清晰的邏輯結(jié)構(gòu)便于開發(fā)維護,但在網(wǎng)站的發(fā)展過程中,分層結(jié)構(gòu)對網(wǎng)站支持高并發(fā)向分布式方向發(fā)展至關(guān)重要。因此在網(wǎng)站規(guī)模還很小的時候就應(yīng)該采用分層的架構(gòu),這樣將來網(wǎng)站做大時才能有更好地應(yīng)對。分割如果說分層是將軟件在橫向方面進行切分,那么分割就是在縱向方面對軟件進行切分。網(wǎng)站越大,功能越復(fù)雜,服務(wù)和數(shù)據(jù)處理的種類也越多,將這些不同的功能和服務(wù)分割開來,包裝成高內(nèi)聚低耦合的模塊單元,一方面有助于軟件的開發(fā)和維護;另一方面,便于不同模塊的分布式部署,提高網(wǎng)站的并發(fā)處理能力和功能擴展能力。成機票酒店業(yè)務(wù)、3C業(yè)務(wù),小商品業(yè)務(wù)等更細小的粒度。而即使在這個粒度上,還是可以繼續(xù)分割成首頁、搜索列表、商品詳情等模塊,這些模塊不管在邏輯上還是物理部署上,都可以是獨立的。同樣在服務(wù)層也可以根據(jù)需要將服務(wù)分割成合適的模塊。分布式對于大型網(wǎng)站,分層和分割的一個主要目的是為了切分后的模塊便于分布式部署,即將不同模塊部署在不同的服務(wù)器上,通過遠程調(diào)用協(xié)同工作。分布式意味著可以使用更多的計算機完成同樣的功能,計算機越多,CPU、內(nèi)存、存儲資源也就越多,能夠處理的并發(fā)訪問和數(shù)據(jù)量就越大,進而能夠為更多的用戶提供服務(wù)。但分布式在解決網(wǎng)站高并發(fā)問題的同時也帶來了其他問題。首先,分布式意味著服務(wù)調(diào)用必須通過網(wǎng)絡(luò),這可能會對性能造成比較嚴(yán)重的影響;其次,服務(wù)器越多,服務(wù)器宕機的概率也就越大,一臺服務(wù)器宕機造成的服務(wù)不可用可能會導(dǎo)致很多應(yīng)用不可訪問,使網(wǎng)站可用性降低;另外,數(shù)據(jù)在分布式的環(huán)境中保持?jǐn)?shù)據(jù)一致性也非常困難,分布式事務(wù)也難以保證,這對網(wǎng)站業(yè)務(wù)正確性和業(yè)務(wù)流程有可能造成很大影響;分布式還導(dǎo)致網(wǎng)站依賴錯綜復(fù)雜,開發(fā)管理維護困難。因此分布式設(shè)計要根據(jù)具體情況量力而行,切莫為了分布式而分布式。在網(wǎng)站應(yīng)用中,常用的分布式方案有以下幾種。分布式應(yīng)用和服務(wù):將分層和分割后的應(yīng)用和服務(wù)模塊分布式部署,除了可以改善網(wǎng)站性能和并發(fā)性、加快開發(fā)和發(fā)布速度、減少數(shù)據(jù)庫連接資源消耗外;還可以使不同應(yīng)用復(fù)用共同的服務(wù),便于業(yè)務(wù)功能擴展。分布式靜態(tài)資源:網(wǎng)站的靜態(tài)資源如JS,CSS,Logo圖片等資源獨立分布式部署,并采用獨立的域名,即人們常說的動靜分離。靜態(tài)資源分布式部署可以減輕應(yīng)用服務(wù)器的負(fù)載壓力;通過使用獨立域名加快瀏覽器并發(fā)加載的速度;由負(fù)責(zé)用戶體驗的團隊進行開發(fā)維護有利于網(wǎng)站分工合作,使不同技術(shù)工種術(shù)業(yè)有專攻。分布式數(shù)據(jù)和存儲:大型網(wǎng)站需要處理以P為單位的海量數(shù)據(jù),單臺計算機無法提供如此大的存儲空間,這些數(shù)據(jù)需要分布式存儲。除了對傳統(tǒng)的關(guān)系數(shù)據(jù)庫進行分布式部署外,為網(wǎng)站應(yīng)用而生的各種NoSQL產(chǎn)品幾乎都是分布式的。數(shù)據(jù)倉庫的數(shù)據(jù)分析統(tǒng)計等。這些業(yè)務(wù)的計算規(guī)模非常龐大,目前網(wǎng)站普遍使用Hadoop及其MapReduce分布式計算框架進行此類批處理計算,其特點是移動計算而不是移動數(shù)據(jù),將計算程序分發(fā)到數(shù)據(jù)所在的位置以加速計算和分布式計算。此外,還有可以支持網(wǎng)站線上服務(wù)器配置實時更新的分布式配置;分布式環(huán)境下實現(xiàn)并發(fā)和協(xié)同的分布式鎖;支持云存儲的分布式文件系統(tǒng)等。集群使用分布式雖然已經(jīng)將分層和分割后的模塊獨立部署,但是對于用戶訪問集中的模塊(如網(wǎng)站的首頁)戶訪問的時候,只需要向集群中加入新的機器即可。同時因為一個應(yīng)用由多臺服務(wù)器提的可用性。緩存緩存就是將數(shù)據(jù)存放在距離計算最近的位置以加快處理速度。緩存是改善軟件性能的第一手段,現(xiàn)代CPU越來越快的一個重要因素就是使用了更多的緩存,在復(fù)雜的軟件設(shè)計中,緩存幾乎無處不在。大型網(wǎng)站架構(gòu)設(shè)計在很多方面都使用了緩存設(shè)計。CDN:即內(nèi)容分發(fā)網(wǎng)絡(luò),部署在距離終端用戶最近的網(wǎng)絡(luò)服務(wù)商,用戶的網(wǎng)絡(luò)請求總是先到達他的網(wǎng)絡(luò)服務(wù)商那里,在這里緩存網(wǎng)站的一些靜態(tài)資源(較少變化的數(shù)據(jù))在CDN。反向代理:反向代理屬于網(wǎng)站前端架構(gòu)的一部分,部署在網(wǎng)站的前端,當(dāng)用戶請求到達網(wǎng)站的數(shù)據(jù)中心時,最先訪問到的就是反向代理服務(wù)器,這里緩存網(wǎng)站的靜態(tài)資源,無需將請求繼續(xù)轉(zhuǎn)發(fā)給應(yīng)用服務(wù)器就能返回給用戶。本地緩存:在應(yīng)用服務(wù)器本地緩存著熱點數(shù)據(jù),應(yīng)用程序可以在本機內(nèi)存中直接訪問數(shù)據(jù),而無需訪問數(shù)據(jù)庫。分布式緩存:大型網(wǎng)站的數(shù)據(jù)量非常龐大,即使只緩存一小部分,需要的內(nèi)存空間也不是單機能承受的,所以除了本地緩存,還需要分布式緩存,將數(shù)據(jù)緩存在一個專門的分布式緩存集群中,應(yīng)用程序通過網(wǎng)絡(luò)通信訪問緩存數(shù)據(jù)。使用緩存有兩個前提條件,一是數(shù)據(jù)訪問熱點不均衡,某些數(shù)據(jù)會被更頻繁的訪問,這些數(shù)據(jù)應(yīng)該放在緩存中;二是數(shù)據(jù)在某個時間段內(nèi)有效,不會很快過期,否則緩存的數(shù)據(jù)就會因已經(jīng)失效而產(chǎn)生臟讀,影響結(jié)果的正確性。網(wǎng)站應(yīng)用中,緩存除了可以加快數(shù)據(jù)訪問速度,還可以減輕后端應(yīng)用和數(shù)據(jù)存儲的負(fù)載壓力,這一點對網(wǎng)站數(shù)據(jù)庫架構(gòu)至關(guān)重要,網(wǎng)站數(shù)據(jù)庫幾乎都是按照有緩存的前提進行負(fù)載能力設(shè)計的。異步異步架構(gòu)是典型的生產(chǎn)者消費者模式,兩者不存在直接調(diào)用,只要保持?jǐn)?shù)據(jù)結(jié)構(gòu)不變,彼此功能實現(xiàn)可以隨意變化而不互相影響,這對網(wǎng)站擴展新功能非常便利。除此之外,使用異步消息隊列還有如下特性。提高系統(tǒng)可用性。消費者服務(wù)器發(fā)生故障,數(shù)據(jù)會在消息隊列服務(wù)器中存儲堆積,生產(chǎn)者服務(wù)器可以繼續(xù)處理業(yè)務(wù)請求,系統(tǒng)整體表現(xiàn)無故障。消費者服務(wù)器恢復(fù)正常后,繼續(xù)處理消息隊列中的數(shù)據(jù)。加快網(wǎng)站響應(yīng)速度。處在業(yè)務(wù)處理前端的生產(chǎn)者服務(wù)器在處理完業(yè)務(wù)請求后,將數(shù)據(jù)寫入消息隊列,不需要等待消費者服務(wù)器處理就可以返回,響應(yīng)延遲減少。消除并發(fā)訪問高峰。用戶訪問網(wǎng)站是隨機的,存在訪問高峰和低谷,即使網(wǎng)站按照一般訪問高峰進行規(guī)劃和部署,也依然會出現(xiàn)突發(fā)事件,比如購物網(wǎng)站的促銷活動,微博上的熱點事件,都會造成網(wǎng)站并發(fā)訪問突然增大,這可能會造成整個網(wǎng)站負(fù)載過重,響應(yīng)延遲,嚴(yán)重時甚至?xí)霈F(xiàn)服務(wù)宕機的情況。使用消息隊列將突然增加的訪問請求數(shù)據(jù)放入消息隊列中,等待消費者服務(wù)器依次處理,就不會對整個網(wǎng)站負(fù)載造成太大壓力。但需要注意的是,使用異步方式處理業(yè)務(wù)可能會對用戶體驗、業(yè)務(wù)流程造成影響,需要網(wǎng)站產(chǎn)品設(shè)計方面的支持。冗余網(wǎng)站需要7′24小時連續(xù)運行,但是服務(wù)器隨時可能出現(xiàn)故障,特別是服務(wù)器規(guī)模比較大器宕機時,可以將其上的服務(wù)和數(shù)據(jù)訪問轉(zhuǎn)移到其他機器上。訪問和負(fù)載很小的服務(wù)也必須部署至少兩臺服務(wù)器構(gòu)成一個集群,其目的就是通過冗余實現(xiàn)服務(wù)高可用。數(shù)據(jù)庫除了定期備份,存檔保存,實現(xiàn)冷備份外,為了保證在線業(yè)務(wù)高可用,還需要對數(shù)據(jù)庫進行主從分離,實時同步實現(xiàn)熱備份。為了抵御地震、海嘯等不可抗力導(dǎo)致的網(wǎng)站完全癱瘓,某些大型網(wǎng)站會對整個數(shù)據(jù)中心進行備份,全球范圍內(nèi)部署災(zāi)備數(shù)據(jù)中心。網(wǎng)站程序和數(shù)據(jù)實時同步到多個災(zāi)備數(shù)據(jù)中心。自動化在無人值守的情況下網(wǎng)站可以正常運行,一切都可以自動化是網(wǎng)站的理想狀態(tài)。目前大型網(wǎng)站的自動化架構(gòu)設(shè)計主要集中在發(fā)布運維方面。測,安全檢測工具通過對代碼進行靜態(tài)安全掃描及部署到安全測試環(huán)境進行安全攻擊測試,評估其安全性;最后進行自動化部署,將工程代碼自動部署到線上生產(chǎn)環(huán)境。此外,網(wǎng)站在運行過程中可能會遇到各種問題:服務(wù)器宕機、程序Bug、存儲空間不足、突然爆發(fā)的訪問高峰。網(wǎng)站需要對線上生產(chǎn)環(huán)境進行自動化監(jiān)控,對服務(wù)器進行心跳檢測,并監(jiān)控其各項性能指標(biāo)和應(yīng)用程序的關(guān)鍵數(shù)據(jù)指標(biāo)。如果發(fā)現(xiàn)異常、超出預(yù)設(shè)的閾大其部署規(guī)模。安全濫用網(wǎng)絡(luò)資源攻擊網(wǎng)站,網(wǎng)站使用驗證碼進行識別;對于常見的用于攻擊網(wǎng)站的XSS攻擊、SQL注入、進行編碼轉(zhuǎn)換等相應(yīng)處理;對于垃圾信息、敏感信息進行過濾;對交易轉(zhuǎn)賬等重要操作根據(jù)交易模式和交易信息進行風(fēng)險控制。架構(gòu)模式在新浪微博的應(yīng)用新浪微博正在發(fā)展一個集社交、媒體、游戲、電商等多位一體的生態(tài)系統(tǒng)。LAMP(Linux+Apache+MySQL+PHP)架構(gòu),支撐起最初的新浪微博,應(yīng)用程序用PHP開發(fā),所有的數(shù)據(jù),包括微博、用戶、關(guān)系都存儲在MySQL數(shù)據(jù)庫中。這樣簡單的架構(gòu)無法支撐新浪微博快速發(fā)展的業(yè)務(wù)需求,隨著訪問用戶的逐漸增加,系統(tǒng)不堪重負(fù)。新浪微博的架構(gòu)在較短時間內(nèi)幾經(jīng)重構(gòu),最后形成現(xiàn)在的架構(gòu),如圖2.1所示。圖2.1 新浪微博的系統(tǒng)架構(gòu)(圖片來源:\h/architecture/weibo/)系統(tǒng)分為三個層次,最下層是基礎(chǔ)服務(wù)層,提供數(shù)據(jù)庫、緩存、存儲、搜索等數(shù)據(jù)服務(wù),以及其他一些基礎(chǔ)技術(shù)服務(wù),這些服務(wù)支撐了新浪微博的海量數(shù)據(jù)和高并發(fā)訪問,是整個系統(tǒng)的技術(shù)基礎(chǔ)。中間層是平臺服務(wù)和應(yīng)用服務(wù)層,新浪微博的核心服務(wù)是微博、關(guān)系和用戶,它們是新浪微博業(yè)務(wù)大廈的支柱。這些服務(wù)被分割為獨立的服務(wù)模塊,通過依賴調(diào)用和共享基礎(chǔ)數(shù)據(jù)構(gòu)成新浪微博的業(yè)務(wù)基礎(chǔ)。最上層是API和新浪微博的業(yè)務(wù)層,各種客戶端(包括Web網(wǎng)站)和第三方應(yīng)用,通過調(diào)用API集成到新浪微博的系統(tǒng)中,共同組成一個生態(tài)系統(tǒng)。這些被分層和分割后的業(yè)務(wù)模塊與基礎(chǔ)技術(shù)模塊分布式部署,每個模塊都部署在一組獨立的服務(wù)器集群上,通過遠程調(diào)用的方式進行依賴訪問。新浪微博在早期還使用過一種叫作MPSS(MultiPortSingleServer,單服務(wù)器多端口)的分布式集群部署方案,在集群中的多臺服務(wù)器上,每臺都部署多個服務(wù),每個服務(wù)使用不同的端口對外提供服務(wù),通過這種方式使得有限的服務(wù)器可以部署更多的服務(wù)實例,改善服務(wù)的負(fù)載均衡和可用性?,F(xiàn)在網(wǎng)站應(yīng)用中常見的將物理機虛擬化成多個虛擬機后,在虛擬機上部署應(yīng)用的方案跟新浪微博的MPSS方案異曲同工,只是更加簡單,還能在不同虛擬機上使用相同的端口號。在新浪微博的早期架構(gòu)中,微博發(fā)布使用同步推模式,用戶發(fā)表微博后系統(tǒng)會立即將這條微博插入到數(shù)據(jù)庫所有粉絲的訂閱列表中,當(dāng)用戶量比較大時,特別是明星用戶發(fā)布微博時,會引起大量的數(shù)據(jù)庫寫操作,超出數(shù)據(jù)庫負(fù)載,系統(tǒng)性能急劇下降,用戶響應(yīng)延遲加劇。后來新浪微博改用異步推拉結(jié)合的模式,用戶發(fā)表微博后系統(tǒng)將微博寫入消息隊列后立即返回,用戶響應(yīng)迅速,消息隊列消費者任務(wù)將微博推送給所有當(dāng)前在線粉絲的訂閱列表中,非在線用戶登錄后再根據(jù)關(guān)注列表拉取微博訂閱列表。由于微博頻繁刷新,新浪微博使用多級緩存策略,熱門微博和明星用戶的微博緩存在所有的微博服務(wù)器上,在線用戶的微博和近期微博緩存在分布式緩存集群中,對于微博操作中最常見的“刷微博”操作,幾乎全部都是緩存訪問操作,可以獲得很好的系統(tǒng)性能。為了提高系統(tǒng)的整體可用性和性能,新浪微博啟用了多個數(shù)據(jù)中心。這些數(shù)據(jù)中心既是地區(qū)用戶訪問中心,用戶可以就近訪問最近的數(shù)據(jù)中心以加快訪問速度,改善系統(tǒng)性能;同時也是數(shù)據(jù)冗余復(fù)制的災(zāi)備中心,所有的用戶和微博數(shù)據(jù)通過遠程消息系統(tǒng)在不同的數(shù)據(jù)中心之間同步,提高系統(tǒng)可用性。同時,新浪微博還開發(fā)了一系列自動化工具,包括自動化監(jiān)控,自動化發(fā)布,自動化故障修復(fù)等,這些自動化工具還在持續(xù)開發(fā)中,以改善運維水平提高系統(tǒng)可用性。由于微博的開放特性,新浪微博也遇到了一系列的安全挑戰(zhàn),垃圾內(nèi)容、僵尸粉、微博攻擊從未停止,除了使用一般網(wǎng)站常見的安全策略,新浪微博在開放平臺上使用多級安全審核的策略以保護系統(tǒng)和用戶。小結(jié)時間開發(fā)出更好的系統(tǒng),使設(shè)計者的水平也達到更高的境界。但是模式受其適用場景限原來的老問題,反而帶來了更棘手的新問題。好的設(shè)計絕對不是模仿,不是生搬硬套某個模式,而是對問題深刻理解之上的創(chuàng)造與創(chuàng)新,即使是“微創(chuàng)新”,也是讓人耳目一新的似曾相識。山寨與創(chuàng)新的最大區(qū)別不在于是否抄襲,是否模仿,而在于對問題和需求是否真正理解與把握。大型網(wǎng)站核心架構(gòu)要素關(guān)于什么是架構(gòu),一種比較通俗的說法是“最高層次的規(guī)劃,難以改變的決定”,這些規(guī)劃和決定奠定了事物未來發(fā)展的方向和最終的藍圖。從這個意義上說,人生規(guī)劃也是一種架構(gòu)。選什么學(xué)校、學(xué)什么專業(yè)、進什么公司、找什么對象,過什么樣的生活,都是自己人生的架構(gòu)。具體到軟件架構(gòu),維基百科是這樣定義的:“有關(guān)軟件整體結(jié)構(gòu)與組件的抽象描述,用于指導(dǎo)大型軟件系統(tǒng)各個方面的設(shè)計”。系統(tǒng)的各個重要組成部分及其關(guān)系構(gòu)成了系統(tǒng)的架構(gòu),這些組成部分可以是具體的功能模塊,也可以是非功能的設(shè)計與決策,他們相互關(guān)系組成一個整體,共同構(gòu)成了軟件系統(tǒng)的架構(gòu)。一般說來,除了當(dāng)前的系統(tǒng)功能需求外,軟件架構(gòu)還需要關(guān)注性能、可用性、伸縮性、擴展性和安全性這5個架構(gòu)要素,架構(gòu)設(shè)計過程中需要平衡這5個要素之間的關(guān)系以實現(xiàn)需求和架構(gòu)目標(biāo),也可以通過考察這些架構(gòu)要素來衡量一個軟件架構(gòu)設(shè)計的優(yōu)劣,判斷其是否滿足期望。性能性能是網(wǎng)站的一個重要指標(biāo),除非是沒得選擇(比如只能到\h這一個網(wǎng)站上買火車票)構(gòu)設(shè)計的一個重要方面,任何軟件架構(gòu)設(shè)計方案都必須考慮可能會帶來的性能問題。也正是因為性能問題幾乎無處不在,所以優(yōu)化網(wǎng)站性能的手段也非常多,從用戶瀏覽器到數(shù)據(jù)庫,影響用戶請求的所有環(huán)節(jié)都可以進行性能優(yōu)化。在瀏覽器端,可以通過瀏覽器緩存、使用頁面壓縮、合理布局頁面、減少Cookie傳輸?shù)仁侄胃纳菩阅?。還可以使用CDN,將網(wǎng)站靜態(tài)內(nèi)容分發(fā)至離用戶最近的網(wǎng)絡(luò)服務(wù)商機房,使用戶通過最短訪問路徑獲取數(shù)據(jù)??梢栽诰W(wǎng)站機房部署反向代理服務(wù)器,緩存熱點文件,加快請求響應(yīng)速度,減輕應(yīng)用服務(wù)器負(fù)載壓力。在應(yīng)用服務(wù)器端,可以使用服務(wù)器本地緩存和分布式緩存,通過緩存在內(nèi)存中的熱點數(shù)據(jù)處理用戶請求,加快請求處理過程,減輕數(shù)據(jù)庫負(fù)載壓力。也可以通過異步操作將用戶請求發(fā)送至消息隊列等待后續(xù)任務(wù)處理,而當(dāng)前請求直接返回響應(yīng)給用戶。在網(wǎng)站有很多用戶高并發(fā)請求的情況下,可以將多臺應(yīng)用服務(wù)器組成一個集群共同對外服務(wù),提高整體處理能力,改善性能。在代碼層面,也可以通過使用多線程、改善內(nèi)存管理等手段優(yōu)化性能。在數(shù)據(jù)庫服務(wù)器端,索引、緩存、SQL優(yōu)化等性能優(yōu)化手段都已經(jīng)比較成熟。而方興未艾的NoSQL數(shù)據(jù)庫通過優(yōu)化數(shù)據(jù)模型、存儲結(jié)構(gòu)、伸縮特性等手段在性能方面的優(yōu)勢也日趨明顯。衡量網(wǎng)站性能有一系列指標(biāo),重要的有響應(yīng)時間、TPS、系統(tǒng)性能計數(shù)器等,通過測試這些指標(biāo)以確定系統(tǒng)設(shè)計是否達到目標(biāo)。這些指標(biāo)也是網(wǎng)站監(jiān)控的重要參數(shù),通過監(jiān)控這些指標(biāo)可以分析系統(tǒng)瓶頸,預(yù)測網(wǎng)站容量,并對異常指標(biāo)進行報警,保障系統(tǒng)可用性。對于網(wǎng)站而言,性能符合預(yù)期僅僅是必要條件,因為無法預(yù)知網(wǎng)站可能會面臨的訪問壓況下保持穩(wěn)定的性能特性??捎眯詫τ诖笮途W(wǎng)站而言,特別是知名網(wǎng)站,網(wǎng)站宕掉、服務(wù)不可用是一個重大的事故,輕則影響網(wǎng)站聲譽,重則可能會攤上官司。對于電子商務(wù)類網(wǎng)站,網(wǎng)站不可用還意味著損失金錢和用戶。因此幾乎所有網(wǎng)站都承諾7′24可用,但事實上任何網(wǎng)站都不可能達到完全的7′24可用,總會有一些故障時間,扣除這些故障時間,就是網(wǎng)站的總可用時間,這個時間可以換算成網(wǎng)站的可用性指標(biāo),以此衡量網(wǎng)站的可用性,一些知名大型網(wǎng)站可以做到4個9以上的可用性,也就是可用性超過99.99%。因為網(wǎng)站使用的服務(wù)器硬件通常是普通的商用服務(wù)器,這些服務(wù)器的設(shè)計目標(biāo)本身并不保證高可用,也就是說,很有可能會出現(xiàn)服務(wù)器硬件故障,也就是俗稱的服務(wù)器宕機。大型網(wǎng)站通常都會有上萬臺服務(wù)器,每天都必定會有一些服務(wù)器宕機,因此網(wǎng)站高可用架構(gòu)設(shè)計的前提是必然會出現(xiàn)服務(wù)器宕機,而高可用設(shè)計的目標(biāo)就是當(dāng)服務(wù)器宕機的時候,服務(wù)或者應(yīng)用依然可用。網(wǎng)站高可用的主要手段是冗余,應(yīng)用部署在多臺服務(wù)器上同時提供訪問,數(shù)據(jù)存儲在多臺服務(wù)器上互相備份,任何一臺服務(wù)器宕機都不會影響應(yīng)用的整體可用,也不會導(dǎo)致數(shù)據(jù)丟失。對于應(yīng)用服務(wù)器而言,多臺應(yīng)用服務(wù)器通過負(fù)載均衡設(shè)備組成一個集群共同對外提供服將用戶請求轉(zhuǎn)發(fā)到其他服務(wù)器上也無法完成業(yè)務(wù)處理。對于存儲服務(wù)器,由于其上存儲著數(shù)據(jù),需要對數(shù)據(jù)進行實時備份,當(dāng)服務(wù)器宕機時需要將數(shù)據(jù)訪問轉(zhuǎn)移到可用的服務(wù)器上,并進行數(shù)據(jù)恢復(fù)以保證繼續(xù)有服務(wù)器宕機的時候數(shù)據(jù)依然可用。除了運行環(huán)境,網(wǎng)站的高可用還需要軟件開發(fā)過程的質(zhì)量保證。通過預(yù)發(fā)布驗證、自動化測試、自動化發(fā)布、灰度發(fā)布等手段,減少將故障引入線上環(huán)境的可能,避免故障范圍擴大。衡量一個系統(tǒng)架構(gòu)設(shè)計是否滿足高可用的目標(biāo),就是假設(shè)系統(tǒng)中任何一臺或者多臺服務(wù)器宕機時,以及出現(xiàn)各種不可預(yù)期的問題時,系統(tǒng)整體是否依然可用。伸縮性大型網(wǎng)站需要面對大量用戶的高并發(fā)訪問和存儲海量數(shù)據(jù),不可能只用一臺服務(wù)器就處理全部用戶請求,存儲全部數(shù)據(jù)。網(wǎng)站通過集群的方式將多臺服務(wù)器組成一個整體共同提供服務(wù)。所謂伸縮性是指通過不斷向集群中加入服務(wù)器的手段來緩解不斷上升的用戶并發(fā)訪問壓力和不斷增長的數(shù)據(jù)存儲需求。衡量架構(gòu)伸縮性的主要標(biāo)準(zhǔn)就是是否可以用多臺服務(wù)器構(gòu)建集群,是否容易向集群中添加新的服務(wù)器。加入新的服務(wù)器后是否可以提供和原來的服務(wù)器無差別的服務(wù)。集群中可容納的總的服務(wù)器數(shù)量是否有限制。對于應(yīng)用服務(wù)器集群,只要服務(wù)器上不保存數(shù)據(jù),所有服務(wù)器都是對等的,通過使用合適的負(fù)載均衡設(shè)備就可以向集群中不斷加入服務(wù)器。對于緩存服務(wù)器集群,加入新的服務(wù)器可能會導(dǎo)致緩存路由失效,進而導(dǎo)致集群中大部分緩存數(shù)據(jù)都無法訪問。雖然緩存的數(shù)據(jù)可以通過數(shù)據(jù)庫重新加載,但是如果應(yīng)用已經(jīng)嚴(yán)重依賴緩存,可能會導(dǎo)致整個網(wǎng)站崩潰。需要改進緩存路由算法保證緩存數(shù)據(jù)的可訪問性。關(guān)系數(shù)據(jù)庫雖然支持?jǐn)?shù)據(jù)復(fù)制,主從熱備等機制,但是很難做到大規(guī)模集群的可伸縮性,因此關(guān)系數(shù)據(jù)庫的集群伸縮性方案必須在數(shù)據(jù)庫之外實現(xiàn),通過路由分區(qū)等手段將部署有多個數(shù)據(jù)庫的服務(wù)器組成一個集群。至于大部分NoSQL數(shù)據(jù)庫產(chǎn)品,由于其先天就是為海量數(shù)據(jù)而生,因此其對伸縮性的支持通常都非常好,可以做到在較少運維參與的情況下實現(xiàn)集群規(guī)模的線性伸縮。擴展性不同于其他架構(gòu)要素主要關(guān)注非功能性需求,網(wǎng)站的擴展性架構(gòu)直接關(guān)注網(wǎng)站的功能需網(wǎng)站可擴展架構(gòu)主要的目的。衡量網(wǎng)站架構(gòu)擴展性好壞的主要標(biāo)準(zhǔn)就是在網(wǎng)站增加新的業(yè)務(wù)產(chǎn)品時,是否可以實現(xiàn)對現(xiàn)有產(chǎn)品透明無影響,不需要任何改動或者很少改動既有業(yè)務(wù)功能就可以上線新產(chǎn)品。不同產(chǎn)品之間是否很少耦合,一個產(chǎn)品改動對其他產(chǎn)品無影響,其他產(chǎn)品和功能不需要受牽連進行改動。網(wǎng)站可伸縮架構(gòu)的主要手段是事件驅(qū)動架構(gòu)和分布式服務(wù)。事件驅(qū)動架構(gòu)在網(wǎng)站通常利用消息隊列實現(xiàn),將用戶請求和其他業(yè)務(wù)事件構(gòu)造成消息發(fā)布到消息隊列,消息的處理者作為消費者從消息隊列中獲取消息進行處理。通過這種方式將消息產(chǎn)生和消息處理分離開來,可以透明地增加新的消息生產(chǎn)者任務(wù)或者新的消息消費者任務(wù)。分布式服務(wù)則是將業(yè)務(wù)和可復(fù)用服務(wù)分離開來,通過分布式服務(wù)框架調(diào)用。新增產(chǎn)品可以通過調(diào)用可復(fù)用的服務(wù)實現(xiàn)自身的業(yè)務(wù)邏輯,而對現(xiàn)有產(chǎn)品沒有任何影響??蓮?fù)用服務(wù)升級變更的時候,也可以通過提供多版本服務(wù)對應(yīng)用實現(xiàn)透明升級,不需要強制應(yīng)用同步變更。大型網(wǎng)站為了保持市場地位,還會吸引第三方開發(fā)者,調(diào)用網(wǎng)站服務(wù),使用網(wǎng)站數(shù)據(jù)開發(fā)周邊產(chǎn)品,擴展網(wǎng)站業(yè)務(wù)。第三方開發(fā)者使用網(wǎng)站服務(wù)的主要途徑是大型網(wǎng)站提供的開放平臺接口。安全性互聯(lián)網(wǎng)是開放的,任何人在任何地方都可以訪問網(wǎng)站。網(wǎng)站的安全架構(gòu)就是保護網(wǎng)站不受惡意訪問和攻擊,保護網(wǎng)站的重要數(shù)據(jù)不被竊取。衡量網(wǎng)站安全架構(gòu)的標(biāo)準(zhǔn)就是針對現(xiàn)存和潛在的各種攻擊與竊密手段,是否有可靠的應(yīng)對策略。小結(jié)性能、可用性、伸縮性、擴展性和安全性是網(wǎng)站架構(gòu)最核心的幾個要素,這幾個問題解決了,大型網(wǎng)站架構(gòu)設(shè)計的大部分挑戰(zhàn)也就克服了。因此本書第二篇即按這五個架構(gòu)要素進行組織。本章既可以看作本書第二篇的前情提要,同時也可以當(dāng)做第二篇的總結(jié)和歸納,閱讀本章過程中如果有任何困惑都不必糾結(jié),請直接跳過,等讀完全書后可以再回頭重新回顧。第2篇架構(gòu)瞬時響應(yīng):網(wǎng)站的高性能架構(gòu)什么叫高性能的網(wǎng)站?兩個網(wǎng)站性能架構(gòu)設(shè)計方案:A方案和B方案,A方案在小于100個并發(fā)用戶訪問時,每個請求的響應(yīng)時間是1秒,當(dāng)并發(fā)請求達到200的時候,請求的響應(yīng)時間將驟增到10秒。B方案不管是100個并發(fā)用戶訪問還是200個并發(fā)用戶訪問,每個請求的響應(yīng)時間都差不多是1.5秒。哪個方案的性能好?如果老板說“我們要改善網(wǎng)站的性能”,他指的是什么?X網(wǎng)站服務(wù)器平均每個請求的處理時間是500Y均每個請求的處理時間是1000毫秒,為什么用戶卻反映Y網(wǎng)站的速度快呢?感受,而感受則是一種與具體參與者相關(guān)的微妙的東西,用戶的感受和工程師的感受不同,不同的用戶感受也不同。網(wǎng)站性能測試性能測試是性能優(yōu)化的前提和基礎(chǔ),也是性能優(yōu)化結(jié)果的檢查和度量標(biāo)準(zhǔn)。不同視角下的網(wǎng)站性能有不同的標(biāo)準(zhǔn),也有不同的優(yōu)化手段。不同視角下的網(wǎng)站性能軟件工程師說到網(wǎng)站性能的時候,通常和用戶說的不一樣。用戶視角的網(wǎng)站性能從用戶角度,網(wǎng)站性能就是用戶在瀏覽器上直觀感受到的網(wǎng)站響應(yīng)速度快還是慢。用戶感受到的時間,包括用戶計算機和網(wǎng)站服務(wù)器通信的時間、網(wǎng)站服務(wù)器處理的時間、用戶計算機瀏覽器構(gòu)造請求解析響應(yīng)數(shù)據(jù)的時間,如圖4.1所示。圖4.1 用戶視角的網(wǎng)站性能不同計算機的性能差異,不同瀏覽器解析HTML速度的差異,不同網(wǎng)絡(luò)運營商提供的互聯(lián)網(wǎng)寬帶服務(wù)的差異,這些差異最終導(dǎo)致用戶感受到的響應(yīng)延遲可能會遠遠大于網(wǎng)站服務(wù)器處理請求需要的時間。在實踐中,使用一些前端架構(gòu)優(yōu)化手段,通過優(yōu)化頁面HTML式樣、利用瀏覽器端的并發(fā)和異步特性、調(diào)整瀏覽器緩存策略、使用CDN服務(wù)、反向代理等手段,使瀏覽器盡快地顯示用戶感興趣的內(nèi)容、盡可能近地獲取頁面內(nèi)容,即使不優(yōu)化應(yīng)用程序和架構(gòu),也可以很大程度地改善用戶視角下的網(wǎng)站性能。開發(fā)人員視角的網(wǎng)站性能開發(fā)人員關(guān)注的主要是應(yīng)用程序本身及其相關(guān)子系統(tǒng)的性能,包括響應(yīng)延遲、系統(tǒng)吞吐程序性能。運維人員視角的網(wǎng)站性能運維人員更關(guān)注基礎(chǔ)設(shè)施性能和資源利用率,如網(wǎng)絡(luò)運營商的帶寬能力、服務(wù)器硬件的配置、數(shù)據(jù)中心網(wǎng)絡(luò)架構(gòu)、服務(wù)器和網(wǎng)絡(luò)帶寬的資源利用率等。主要優(yōu)化手段有建設(shè)優(yōu)化骨干網(wǎng)、使用高性價比定制服務(wù)器、利用虛擬化技術(shù)優(yōu)化資源利用等。性能測試指標(biāo)不同視角下有不同的性能標(biāo)準(zhǔn),不同的標(biāo)準(zhǔn)有不同的性能測試指標(biāo),從開發(fā)和測試人員的視角,網(wǎng)站性能測試的主要指標(biāo)有響應(yīng)時間、并發(fā)數(shù)、吞吐量、性能計數(shù)器等。響應(yīng)時間指應(yīng)用執(zhí)行一個操作需要的時間,包括從發(fā)出請求開始到收到最后響應(yīng)數(shù)據(jù)所需要的時間。響應(yīng)時間是系統(tǒng)最重要的性能指標(biāo),直觀地反映了系統(tǒng)的“快慢”。表4.1列出了一些常用的系統(tǒng)操作需要的響應(yīng)時間。表4.1 常用系統(tǒng)操作響應(yīng)時間表(部分?jǐn)?shù)據(jù)來源:\h/~rcs/research/interactive_latency.html)測試程序通過模擬應(yīng)用程序,記錄收到響應(yīng)和發(fā)出請求之間的時間差來計算系統(tǒng)響應(yīng)時總響應(yīng)時間之和,然后除以一萬,得到單次請求的響應(yīng)時間。并發(fā)數(shù)指系統(tǒng)能夠同時處理請求的數(shù)目,這個數(shù)字也反映了系統(tǒng)的負(fù)載特性。對于網(wǎng)站而言,并發(fā)數(shù)即網(wǎng)站并發(fā)用戶數(shù),指同時提交請求的用戶數(shù)目。與網(wǎng)站并發(fā)用戶數(shù)相對應(yīng)的還有網(wǎng)站在線用戶數(shù)(當(dāng)前登錄網(wǎng)站的用戶總數(shù))和網(wǎng)站系統(tǒng)用戶數(shù)(可能訪問系統(tǒng)的總用戶數(shù),對多數(shù)網(wǎng)站而言就是注冊用戶數(shù))。其數(shù)量比較關(guān)系為:網(wǎng)站系統(tǒng)用戶數(shù)>>網(wǎng)站在線用戶數(shù)>>網(wǎng)站并發(fā)用戶數(shù)在網(wǎng)站產(chǎn)品設(shè)計初期,產(chǎn)品經(jīng)理和運營人員就需要規(guī)劃不同發(fā)展階段的網(wǎng)站系統(tǒng)用戶數(shù),并以此為基礎(chǔ),根據(jù)產(chǎn)品特性和運營手段,推算在線用戶數(shù)和并發(fā)用戶數(shù)。這些指標(biāo)將成為系統(tǒng)非功能設(shè)計的重要依據(jù)。響應(yīng)緩慢,急性子的用戶不停刷新瀏覽器,導(dǎo)致系統(tǒng)并發(fā)數(shù)更高,最后以服務(wù)器系統(tǒng)崩潰,用戶瀏覽器顯示“Serviceistoobusy”而告終。出現(xiàn)這種情況,有可能是網(wǎng)站技術(shù)準(zhǔn)備不充分導(dǎo)致,也有可能是運營人員錯誤地評估并發(fā)用戶數(shù)導(dǎo)致。測試程序通過多線程模擬并發(fā)用戶的辦法來測試系統(tǒng)的并發(fā)處理能力,為了真實模擬用戶行為,測試程序并不是啟動多線程然后不停地發(fā)送請求,而是在兩次請求之間加入一個隨機等待時間,這個時間被稱作思考時間。吞吐量指單位時間內(nèi)系統(tǒng)處理的請求數(shù)量,體現(xiàn)系統(tǒng)的整體處理能力。對于網(wǎng)站,可以用“請求數(shù)/秒”或是“頁面數(shù)/秒”來衡量,也可以用“訪問人數(shù)/天”或是“處理的業(yè)務(wù)數(shù)/小時”等來衡量。TPS(每秒事務(wù)數(shù))是吞吐量的一個常用量化指標(biāo),此外還有HPS(每秒HTTP請求數(shù))、QPS(每秒查詢數(shù))等。在系統(tǒng)并發(fā)數(shù)由小逐漸增大的過程中(這個過程也伴隨著服務(wù)器系統(tǒng)資源消耗逐漸增大),系統(tǒng)吞吐量先是逐漸增加,達到一個極限后,隨著并發(fā)數(shù)的增加反而下降,達到系統(tǒng)崩潰點后,系統(tǒng)資源耗盡,吞吐量為零。而這個過程中,響應(yīng)時間則是先保持小幅上升,到達吞吐量極限后,快速上升,到達系統(tǒng)崩潰點后,系統(tǒng)失去響應(yīng)。系統(tǒng)吞吐量、系統(tǒng)并發(fā)數(shù)及響應(yīng)時間之間的關(guān)系將在本章后面內(nèi)容中介紹。吞吐量是每天通過收費站的車輛數(shù)目(可以換算成收費站收取的高速費)增加很快;隨著車輛的繼續(xù)增加,車速變得越來越慢,高速公路越來越堵,收費不增反不動,費當(dāng)然也收不著,而高速公路成了停車場(資源耗盡)。網(wǎng)站性能優(yōu)化的目的,除了改善用戶體驗的響應(yīng)時間,還要盡量提高系統(tǒng)吞吐量,最大限度利用服務(wù)器資源。性能計數(shù)器它是描述服務(wù)器或操作系統(tǒng)性能的一些數(shù)據(jù)指標(biāo)。包括SystemLoad、對象與線程數(shù)、內(nèi)存使用、CPU使用、磁盤與網(wǎng)絡(luò)I/O等指標(biāo)。這些指標(biāo)也是系統(tǒng)監(jiān)控的重要參數(shù),對這些指標(biāo)設(shè)置報警閾值,當(dāng)監(jiān)控系統(tǒng)發(fā)現(xiàn)性能計數(shù)器超過閾值時,就向運維和開發(fā)人員報警,及時發(fā)現(xiàn)處理系統(tǒng)異常。SystemLoad即系統(tǒng)負(fù)載,指當(dāng)前正在被CPU執(zhí)行和等待被CPU執(zhí)行的進程數(shù)目總和,是反映系統(tǒng)忙閑程度的重要指標(biāo)。多核CPU的情況下,完美情況是所有CPU都在使用,沒有Load的理想值是CPU的數(shù)目。當(dāng)Load值低于CPU數(shù)目的時候,表示CPU有空閑,資源存在浪費;當(dāng)Load值高于CPU數(shù)目的時候,表示進程在排隊等待CPU調(diào)度,表示系統(tǒng)資源不足,影響應(yīng)用程序的執(zhí)行性能。在Linux系統(tǒng)中使用top命令查看,該值是三個浮點數(shù),表示最近1分鐘,10分鐘,15分鐘的運行隊列平均進程數(shù)。如圖4.2所示。圖4.2 在Linux命令行查看系統(tǒng)負(fù)載性能測試方法性能測試是一個總稱,具體可細分為性能測試、負(fù)載測試、壓力測試、穩(wěn)定性測試。性能測試以系統(tǒng)設(shè)計初期規(guī)劃的性能指標(biāo)為預(yù)期目標(biāo),對系統(tǒng)不斷施加壓力,驗證系統(tǒng)在資源可接受范圍內(nèi),是否能達到性能預(yù)期。負(fù)載測試對系統(tǒng)不斷地增加并發(fā)請求以增加系統(tǒng)壓力,直到系統(tǒng)的某項或多項性能指標(biāo)達到安全臨界值,如某種資源已經(jīng)呈飽和狀態(tài),這時繼續(xù)對系統(tǒng)施加壓力,系統(tǒng)的處理能力不但不能提高,反而會下降。壓力測試超過安全負(fù)載的情況下,對系統(tǒng)繼續(xù)施加壓力,直到系統(tǒng)崩潰或不能再處理任何請求,以此獲得系統(tǒng)最大壓力承受能力。穩(wěn)定性測試被測試系統(tǒng)在特定硬件、軟件、網(wǎng)絡(luò)環(huán)境條件下,給系統(tǒng)加載一定業(yè)務(wù)壓力,使系統(tǒng)運行一段較長時間,以此檢測系統(tǒng)是否穩(wěn)定。在不同生產(chǎn)環(huán)境、不同時間點的請求壓力是不均勻的,呈波浪特性,因此為了更好地模擬生產(chǎn)環(huán)境,穩(wěn)定性測試也應(yīng)不均勻地對系統(tǒng)施加壓力。性能測試是一個不斷對系統(tǒng)增加訪問壓力,以獲得系統(tǒng)性能指標(biāo)、最大負(fù)載能力、最大壓力承受能力的過程。所謂的增加訪問壓力,在系統(tǒng)測試環(huán)境中,就是不斷增加測試程序的并發(fā)請求數(shù),一般說來,性能測試遵循如圖4.3所示的拋物線規(guī)律。圖4.3中的橫坐標(biāo)表示消耗的系統(tǒng)資源,縱坐標(biāo)表示系統(tǒng)處理能力(吞吐量)。在開始階段,隨著并發(fā)請求數(shù)目的增加,系統(tǒng)使用較少的資源就達到較好的處理能力(a~b段)稱作性能測試,測試目標(biāo)是評估系統(tǒng)性能是否符合需求及設(shè)計目標(biāo);隨著壓力的持續(xù)增加,系統(tǒng)處理能力增加變緩,直到達到一個最大值(c點)統(tǒng)的處理能力反而下降,而資源消耗卻更多,直到資源消耗達到極限(d點)這一段被稱作壓力測試,測試目標(biāo)是評估可能導(dǎo)致系統(tǒng)崩潰的最大訪問負(fù)載壓力。圖4.3 性能測試曲線性能測試反應(yīng)的是系統(tǒng)在實際生產(chǎn)環(huán)境中使用時,隨著用戶并發(fā)訪問數(shù)量的增加,系統(tǒng)的處理能力。與性能曲線相對應(yīng)的是用戶訪問的等待時間(系統(tǒng)響應(yīng)時間),如圖4.4所示。圖4.4 并發(fā)用戶訪問響應(yīng)時間曲線在日常運行區(qū)間,可以獲得最好的用戶響應(yīng)時間,隨著并發(fā)用戶數(shù)的增加,響應(yīng)延遲越來越大,直到系統(tǒng)崩潰,用戶失去響應(yīng)。性能測試報告測試結(jié)果報告應(yīng)能夠反映上述性能測試曲線的規(guī)律,閱讀者可以得到系統(tǒng)性能是否滿足設(shè)計目標(biāo)和業(yè)務(wù)要求、系統(tǒng)最大負(fù)載能力、系統(tǒng)最大壓力承受能力等重要信息,表4.2是一個簡單示例。表4.2 性能測試結(jié)果報告性能優(yōu)化策略如果性能測試結(jié)果不能滿足設(shè)計或業(yè)務(wù)需求,那么就需要尋找系統(tǒng)瓶頸,分而治之,逐步優(yōu)化。性能分析大型網(wǎng)站結(jié)構(gòu)復(fù)雜,用戶從瀏覽器發(fā)出請求直到數(shù)據(jù)庫完成操作事務(wù),中間需要經(jīng)過很多環(huán)節(jié),如果測試或者用戶報告網(wǎng)站響應(yīng)緩慢,存在性能問題,必須對請求經(jīng)歷的各個環(huán)節(jié)進行分析,排查可能出現(xiàn)性能瓶頸的地方,定位問題。排查一個網(wǎng)站的性能瓶頸和排查一個程序的性能瓶頸的手法基本相同:檢查請求處理的各個環(huán)節(jié)的日志,分析哪個環(huán)節(jié)響應(yīng)時間不合理、超過預(yù)期;然后檢查監(jiān)控數(shù)據(jù),分析影響性能的主要因素是內(nèi)存、磁盤、網(wǎng)絡(luò)、還是CPU,是代碼問題還是架構(gòu)設(shè)計不合理,或者系統(tǒng)資源確實不足。性能優(yōu)化定位產(chǎn)生性能問題的具體原因后,就需要進行性能優(yōu)化,根據(jù)網(wǎng)站分層架構(gòu),可分為Web前端性能優(yōu)化、應(yīng)用服務(wù)器性能優(yōu)化、存儲服務(wù)器性能優(yōu)化3大類。Web前端性能優(yōu)化一般說來Web前端指網(wǎng)站業(yè)務(wù)邏輯之前的部分,包括瀏覽器加載、網(wǎng)站視圖模型、圖片服務(wù)、CDN服務(wù)等,主要優(yōu)化手段有優(yōu)化瀏覽器訪問、使用反向代理、CDN等。瀏覽器訪問優(yōu)化減少http請求HTTP協(xié)議是無狀態(tài)的應(yīng)用層協(xié)議,意味著每次HTTP請求都需要建立通信鏈路、進行數(shù)據(jù)傳輸,而在服務(wù)器端,每個HTTP都需要啟動獨立的線程去處理。這些通信和服務(wù)的開銷都很昂貴,減少HTTP請求的數(shù)目可有效提高訪問性能。減少HTTP的主要手段是合并CSS、合并JavaScript、合并圖片。將瀏覽器一次訪問需要的JavaScript、CSS合并成一個文件,這樣瀏覽器就只需要一次請求。圖片也可以合并,多張圖片合并成一張,如果每張圖片都有不同的超鏈接,可通過CSS偏移響應(yīng)鼠標(biāo)點擊操作,構(gòu)造不同的URL。使用瀏覽器緩存對一個網(wǎng)站而言,CSS、JavaScript、Logo、圖標(biāo)這些靜態(tài)資源文件更新的頻率都比較低,而這些文件又幾乎是每次HTTP以極好地改善性能。通過設(shè)置HTTP頭中Cache-Control和Expires的屬性,可設(shè)定瀏覽器緩存,緩存時間可以是數(shù)天,甚至是幾個月。在某些時候,靜態(tài)資源文件變化需要及時應(yīng)用到客戶端瀏覽器,這種情況,可通過改變文件名實現(xiàn),即更新JavaScript文件并不是更新JavaScript文件內(nèi)容,而是生成一個新的JS文件并更新HTML文件中的引用。使用瀏覽器緩存策略的網(wǎng)站在更新靜態(tài)資源時,應(yīng)采用批量更新的方法,比如需要更新個圖標(biāo)文件,不宜把10定的間隔時間,以免用戶瀏覽器突然大量緩存失效,集中更新緩存,造成服務(wù)器負(fù)載驟增、網(wǎng)絡(luò)堵塞的情況。啟用壓縮在服務(wù)器端對文件進行壓縮,在瀏覽器端對文件解壓縮,可有效減少通信傳輸?shù)臄?shù)據(jù)量。文本文件的壓縮效率可達80%以上,因此HTML、CSS、JavaScript文件啟用GZip壓縮可達到較好的效果。但是壓縮對服務(wù)器和瀏覽器產(chǎn)生一定的壓力,在通信帶寬良好,而服務(wù)器資源不足的情況下要權(quán)衡考慮。CSS放在頁面最上面、JavaScript放在頁面最下面瀏覽器會在下載完全部CSS之后才對整個頁面進行渲染,因此最好的做法是將CSS放在頁面最上面,讓瀏覽器盡快下載CSS。JavaScript則相反,瀏覽器在加載JavaScript后立即執(zhí)行,有可能會阻塞整個頁面,造成頁面顯示緩慢,因此JavaScript最好放在頁面最下面。但如果頁面解析時就需要用到JavaScript,這時放在底部就不合適了。減少Cookie傳輸一方面,Cookie包含在每次請求和響應(yīng)中,太大的Cookie會嚴(yán)重影響數(shù)據(jù)傳輸,因此哪些數(shù)據(jù)需要寫入Cookie需要慎重考慮,盡量減少Cookie中傳輸?shù)臄?shù)據(jù)量。另一方面,對于某些靜態(tài)資源的訪問,如CSS、Script等,發(fā)送Cookie沒有意義,可以考慮靜態(tài)資源使用獨立域名訪問,避免請求靜態(tài)資源時發(fā)送Cookie,減少Cookie傳輸?shù)拇螖?shù)。CDN加速CDN(ContentDistributeNetwork,內(nèi)容分發(fā)網(wǎng)絡(luò))的本質(zhì)仍然是一個緩存,而且將數(shù)據(jù)緩存在離用戶最近的地方,使用戶以最快速度獲取數(shù)據(jù),即所謂網(wǎng)絡(luò)訪問第一跳,如圖4.5所示。由于CDN部署在網(wǎng)絡(luò)運營商的機房,這些運營商又是終端用戶的網(wǎng)絡(luò)服務(wù)提供商,因此用戶請求路由的第一跳就到達了CDN服務(wù)器,當(dāng)CDN中存在瀏覽器請求的資源時,從CDN直接返回給瀏覽器,最短路徑返回響應(yīng),加快用戶訪問速度,減少數(shù)據(jù)中心負(fù)載壓力。圖4.5 利用CDN的網(wǎng)站架構(gòu)CDN能夠緩存的一般是靜態(tài)資源,如圖片、文件、CSS、Script腳本、靜態(tài)網(wǎng)頁等,但是這些文件訪問頻度很高,將其緩存在CDN可極大改善網(wǎng)頁的打開速度。反向代理傳統(tǒng)代理服務(wù)器位于瀏覽器一側(cè),代理瀏覽器將HTTP請求發(fā)送到互聯(lián)網(wǎng)上,而反向代理服務(wù)器位于網(wǎng)站機房一側(cè),代理網(wǎng)站W(wǎng)eb服務(wù)器接收HTTP請求。如圖4.6所示。圖4.6 利用反向代理的網(wǎng)站架構(gòu)和傳統(tǒng)代理服務(wù)器可以保護瀏覽器安全一樣,反向代理服務(wù)器也具有保護網(wǎng)站安全的作用,來自互聯(lián)網(wǎng)的訪問請求必須經(jīng)過代理服務(wù)器,相當(dāng)于在Web服務(wù)器和可能的網(wǎng)絡(luò)攻擊之間建立了一個屏障。除了安全功能,代理服務(wù)器也可以通過配置緩存功能加速Web請求。當(dāng)用戶第一次訪問靜態(tài)內(nèi)容的時候,靜態(tài)內(nèi)容就被緩存在反向代理服務(wù)器上,這樣當(dāng)其他用戶訪問該靜態(tài)內(nèi)容的時候,就可以直接從反向代理服務(wù)器返回,加速Web請求響應(yīng)速度,減輕Web服務(wù)器負(fù)載壓力。事實上,有些網(wǎng)站會把動態(tài)內(nèi)容也緩存在代理服務(wù)器上,比如維基百科及某些博客論壇網(wǎng)站,把熱門詞條、帖子、博客緩存在反向代理服務(wù)器上加速用戶訪問速度,當(dāng)這些動態(tài)內(nèi)容有變化時,通過內(nèi)部通知機制通知反向代理緩存失效,反向代理會重新加載最新的動態(tài)內(nèi)容再次緩存起來。此外,反向代理也可以實現(xiàn)負(fù)載均衡的功能,而通過負(fù)載均衡構(gòu)建的應(yīng)用集群可以提高系統(tǒng)總體處理能力,進而改善網(wǎng)站高并發(fā)情況下的性能。應(yīng)用服務(wù)器性能優(yōu)化應(yīng)用服務(wù)器就是處理網(wǎng)站業(yè)務(wù)的服務(wù)器,網(wǎng)站的業(yè)務(wù)代碼都部署在這里,是網(wǎng)站開發(fā)最復(fù)雜,變化最多的地方,優(yōu)化手段主要有緩存、集群、異步等。分布式緩存服務(wù)器;既可以對數(shù)據(jù)緩存,也可以對文件緩存,還可以對頁面片段緩存。合理使用緩存,對網(wǎng)站性能優(yōu)化意義重大。網(wǎng)站性能優(yōu)化第一定律:優(yōu)先考慮使用緩存優(yōu)化性能。緩存的基本原理緩存指將數(shù)據(jù)存儲在相對較高訪問速度的存儲介質(zhì)中,以供系統(tǒng)處理。一方面緩存訪問速度快,可以減少數(shù)據(jù)訪問的時間,另一方面如果緩存的數(shù)據(jù)是經(jīng)過計算處理得到的,那么被緩存的數(shù)據(jù)無需重復(fù)計算即可直接使用,因此緩存還起到減少計算時間的作用。緩存的本質(zhì)是一個內(nèi)存Hash表,網(wǎng)站應(yīng)用中,數(shù)據(jù)緩存以一對Key、Value的形式存儲在內(nèi)存Hash表中。Hash表數(shù)據(jù)讀寫的時間復(fù)雜度為O(1)4.7為一對KV在Hash表中的存儲。計算KV對中Key的HashCode對應(yīng)的Hash表索引,可快速訪問Hash表中的數(shù)據(jù)。許多語言支持獲得任意對象的HashCode,可以把HashCode理解為對象的唯一標(biāo)示符,Java語言中Hashcode方法包含在根對象Object中,其返回值是一個Int。然后通過Hashcode計算Hash表的索引下標(biāo),最簡單的是余數(shù)法,使用Hash表數(shù)組長度對Hashcode求余,余數(shù)即為Hash表索引,使用該索引可直接訪問得到Hash表中存儲的KV對。Hash表是軟件開發(fā)中常用到的一種數(shù)據(jù)結(jié)構(gòu),其設(shè)計思想在很多場景下都可以應(yīng)用。圖4.7Hash表存儲例子緩存主要用來存放那些讀寫比很高、很少變化的數(shù)據(jù),如商品的類目信息,熱門詞的搜索列表信息,熱門商品信息等。應(yīng)用程序讀取數(shù)據(jù)時,先到緩存中讀取,如果讀取不到或數(shù)據(jù)已失效,再訪問數(shù)據(jù)庫,并將數(shù)據(jù)寫入緩存,如圖4.8所示。圖4.8 使用緩存存取數(shù)據(jù)網(wǎng)站數(shù)據(jù)訪問通常遵循二八定律,即80%的訪問落在20%的數(shù)據(jù)上,因此利用Hash表和內(nèi)存的高速訪問特性,將這20%的數(shù)據(jù)緩存起來,可很好地改善系統(tǒng)性能,提高數(shù)據(jù)讀取速度,降低存儲訪問壓力。合理使用緩存使用緩存對提高系統(tǒng)性能有很多好處,但是不合理使用緩存非但不能提高系統(tǒng)的性能,還會成為系統(tǒng)的累贅,甚至風(fēng)險。實踐中,緩存濫用的情景屢見不鮮——過分依賴低可用的緩存系統(tǒng)、不恰當(dāng)?shù)厥褂镁彺娴臄?shù)據(jù)訪問特性等。頻繁修改的數(shù)據(jù)如果緩存中保存的是頻繁修改的數(shù)據(jù),就會出現(xiàn)數(shù)據(jù)寫入緩存后,應(yīng)用還來不及讀取緩存,數(shù)據(jù)就已失效的情形,徒增系統(tǒng)負(fù)擔(dān)。一般說來,數(shù)據(jù)的讀寫比在2:1以上,即寫入一次緩存,在數(shù)據(jù)更新前至少讀取兩次,緩存才有意義。實踐中,這個讀寫比通常非常高,比如新浪微博的熱門微博,緩存以后可能會被讀取數(shù)百萬次。沒有熱點的訪問緩存使用內(nèi)存作為存儲,內(nèi)存資源寶貴而有限,不可能將所有數(shù)據(jù)都緩存起來,只能將最新訪問的數(shù)據(jù)緩存起來,而將歷史數(shù)據(jù)清理出緩存。如果應(yīng)用系統(tǒng)訪問數(shù)據(jù)沒有熱點,不遵循二八定律,即大部分?jǐn)?shù)據(jù)訪問并沒有集中在小部分?jǐn)?shù)據(jù)上,那么緩存就沒有意義,因為大部分?jǐn)?shù)據(jù)還沒有被再次訪問就已經(jīng)被擠出緩存了。數(shù)據(jù)不一致與臟讀性的問題。緩存可用性緩存是為提高數(shù)據(jù)讀取性能的,緩存數(shù)據(jù)丟失或者緩存不可用不會影響到應(yīng)用程序的處理——它可以從數(shù)據(jù)庫直接獲取數(shù)據(jù)。但是隨著業(yè)務(wù)的發(fā)展,緩存會承擔(dān)大部分?jǐn)?shù)據(jù)訪問的壓力,數(shù)據(jù)庫已經(jīng)習(xí)慣了有緩存的日子,所以當(dāng)緩存服務(wù)崩潰時,數(shù)據(jù)庫會因為完全不能承受如此大的壓力而宕機,進而導(dǎo)致整個網(wǎng)站不可用。這種情況被稱作緩存雪崩,發(fā)生這種故障,甚至不能簡單地重啟緩存服務(wù)器和數(shù)據(jù)庫服務(wù)器來恢復(fù)網(wǎng)站訪問。實踐中,有的網(wǎng)站通過緩存熱備等手段提高緩存可用性:當(dāng)某臺緩存服務(wù)器宕機時,將緩存訪問切換到熱備服務(wù)器上。但是這種設(shè)計顯然有違緩存的初衷,緩存根本就不應(yīng)該被當(dāng)做一個可靠的數(shù)據(jù)源來使用。通過分布式緩存服務(wù)器集群,將緩存數(shù)據(jù)分布到集群多臺服務(wù)器上可在一定程度上改善緩存的可用性。當(dāng)一臺緩存服務(wù)器宕機的時候,只有部分緩存數(shù)據(jù)丟失,重新從數(shù)據(jù)庫加載這部分?jǐn)?shù)據(jù)不會對數(shù)據(jù)庫產(chǎn)生很大影響。產(chǎn)品在設(shè)計之初就需要一個明確的定位:什么是產(chǎn)品要實現(xiàn)的功能,什么不是產(chǎn)品提供的特性。在產(chǎn)品漫長的生命周期中,會有形形色色的困難和誘惑來改變產(chǎn)品的發(fā)展方向,左右搖擺、什么都想做的產(chǎn)品,最后有可能成為一個失去生命力的四不像。緩存預(yù)熱緩存中存放的是熱點數(shù)據(jù),熱點數(shù)據(jù)又是緩存系統(tǒng)利用LRU(最近最久未用算法)存系統(tǒng)啟動時就把熱點數(shù)據(jù)加載好,這個緩存預(yù)加載手段叫作緩存預(yù)熱(warmup)行預(yù)熱。緩存穿透如果因為不恰當(dāng)?shù)臉I(yè)務(wù)、或者惡意攻擊持續(xù)高并發(fā)地請求某個不存在的數(shù)據(jù),由于緩存沒有保存該數(shù)據(jù),所有的請求都會落到數(shù)據(jù)庫上,會對數(shù)據(jù)庫造成很大壓力,甚至崩潰。一個簡單的對策是將不存在的數(shù)據(jù)也緩存起來(其value值為null)。分布式緩存架構(gòu)分布式緩存指緩存部署在多個服務(wù)器組成的集群中,以集群方式提供緩存服務(wù),其架構(gòu)方式有兩種,一種是以JBossCache為代表的需要更新同步的分布式緩存,一種是以Memcached為代表的不互相通信的分布式緩存。JBossCache的分布式緩存在集群中所有服務(wù)器中保存相同的緩存數(shù)據(jù),當(dāng)某臺服務(wù)器有緩存數(shù)據(jù)更新的時候,會通知集群中其他機器更新緩存數(shù)據(jù)或清除緩存數(shù)據(jù),如圖4.9所示。JBossCache通常將應(yīng)用程序和緩存部署在同一臺服務(wù)器上,應(yīng)用程序可從本地快速獲取緩存數(shù)據(jù),但是這種方式帶來的問題是緩存數(shù)據(jù)的數(shù)量受限于單一服務(wù)器的內(nèi)存空因而這種方案更多見于企業(yè)應(yīng)用系統(tǒng)中,而很少在大型網(wǎng)站使用。圖4.9 需要更新同步的JBossCache大型網(wǎng)站需要緩存的數(shù)據(jù)量一般都很龐大,可能會需要數(shù)TB的內(nèi)存做緩存,這時候就需要另一種分布式緩存,如圖4.10所示。Memcached采用一種集中式的緩存集群管理,也被稱作互不通信的分布式架構(gòu)方式。緩存與應(yīng)用分離部署,緩存系統(tǒng)部署在一組專門的服務(wù)器上,應(yīng)用程序通過一致性Hash等路由算法選擇緩存服務(wù)器遠程訪問緩存數(shù)據(jù),緩存服務(wù)器之間不通信,緩存集群的規(guī)模可以很容易地實現(xiàn)擴容,具有良好的可伸縮性。Memcached的伸縮性設(shè)計參考本書第6章內(nèi)容。4.MemcachedMemcached曾一度是網(wǎng)站分布式緩存的代名詞,被大量網(wǎng)站使用。其簡單的設(shè)計、優(yōu)異的性能、互不通信的服務(wù)器集群、海量數(shù)據(jù)可伸縮的架構(gòu)令網(wǎng)站架構(gòu)師們趨之若鶩。圖4.10 互相通信的Memcached簡單的通信協(xié)議遠程通信設(shè)計需要考慮兩方面的要素,一是通信協(xié)議,即選擇TCP協(xié)議還是UDP協(xié)議,抑或HTTP協(xié)議;一是通信序列化協(xié)議,數(shù)據(jù)傳輸?shù)膬啥?,必須使用彼此可識別的數(shù)據(jù)序列化方式才能使通信得以完成,如XML、JSON等文本序列化協(xié)議,或者GoogleProtobuffer等二進制序列化協(xié)議。Memcached使用TCP協(xié)議(UDP也支持)通信,其序列化協(xié)議則是一套基于文本的自定義協(xié)議,非常簡單,以一個命令關(guān)鍵字開頭,后面是一組命令操作數(shù)。例如讀取一個數(shù)據(jù)的命令協(xié)議是get﹤key﹥。Memcached以后,許多NoSQL產(chǎn)品都借鑒了或直接支持這套協(xié)議。豐富的客戶端程序Memcached通信協(xié)議非常簡單,只要支持該協(xié)議的客戶端都可以和Memcached服務(wù)器通信,因此MemcachedJava、C/C++/C#、Perl、Python、PHP、Ruby等,因此在混合使用多種編程語言的網(wǎng)站,Memcached更是如魚得水。高性能的網(wǎng)絡(luò)通信Memcached服務(wù)端通信模塊基于Libevent,一個支持事件觸發(fā)的網(wǎng)絡(luò)通信程序庫。Libevent的設(shè)計和實現(xiàn)有許多值得改善的地方,但它在穩(wěn)定的長連接方面的表現(xiàn)卻正是Memcached需要的。高效的內(nèi)存管理想了許多辦法:壓縮、復(fù)制等。Memcached使用了一個非常簡單的辦法——固定空間分配。Memcached將內(nèi)存空間分為一組slab,每個slab里又包含一組chunk,同一個slab里的每個chunk的大小是固定的,擁有相同大小chunk的slab被組織在一起,叫作slab_class,如圖4.11所示。存儲數(shù)據(jù)時根據(jù)數(shù)據(jù)的Size大小,尋找一個大于Size的最小chunk將數(shù)據(jù)寫入。這種內(nèi)存管理方式避免了內(nèi)存碎片管理的問題,內(nèi)存的分配和釋放都是以chunk為單位的。和其他緩存一樣,Memcached采用LRU算法釋放最近最久未被訪問的數(shù)據(jù)占用的空間,釋放的chunk被標(biāo)記為未用,等待下一個合適大小數(shù)據(jù)的寫入。當(dāng)然這種方式也會帶來內(nèi)存浪費的問題。數(shù)據(jù)只能存入一個比它大的chunk里,而一個chunk只能存一個數(shù)據(jù),其他空間被浪費了。如果啟動參數(shù)配置不合理,浪費會更加驚人,發(fā)現(xiàn)沒有緩存多少數(shù)據(jù),內(nèi)存空間就用盡了。圖4.11 Memcached內(nèi)存管理互不通信的服務(wù)器集群架構(gòu)如上所述,正是這個特性使得Memcached從JBossCache、OSCache等眾多分布式緩存產(chǎn)品中脫穎而出,滿足網(wǎng)站對海量緩存數(shù)據(jù)的需求。而其客戶端路由算法一致性Hash更成為數(shù)據(jù)存儲伸縮性架構(gòu)設(shè)計的經(jīng)典范式(參考本書第6章)基本架構(gòu)特點。雖然近些年許多NoSQL產(chǎn)品層出不窮,在數(shù)據(jù)持久化、支持復(fù)雜數(shù)據(jù)結(jié)構(gòu)、甚至性能方面有許多產(chǎn)品優(yōu)于Memcached,但Memcached由于其簡單、穩(wěn)定、專注的特點,仍然在分布式緩存領(lǐng)域占據(jù)著重要地位。異步操作使用消息隊列將調(diào)用異步化,可改善網(wǎng)站的擴展性(參考本書第7章內(nèi)容)。事實上,使用消息隊列還可改善網(wǎng)站系統(tǒng)的性能,如圖4.12和圖4.13所示。圖4.12 不使用消息隊列服務(wù)器圖4.13 使用消息隊列服務(wù)器在不使用消息隊列的情況下,用戶的請求數(shù)據(jù)直接寫入數(shù)據(jù)庫,在高并發(fā)的情況下,會對數(shù)據(jù)庫造成巨大的壓力,同時也使得響應(yīng)延遲加劇。在使用消息隊列后,用戶請求的數(shù)據(jù)發(fā)送給消息隊列后立即返回,再由消息隊列的消費者進程(通常情況下,該進程通常獨立部署在專門的服務(wù)器集群上)從消息隊列中獲取數(shù)據(jù),異步寫入數(shù)據(jù)庫。由于消息隊列服務(wù)器處理速度遠快于數(shù)據(jù)庫(消息隊列服務(wù)器也比數(shù)據(jù)庫具有更好的伸縮性),因此用戶的響應(yīng)延遲可得到有效改善。消息隊列具有很好的削峰作用——即通過異步處理,將短時間高并發(fā)產(chǎn)生的事務(wù)消息存儲在消息隊列中,從而削平高峰期的并發(fā)事務(wù)。在電子商務(wù)網(wǎng)站促銷活動中,合理使用消息隊列,可有效抵御促銷活動剛開始大量涌入的訂單對系統(tǒng)造成的沖擊。如圖4.14所示。圖4.14 使用消息隊列消除并發(fā)訪問高峰需要注意的是,由于數(shù)據(jù)寫入消息隊列后立即返回給用戶,數(shù)據(jù)在后續(xù)的業(yè)務(wù)校驗、寫數(shù)據(jù)庫等操作可能失敗,因此在使用消息隊列進行業(yè)務(wù)異步處理后,需要適當(dāng)修改業(yè)務(wù)流程進行配合,如訂單提交后,訂單數(shù)據(jù)寫入消息隊列,不能立即返回用戶訂單提交成功,需要在消息隊列的訂單消費者進程真正處理完該訂單,甚至商品出庫后,再通過電子郵件或SMS消息通知用戶訂單成功,以免交易糾紛。任何可以晚點做的事情都應(yīng)該晚點再做。使用集群在網(wǎng)站高并發(fā)訪問的場景下,使用負(fù)載均衡技術(shù)為一個應(yīng)用構(gòu)建一個由多臺服務(wù)器組成的服務(wù)器集群,將并發(fā)訪問請求分發(fā)到多臺服務(wù)器上處理,避免單一服務(wù)器因負(fù)載壓力過大而響應(yīng)緩慢,使用戶請求具有更好的響應(yīng)延遲特性,如圖4.15所示。圖4.15 利用負(fù)載均衡技術(shù)改善性能三臺Web服務(wù)器共同處理來自用戶瀏覽器的訪問請求,這樣每臺Web服務(wù)器需要處理的http請求只有總并發(fā)請求數(shù)的三分之一,根據(jù)性能測試曲線,使服務(wù)器的并發(fā)請求數(shù)目控制在最佳運行區(qū)間,獲得最佳的訪問請求延遲。代碼優(yōu)化網(wǎng)站的業(yè)務(wù)邏輯實現(xiàn)代碼主要部署在應(yīng)用服務(wù)器上,需要處理復(fù)雜的并發(fā)事務(wù)。合理優(yōu)化業(yè)務(wù)代碼,可以很好地改善網(wǎng)站性能。不同編程語言的代碼優(yōu)化手段有很多,這里我們概要地關(guān)注比較重要的幾個方面。多線程多用戶并發(fā)訪問是網(wǎng)站的基本需求,大型網(wǎng)站的并發(fā)用戶數(shù)會達到數(shù)萬,單臺服務(wù)器的并發(fā)用戶也會達到數(shù)百。CGI編程時代,每個用戶請求都會創(chuàng)建一個獨立的系統(tǒng)進程去處理。由于線程比進程更輕量,更少占有系統(tǒng)資源,切換代價更小,所以目前主要的Web應(yīng)用服務(wù)器都采用多線程的方式響應(yīng)并發(fā)用戶請求,因此網(wǎng)站開發(fā)天然就是多線程編程。從資源利用的角度看,使用多線程的原因主要有兩個:IO阻塞與多CPU。當(dāng)前線程進行IO處理的時候,會被阻塞釋放CPU以等待IO操作完成,由于IO操作(不管是磁盤IO還是網(wǎng)絡(luò)IO)通常都需要較長的時間,這時CPU可以調(diào)度其他的線程進行處理。前面我們提到,理想的系統(tǒng)Load是既沒有進程(線程)等待也沒有CPU空閑,利用多線程IO阻塞與執(zhí)行交替進行,可最大限度地利用CPU資源。使用多線程的另一個原因是服務(wù)器有多個CPU,在這個連手機都有四核CPU的時代,除了最低配置的虛擬機,一般數(shù)據(jù)中心的服務(wù)器至少16核CPU,要想最大限度地使用這些CPU,必須啟動多線程。網(wǎng)站的應(yīng)用程序一般都被Web服務(wù)器容器管理,用戶請求的多線程也通常被Web服務(wù)器容器管理,但不管是Web容器管理的線程,還是應(yīng)用程序自己創(chuàng)建的線程,一臺服務(wù)器上啟動多少線程合適呢?假設(shè)服務(wù)器上執(zhí)行的都是相同類型任務(wù),針對該類任務(wù)啟動的線程數(shù)有個簡化的估算公式可供參考:啟動線程數(shù)=[任務(wù)執(zhí)行時間/(任務(wù)執(zhí)行時間-IO等待時間)]′CPU內(nèi)核數(shù)最佳啟動線程數(shù)和CPU內(nèi)核數(shù)量成正比,和IO阻塞時間成反比。如果任務(wù)都是CPU計算型任務(wù),那么線程數(shù)最多不超過CPU內(nèi)核數(shù),因為啟動再多線程,CPU也來不及調(diào)度;相反如果是任務(wù)需要等待磁盤操作,網(wǎng)絡(luò)響應(yīng),那么多啟動線程有助于提高任務(wù)并發(fā)度,提高系統(tǒng)吞吐能力,改善系統(tǒng)性能。多線程編程一個需要注意的問題是線程安全問題,即多線程并發(fā)對某個資源進行修改,導(dǎo)致數(shù)據(jù)混亂。這也是缺乏經(jīng)驗的網(wǎng)站工程師最容易犯錯的地方,而線程安全Bug又難以測試和重現(xiàn),網(wǎng)站故障中,許多所謂偶然發(fā)生的“靈異事件”都和多線程并發(fā)問題有關(guān)。對網(wǎng)站而言,不管有沒有進行多線程編程,工程師寫的每一行代碼都會被多線程執(zhí)行,因為用戶請求是并發(fā)提交的,也就是說,所有的資源——對象、內(nèi)存、文件、數(shù)據(jù)庫,乃至另一個線程都可能被多線程并發(fā)訪問。編程上,解決線程安全的主要手段有如下幾點。將對象設(shè)計為無狀態(tài)對象:所謂無狀態(tài)對象是指對象本身不存儲狀態(tài)信息(量,或者成員變量也是無狀態(tài)對象)Web開發(fā)中常用的

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論