我們以淘寶架構(gòu)為例,了解下大型的電商項(xiàng)目的服務(wù)端的架構(gòu)是怎樣,如下圖所示:
上面是一些安全體系系統(tǒng),如數(shù)據(jù)安全體系、應(yīng)用安全體系、前端安全體系等。
中間是業(yè)務(wù)運(yùn)營(yíng)服務(wù)系統(tǒng),如會(huì)員服務(wù)、商品服務(wù)、店鋪服務(wù)、交易服務(wù)等。
還有共享業(yè)務(wù),如分布式數(shù)據(jù)層、數(shù)據(jù)分析服務(wù)、配置服務(wù)、數(shù)據(jù)搜索服務(wù)等。
下面呢,是中間件服務(wù),如MQS即隊(duì)列服務(wù),OCS即緩存服務(wù)等。
圖中也有一些看不到,例如高可用的一個(gè)體現(xiàn),實(shí)現(xiàn)雙機(jī)房容災(zāi)和異地機(jī)房單元化部署,為淘寶業(yè)務(wù)提供穩(wěn)定、高效和易于維護(hù)的基礎(chǔ)架構(gòu)支撐。
這是一個(gè)含金量非常高的架構(gòu),也是一個(gè)非常復(fù)雜而龐大的架構(gòu)。當(dāng)然這個(gè)也不是一天兩天演進(jìn)成這樣的,也不是一上來就設(shè)計(jì)并開發(fā)成這樣高大上的架構(gòu)的。
這邊就要說一下,小型公司要怎么做呢?對(duì)很多創(chuàng)業(yè)公司而言,很難在初期就預(yù)估到流量十倍、百倍以及千倍以后網(wǎng)站架構(gòu)會(huì)是什么樣的一個(gè)狀況。同時(shí),如果系統(tǒng)初期就設(shè)計(jì)一個(gè)千萬級(jí)并發(fā)的流量架構(gòu),很難有公司可以支撐這個(gè)成本。
因此,一個(gè)大型服務(wù)系統(tǒng)都是從小一步一步走過來的,在每個(gè)階段,找到對(duì)應(yīng)該階段網(wǎng)站架構(gòu)所面臨的問題,然后在不斷解決這些問題,在這個(gè)過程中整個(gè)架構(gòu)會(huì)一直演進(jìn)。
那我們來一起看一下。
從一個(gè)小網(wǎng)站說起。一臺(tái)服務(wù)器也就足夠了。文件服務(wù)器,數(shù)據(jù)庫(kù),還有應(yīng)用都部署在一臺(tái)機(jī)器,俗稱ALL IN ONE。
隨著我們用戶越來越多,訪問越來越大,硬盤,CPU,內(nèi)存等都開始吃緊,一臺(tái)服務(wù)器已經(jīng)滿足不了。
這個(gè)時(shí)候看一下下一步演進(jìn)。
我們將數(shù)據(jù)服務(wù)和應(yīng)用服務(wù)分離,給應(yīng)用服務(wù)器配置更好的 CPU,內(nèi)存。而給數(shù)據(jù)服務(wù)器配置更好更大的硬盤。
分離之后提高一定的可用性,例如Files Server掛了,我們還是可以操作應(yīng)用和數(shù)據(jù)庫(kù)等。
隨著訪問qps越來越高,降低接口訪問時(shí)間,提高服務(wù)性能和并發(fā),成為了我們下一個(gè)目標(biāo),發(fā)現(xiàn)有很多業(yè)務(wù)數(shù)據(jù)不需要每次都從數(shù)據(jù)庫(kù)獲取。
因?yàn)?80% 的業(yè)務(wù)訪問都集中在 20% 的數(shù)據(jù)上,也就是我們經(jīng)常說的28法則。如果我們能將這部分?jǐn)?shù)據(jù)緩存下來,性能一下子就上來了。而緩存又分為兩種:本地緩存和遠(yuǎn)程緩存緩存,以及遠(yuǎn)程分布式緩存,我們這里面的遠(yuǎn)程緩存圖上畫的是分布式的緩存集群(Cluster)。
這個(gè)時(shí)候隨著訪問qps的提高,服務(wù)器的處理能力會(huì)成為瓶頸。雖然是可以通過購(gòu)買更強(qiáng)大的硬件,但總會(huì)有上限,而且這個(gè)到后期成本就是指數(shù)級(jí)增長(zhǎng)了,這時(shí),我們就需要服務(wù)器的集群。需要使我們的服務(wù)器可以橫向擴(kuò)展,這時(shí),就必須加個(gè)新東西:負(fù)載均衡調(diào)度服務(wù)器。
增加了負(fù)載均衡,服務(wù)器集群之后,我們可以橫向擴(kuò)展服務(wù)器,解決了服務(wù)器處理能力的瓶頸。
打個(gè)比方,我們有輪詢,權(quán)重,地址散列,地址散列又分為原ip地址散列hash,目標(biāo)ip地址散列hash,少連接,加權(quán)少連接,還有繼續(xù)升級(jí)的很多種策略……
我們一起來分析一下。
我們的登錄的時(shí)候登錄了A服務(wù)器,session信息存儲(chǔ)到A服務(wù)器上了,假設(shè)我們使用的負(fù)載均衡策略是ip hash,那么登錄信息還可以從A服務(wù)器上訪問,但是這個(gè)有可能造成某些服務(wù)器壓力過大,某些服務(wù)器又沒有什么壓力,這個(gè)時(shí)候壓力過大的機(jī)器(包括網(wǎng)卡帶寬)有可能成為瓶頸,并且請(qǐng)求不夠分散。
這時(shí)候我們使用輪詢或者小連接負(fù)載均衡策略,就導(dǎo)致了,次訪問A服務(wù)器,第二次可能訪問到B服務(wù)器,這個(gè)時(shí)候存儲(chǔ)在A服務(wù)器上的session信息在B服務(wù)器上讀取不到。
打個(gè)比方就是如果我們每次吃飯都要保證我們用的是自己的碗筷,而只要我們?cè)谝患绎埖昀锎嬷覀兊耐肟辏灰覀兠看稳ミ@家飯店吃飯就好了。
對(duì)于同一個(gè)連接中的數(shù)據(jù)包,負(fù)載均衡會(huì)將其轉(zhuǎn)發(fā)至后端固定的服務(wù)器進(jìn)行處理。
解決了我們session共享的問題,但是它有什么缺點(diǎn)呢?
就像我們?cè)谒械娘埖昀锒即嬉环葑约旱耐肟辍N覀冸S意去哪一家飯店吃飯都OK,不適合做大規(guī)模集群,適合機(jī)器不多的情況。
解決了我們session共享的問題,但是它有什么缺點(diǎn)呢?
打個(gè)比方,就是我們每次去飯店吃飯,都自己帶著自己的碗筷。
解決了我們session共享的問題,但是它有什么缺點(diǎn)呢?
打個(gè)比方,就是我們的碗筷都存在了一個(gè)龐大的櫥柜里,我們?nèi)ト魏我患绎埖瓿燥垼伎梢詮臋还裰心玫綄儆谖覀冏约旱耐肟辍?
解決了我們session共享的問題,這種方案需要思考哪些問題呢?
打個(gè)比方,我們?yōu)榱颂岣遱ession server的可用性,可以繼續(xù)給session server做集群。
所以說,網(wǎng)站架構(gòu)在遇到某些指標(biāo)瓶頸時(shí),演進(jìn)的過程中,都有哪些解決方案,他們都有什么優(yōu)缺點(diǎn)?業(yè)務(wù)功能上如何取舍?如何做出選擇?這個(gè)過程才是重要的。
在解決了橫向擴(kuò)展應(yīng)用服務(wù)器之后,那我們繼續(xù)~~
數(shù)據(jù)庫(kù)的讀及寫操作都還需要經(jīng)過數(shù)據(jù)庫(kù)。當(dāng)用戶量達(dá)到一定量,數(shù)據(jù)庫(kù)將會(huì)成為瓶頸。那我們?nèi)绾蝸斫鉀Q呢?
使用數(shù)據(jù)庫(kù)提供的熱備功能,將所有的讀操作引入slave 服務(wù)器,因?yàn)閿?shù)據(jù)庫(kù)的讀寫分離了,所以,我們的應(yīng)用程序也得做相應(yīng)的變化。我們實(shí)現(xiàn)一個(gè)數(shù)據(jù)訪問模塊(圖中的data access module)使上層寫代碼的人不知道讀寫分離的存在。這樣多數(shù)據(jù)源讀寫分離就對(duì)業(yè)務(wù)代碼沒有了侵入。這里就引出了代碼層次的演變。
數(shù)據(jù)庫(kù)讀寫分離會(huì)遇到如下問題:
使用 CDN 可以很好的解決不同的地區(qū)的訪問速度問題,反向代理則在服務(wù)器機(jī)房中緩存用戶資源。
訪問量越來越大,我們文件服務(wù)器也出現(xiàn)了瓶頸。
這個(gè)時(shí)候數(shù)據(jù)庫(kù)又出現(xiàn)了瓶頸。
數(shù)據(jù)庫(kù)專庫(kù)專用,如圖Products、Users、Deal庫(kù)。
解決寫數(shù)據(jù)時(shí),并發(fā),量大的問題。
這個(gè)時(shí)候,某個(gè)業(yè)務(wù)的數(shù)據(jù)表的數(shù)據(jù)量或者更新量達(dá)到了單個(gè)數(shù)據(jù)庫(kù)的瓶頸。
如圖,我們把User拆成了User1和User2,將同一個(gè)表的數(shù)據(jù)拆分到兩個(gè)數(shù)據(jù)庫(kù)中,解決了單數(shù)據(jù)庫(kù)的瓶頸。
這個(gè)時(shí)候,公司對(duì)外部做了流量導(dǎo)入,我們應(yīng)用中的搜索量飆升,繼續(xù)演進(jìn)。
使用搜索引擎,解決數(shù)據(jù)查詢問題。部分場(chǎng)景可使用 NoSQL 提高性能,開發(fā)數(shù)據(jù)統(tǒng)一訪問模塊,解決上層應(yīng)用開發(fā)的數(shù)據(jù)源問題。如圖data access module 可以訪問數(shù)據(jù)庫(kù),搜索引擎,NoSQL。
這個(gè)只是一個(gè)舉例演示,各個(gè)服務(wù)的技術(shù)架構(gòu)是需要根據(jù)自己業(yè)務(wù)特點(diǎn)進(jìn)行優(yōu)化和演進(jìn)的,所以大家的過程也不完全相同。
后的這個(gè)也不是完美的,例如負(fù)載均衡還是一個(gè)單點(diǎn),也需要集群,我們的這個(gè)架構(gòu)呢也只是冰山一角,滄海一粟。在架構(gòu)演進(jìn)的過程中,還要考慮系統(tǒng)的安全性、數(shù)據(jù)分析、監(jiān)控、反作弊等等……,同時(shí)繼續(xù)發(fā)展呢,SOA架構(gòu)、服務(wù)化、消息隊(duì)列、任務(wù)調(diào)度、多機(jī)房等等……
從剛才對(duì)架構(gòu)演進(jìn)的講解,也可以看出來,所有大型項(xiàng)目的架構(gòu)和代碼,都是這么一步一步的根據(jù)實(shí)際的業(yè)務(wù)場(chǎng)景,和發(fā)展情況發(fā)展演變而來的,在不同的階段,會(huì)使用的不同的技術(shù),不同的架構(gòu)來解決實(shí)際的問題,所以說,高大上的項(xiàng)目技術(shù)架構(gòu)和開發(fā)設(shè)計(jì)實(shí)現(xiàn)不是一蹴而就的。
正是所謂的萬丈高樓平地起。在架構(gòu)演進(jìn)的過程中,小到核心模塊代碼,大到核心架構(gòu),都會(huì)不斷演進(jìn)的,這個(gè)過程值得我們?nèi)ド钊雽W(xué)習(xí)和思考。一起加油吧~~
歡迎大家一起交流~
本站文章版權(quán)歸原作者及原出處所有 。內(nèi)容為作者個(gè)人觀點(diǎn), 并不代表本站贊同其觀點(diǎn)和對(duì)其真實(shí)性負(fù)責(zé),本站只提供參考并不構(gòu)成任何投資及應(yīng)用建議。本站是一個(gè)個(gè)人學(xué)習(xí)交流的平臺(tái),網(wǎng)站上部分文章為轉(zhuǎn)載,并不用于任何商業(yè)目的,我們已經(jīng)盡可能的對(duì)作者和來源進(jìn)行了通告,但是能力有限或疏忽,造成漏登,請(qǐng)及時(shí)聯(lián)系我們,我們將根據(jù)著作權(quán)人的要求,立即更正或者刪除有關(guān)內(nèi)容。本站擁有對(duì)此聲明的最終解釋權(quán)。