往往程序員在面試的時(shí)候,公司的面試任職資格上,總有一個(gè)大型系統(tǒng)網(wǎng)站的開發(fā)經(jīng)驗(yàn),我們先來看看幾張面試招聘信息截圖.......
大型網(wǎng)站定義
首先我們要思考一個(gè)問題,什么樣的網(wǎng)站才是大型網(wǎng)站,從網(wǎng)站的技術(shù)指標(biāo)角度考慮這個(gè)問題人們很容易犯一個(gè)毛病就是認(rèn)為網(wǎng)站的訪問量是衡量的指標(biāo),懂點(diǎn) 行的人也許會(huì)認(rèn)為是網(wǎng)站在單位時(shí)間里的并發(fā)量的大小來作為指標(biāo),如果按這些標(biāo)準(zhǔn)那么像hao123這樣的網(wǎng)站就是大型網(wǎng)站了,如下圖所示:
其實(shí)這種網(wǎng)站訪問量非常大,并發(fā)數(shù)也非常高,但是它卻能用最為簡單的Web技術(shù)來實(shí)現(xiàn):我們只要保持網(wǎng)站的充分的靜態(tài)化,多部署幾臺(tái)服務(wù)器,那么就算地球上所有人都用它,網(wǎng)站也能正常運(yùn)行。
大型網(wǎng)站是技術(shù)和業(yè)務(wù)的結(jié)合,一個(gè)滿足某些用戶需求的網(wǎng)站只要技術(shù)和業(yè)務(wù)二者有一方難度很大,必然會(huì)讓企業(yè)投入更多的、更優(yōu)秀的人力成本實(shí)現(xiàn)它,那么這樣的網(wǎng)站就是所謂的大型網(wǎng)站了。0
如何逐步去構(gòu)建一個(gè)大型網(wǎng)站系統(tǒng)
互聯(lián)網(wǎng)時(shí)代,怎么構(gòu)建一個(gè)大型網(wǎng)站是不可缺少的技能。當(dāng)然,本人目前接觸的網(wǎng)站都是讀遠(yuǎn)遠(yuǎn)大于寫。本文將一步步講訴,怎么去使用lamp構(gòu)建完善一個(gè)大型網(wǎng)站(讀大于寫)。
網(wǎng)站架構(gòu),我個(gè)人認(rèn)為最為重要的是兩方面的考慮:計(jì)算和存儲(chǔ)。有些是屬于計(jì)算密集型,有些是IO密集型。所以以下都將圍繞計(jì)算和存儲(chǔ)來講述問題。
1、最簡單的搭建
假設(shè)我們自己創(chuàng)業(yè)了,那么我們可能需要自己去搭建一個(gè)網(wǎng)站。
這個(gè)時(shí)候,我們需要去租借一個(gè)主機(jī)(比如阿里云的虛擬主機(jī)等)。對于網(wǎng)站來說,數(shù)據(jù)是最為重要的,所以需要有一個(gè)備份。但是每天pv肯定不高,所以理論上只需要一個(gè)計(jì)算機(jī)器即可。因此,我們只需要3臺(tái)機(jī)器就能完整一個(gè)完整的架構(gòu)。
從上圖可以看到計(jì)算機(jī)器上主要部署2部分內(nèi)容,一部分是webserver(輕量級可以考慮niginx,lighttpd等),一個(gè)是UI邏輯處理部分,lamp架構(gòu)則使用php語言來搞定這個(gè)問題。因?yàn)閿?shù)據(jù)是最重要的,所以database則明顯需要2臺(tái)機(jī)器,一臺(tái)主機(jī),一臺(tái)做冗余備份。lamp使用mysql來存儲(chǔ)數(shù)據(jù)。
2 增加數(shù)據(jù)緩存
隨著我們網(wǎng)站知名度變高,每天pv越來越大,導(dǎo)致的問題是數(shù)據(jù)庫壓力越來越大。很明顯,絕大部分網(wǎng)站,讀流量都遠(yuǎn)遠(yuǎn)高于寫流量。即使我們開了mysql的query cache,它也只能在一定程度上通過減少DB機(jī)器I的操作來減少DB服務(wù)器壓力。更為靠譜的是,減少對DB服務(wù)器的請求。那么這個(gè)時(shí)候就需要使用cache.
cache為非關(guān)系型kv存儲(chǔ),在使用過程中一般為內(nèi)存操作。下面的架構(gòu)改進(jìn)如下。
可以看出ui寫數(shù)據(jù)仍然直接寫入到數(shù)據(jù)庫,但是讀則先從cache讀取,cache讀取不到再從database讀取。因?yàn)楹苡锌赡艽蟛糠謹(jǐn)?shù)據(jù)都直接訪問cache就可以搞定,這樣就可以大大減少數(shù)據(jù)庫的壓力。
3、增加計(jì)算機(jī)器集群(計(jì)算方向)
隨著整個(gè)系統(tǒng)pv繼續(xù)上漲。單臺(tái)的計(jì)算機(jī)器已經(jīng)無法滿足要求。這個(gè)時(shí)候就需要使用增加計(jì)算機(jī)器來解決問題。為了方便起見,可以把這個(gè)機(jī)器放入一個(gè)集群進(jìn)行統(tǒng)一管理。
這個(gè)時(shí)候,我們可能需要考慮2個(gè)問題:負(fù)載均衡、數(shù)據(jù)同步。負(fù)載均衡系統(tǒng)相對難度較大,但是是必不可少的,最簡單的可以通過zookkeeper等對配置文件進(jìn)行統(tǒng)一管理。對于節(jié)點(diǎn)下的若干機(jī)器,可以簡單通過概率來進(jìn)行請求分發(fā)。數(shù)據(jù)同步也是一個(gè)難點(diǎn),比如session同步、文件操作等。
需要說明的是,好的架構(gòu)結(jié)果如下:N臺(tái)機(jī)器能撐住的PV為X,那么T*N臺(tái)機(jī)器基本能撐住T*X pv。換句話說,架構(gòu)必須能支持橫向擴(kuò)展。如果機(jī)器加了一倍,但是撐住的峰值pv不能增加(接近)一倍,那個(gè)這個(gè)架構(gòu)就是失敗的架構(gòu),不是可擴(kuò)展性的架構(gòu)。
可以看出的是在負(fù)載均衡系統(tǒng)下可以掛很多機(jī)器。好的擴(kuò)展是,加入多少倍機(jī)器,計(jì)算能力就相應(yīng)提高多少倍(暫時(shí)不考慮存儲(chǔ)的瓶頸)。
4、搭建簡單的數(shù)據(jù)庫集群(存儲(chǔ)方向)
流量上升,計(jì)算能力提升的同時(shí),也需要提升數(shù)據(jù)庫的能力。這時(shí)候,我們可以采用讀寫分離。也就有了主從之說。主庫可以寫,當(dāng)然也肯定能提供寫,從庫只能提供讀,我們目前主從延時(shí)在20ms以內(nèi)。目前這種工具不少,比如mysql proxy等。(下圖應(yīng)該是ui logic訪問dbproxy,圖有稍許錯(cuò)誤,但是不影響理解)。
如上圖,dbproxy作用主要有3個(gè):
1、讀寫分離。讀主要讀從庫,寫只能是寫主庫。我們在實(shí)際設(shè)計(jì)的時(shí)候需要考慮主從延時(shí),比如事務(wù)讀必須讀主庫,寫完若干秒內(nèi)最好讀主庫等等。
2、負(fù)載均衡。他能自動(dòng)根據(jù)dbproxy下面掛在的db進(jìn)行負(fù)載均衡。
3、dbproxy維持sql連接池,里面存在和db的長連接。請求過來之后,直接從連接池取連接即可。
5、靜態(tài)頁面跨地域緩存
很明顯,我們網(wǎng)站有很多靜態(tài)頁面,若干天才會(huì)更換一次。但是因?yàn)榭绲赜?、跨機(jī)房的問題,外地用戶可能訪問較慢,所以我們可以通過cdn等技術(shù)緩存靜態(tài)頁面。這樣就可以減少對服務(wù)器的請求,同時(shí)加快外地、不同機(jī)房用戶的訪問時(shí)間。
如上圖所示,加入了靜態(tài)頁面緩存
6、跨地域跨機(jī)房設(shè)計(jì)
當(dāng)我們業(yè)務(wù)進(jìn)一步擴(kuò)大,我們可能需要跨地域進(jìn)行機(jī)器部署,目前我們主要分為華北(北京)和華東機(jī)房(杭州、南京)。跨地域部署,可以加快因?yàn)閰^(qū)域帶來的訪問過慢問題。比如廣州訪問北京機(jī)房數(shù)據(jù),就不如北京訪問北京機(jī)房速度快。這個(gè)時(shí)候,還是主要分為計(jì)算和存儲(chǔ)兩方面進(jìn)行講述。
6.1 計(jì)算方向
除了該機(jī)房的標(biāo)示以外,各個(gè)機(jī)房的機(jī)器部署應(yīng)該完全一致。
6.2 存儲(chǔ)方向
在我看來,對于讀遠(yuǎn)遠(yuǎn)大于寫的系統(tǒng)而言,最好只有一個(gè)主庫,若干個(gè)從庫。所以只需要在其他機(jī)房搭建從庫,讓從庫從主庫進(jìn)行數(shù)據(jù)同步即可。當(dāng)然,這樣的代價(jià)是主從時(shí)間比比較長。在數(shù)據(jù)鏈路不穩(wěn)定的情況下,主從同步可能在400ms以上,所以設(shè)計(jì)需要考慮這個(gè)。
當(dāng)然cache等等也需要跨地域跨機(jī)房部署。
如圖簡要勾勒出了跨地域跨機(jī)房的一個(gè)部署方案。
7、通用服務(wù)的使用
隨著業(yè)務(wù)拓寬,我們可能會(huì)有一些需要考慮新能的模塊或者業(yè)務(wù)。
如搜索業(yè)務(wù),我們不可能直接通過數(shù)據(jù)庫的select like來實(shí)現(xiàn),就需要使用C等編譯型語言來搭建其他系統(tǒng)。所以需要我們根據(jù)業(yè)務(wù)進(jìn)行架構(gòu)調(diào)整來通過http等使用一些通用的高性能計(jì)算方向的服務(wù)。
同樣,出于業(yè)務(wù)發(fā)展等因素的考慮,我們需要使用內(nèi)存型的數(shù)據(jù)庫,比如redis等,這些屬于存儲(chǔ)方向的通用服務(wù)。
這些服務(wù),有的可以跨機(jī)房部署,各個(gè)機(jī)房無耦合,有的則相互之間有耦合,比如類似于數(shù)據(jù)庫的主庫從庫。
8、其他考慮
除此以外,我們還需要有其他因素進(jìn)行考慮。需要了解的可以加JAVA架構(gòu)師學(xué)術(shù)交流群:587372254
8.1 網(wǎng)站數(shù)據(jù)
這個(gè)主要是比如uv/pv。這個(gè)有幾種做法,第一種是借助第三方的統(tǒng)計(jì)攻擊,比如百度統(tǒng)計(jì)、Google統(tǒng)計(jì)等。第二種是對我們現(xiàn)有系統(tǒng)的日志進(jìn)行統(tǒng)計(jì),同時(shí)可以進(jìn)行深一步的數(shù)據(jù)挖掘。
8.2 安全性
這個(gè)需要考慮網(wǎng)站是不是存在sql注入,xss漏洞,csrf漏洞等。這個(gè)方面對于網(wǎng)站是非常關(guān)鍵的。一旦有黑客攻入,后果不堪設(shè)想。
對于管理員后臺(tái),最好不要開通外網(wǎng)權(quán)限,只能通過內(nèi)網(wǎng)訪問。
8.3 seo等
搜索引擎優(yōu)化對于網(wǎng)站作用不言而喻。 后續(xù)可能會(huì)專門針對百度SEO進(jìn)行一些分析。