|
本篇通過閱讀《高擴展性網(wǎng)站的50條原則》,總結(jié)出以下內(nèi)容。 一方面博主沒有實際的架構(gòu)經(jīng)驗,另一方面知識面也不夠?qū)掗?,所以只能系統(tǒng)的總結(jié)書中的要點,并根據(jù)自己的理解做些歸納。 主要內(nèi)容本書從多個方面圍繞高擴展性提出了50條建議,一個高擴展性的網(wǎng)站會隨著業(yè)務(wù)的發(fā)展、用戶的增加,自由的擴展架構(gòu),從而輕松的應(yīng)付網(wǎng)站的快速發(fā)展。下面看看本書的具體內(nèi)容:
化簡方程1 不要過度的設(shè)計 過度的設(shè)計相當(dāng)于給系統(tǒng)增加了復(fù)雜度與維護的成本。而這些過度的設(shè)計,在正常的使用中,卻沒有太大的作用。往往是設(shè)計者自己認為很重要或者錦上添花的功能,實際用處不大。 2 設(shè)計時考慮到擴展性 在設(shè)計時要遵循一下的設(shè)計原則:設(shè)計時考慮20倍的容量,實現(xiàn)時考慮3倍的容量,部署時考慮1.5的容量。一面項目擴大時,臨時擴展造成的困難。 3 把方案一簡再簡 應(yīng)該遵循帕累托法則,20%的設(shè)計做了80%的工作,所以80%的時間,都應(yīng)該放在這20%的設(shè)計上。 一個產(chǎn)品主要的功能其實都集中在幾個點上,把這幾個點設(shè)計好了,其他的都是些附加的功能而已。所以這核心的業(yè)務(wù)一定要保證足夠的簡潔易用。 4 減少DNS查詢 每個不同的域下的文件,加載時都需要查詢DNS。比如cnblogs.com與i.cnblogs.com就屬于不同的域。那么在查詢DNS的時候,就會查詢兩次。當(dāng)業(yè)務(wù)量很大時,就會造成一定的影響。 5 盡可能減少對象 由于對象在瀏覽器訪問時,需要加載。所以可以考慮減少請求文件的數(shù)量(數(shù)量與瀏覽器并發(fā)加載數(shù)有關(guān)),把一些對象盡量的合并。比如圖標(biāo)類的文件,可以合并成一個大的圖片。合理的文件數(shù)量,會加速瀏覽器的訪問加載。 6 使用同一品牌的網(wǎng)絡(luò)設(shè)備 由于一個http請求,可能通過很多物理設(shè)備。比如負載均衡器,交換機,路由器。所以盡量使用同一品牌的設(shè)備,會避免一些意外的情況。 分布工作
7 X軸,橫向復(fù)制 這種事最簡單的服務(wù)擴充,通過克隆或者復(fù)制實現(xiàn),比如你的應(yīng)用放在多個服務(wù)器上進行服務(wù)。常見的比如集群,負載均衡等等,數(shù)據(jù)庫的讀寫分離。 8 Y軸,拆分不同的東西 大型系統(tǒng)中,拆分不同的功能,比如注冊、購買、查詢、云盤。等等 9 Z軸,拆分不同的相似的東西 比如按照用戶的級別,或者用戶的地理位置等等拆分。 橫向擴展設(shè)計10 設(shè)計橫向的擴展方案 擴展包括橫向、縱向。橫向就是通過復(fù)制克隆應(yīng)用,利用小型機集群擴展??v向就是提高服務(wù)器的硬件以及網(wǎng)絡(luò)設(shè)施。 通過很多的案例都可以發(fā)現(xiàn),單純的升級硬件實現(xiàn)的縱向擴展,僅僅能解決一點點現(xiàn)實壓力。而通過橫向的集群擴展,卻能夠自由的實現(xiàn)伸縮。 11 采用經(jīng)濟型系統(tǒng) 與上面的原則類似,采用高價格的服務(wù)器,并不能保證日后的良好性能。應(yīng)該使用普通的小型機集群擴展。 12 橫向擴展數(shù)據(jù)中心 數(shù)據(jù)中心有很多的設(shè)計方案,比如 熱冷站配置:使用熱站提供服務(wù),當(dāng)熱站崩潰時,使用冷站繼續(xù)服務(wù)。
推薦使用多個實時站點,成本更低,動態(tài)調(diào)用。缺點是增加了運維的難度。 13 利用云技術(shù)進行設(shè)計 云計算的有點就是虛擬化,可以在業(yè)務(wù)峰值時,彈性的擴充設(shè)備。并且在日常處理用,歸還該擴展。 缺點是提高了應(yīng)用于虛擬環(huán)境的耦合。后面提到利用物理設(shè)備,隔離業(yè)務(wù),在虛擬化的云計算中,可能會對業(yè)務(wù)隔離錯誤排查造成一定的干擾。 使用正確的工具14 合理使用數(shù)據(jù)庫 目前有許多的數(shù)據(jù)庫版本,比如傳統(tǒng)的關(guān)系型數(shù)據(jù)庫Oracle、MySQl,還有比較新的非關(guān)系型數(shù)據(jù)庫NoSql,比如MongoDB,以及內(nèi)存數(shù)據(jù)庫FastDB,還有專門針對SSD固態(tài)硬盤的Aerospike等等。 但是到了選型的時候,還是要一句個人的業(yè)務(wù)需求來定??茨愕臄?shù)據(jù)庫要求的是速度,還是安全性等等。 15 防火墻,到處都是防火墻 防火墻可以對一些無效的訪問進行攔截過濾。通常把一些CSS,靜態(tài)文件,圖片,JS等不采用防火墻,而關(guān)鍵的業(yè)務(wù)涉及到個人信息時采用。合理的設(shè)計防火墻,也會對網(wǎng)站的性能產(chǎn)生一定的影響。 16 積極的利用日志文件 利用各種日志以及工具,實時的監(jiān)控業(yè)務(wù)。不僅僅是監(jiān)控服務(wù)器的內(nèi)存CPU,還應(yīng)該監(jiān)控業(yè)務(wù)上的數(shù)據(jù)。比如splunk(提供日志的搜集,存儲,搜索,圖形化展示)。 不要做重復(fù)的工作17 不要立即檢查剛做過的工作 比如剛剛寫如了數(shù)據(jù),不要立即讀取。雖然有些客戶需要保證數(shù)據(jù)的完整,不能丟失。但是可以通過日志等記錄,寫完查這種做法,還是不推薦。 18 停止重定向 重定向會消耗一定的延遲,計算資源。應(yīng)該盡量避免 19 放松時序約束 大多數(shù)的關(guān)系型數(shù)據(jù)庫講究ACID屬性,擴展時就造成一定的困擾。因此某些業(yè)務(wù)適當(dāng)?shù)姆潘蓵r序約束,可以提高網(wǎng)站的性能。 比如某站在預(yù)定酒店時,用戶預(yù)定后,會等待酒店的審核。比如某寶,在提款時,進行范圍時間的確認。這種就是擴大了時序約束,進而提高網(wǎng)站性能以及事務(wù)安全。 積極利用緩存20 利用CDN 可以利用CDN保存客戶的數(shù)據(jù)和內(nèi)容。大概的過程是,用戶在進行網(wǎng)站訪問時,轉(zhuǎn)到CDN的服務(wù)器,CDN執(zhí)行DNS查詢,把用戶請求分攤到不同的服務(wù)器。有很多的CDN服務(wù)商提供這種服務(wù)。 21 使用過期頭 針對不同的對象類型,使用過期頭,減少對象請求。常見的HTTP對應(yīng)屬性為:public no-cahe max-age等等 22 緩存Ajax調(diào)用 正確修改Http頭Last-Modified Cache-Control Expires等屬性。 23 利用頁面緩存 緩存響應(yīng)之前的冬天請求,降低web服務(wù)器的負載。 24 利用應(yīng)用緩存 比如針對某些特殊的用戶,緩存其請求數(shù)據(jù)。 25 利用對象緩存 適用于反復(fù)查詢使用的數(shù)據(jù)對象。比如一個購物網(wǎng)站,緩存器熱銷產(chǎn)品數(shù)據(jù)。 26 把對象緩存放在自己的層上 使用單獨的緩層,易于擴展和維護。 從錯誤中吸取教訓(xùn)27 積極的學(xué)習(xí) 一個公司有學(xué)習(xí)的氛圍,才會衍生出更好的產(chǎn)品。學(xué)習(xí)的內(nèi)容一方面包括客戶的業(yè)務(wù)知識,一方面來自技術(shù)和運維領(lǐng)域。 28 不要依靠QA發(fā)現(xiàn)失誤 雇傭測試或者質(zhì)量保證人員,最大的目的是為了檢測產(chǎn)品的正確性。它能減少成本,提高開發(fā)人員的開發(fā)速度,因為開發(fā)人員不需要時刻關(guān)注代碼的正確性,可以交給QA來測試。 但是QA只負責(zé)發(fā)現(xiàn)問題,如何避免為題還是得依靠開發(fā)人員。 29 沒有回退的設(shè)計是失敗的設(shè)計 這里的回退,指的是產(chǎn)品發(fā)布的回退。如果碰上某些版本的BUG,可能需要交付之前可運行的版本,此時沒有回退,就無法交付產(chǎn)品了。 這里推薦學(xué)習(xí)持續(xù)集成的相關(guān)內(nèi)容。 30 討論失敗并從中吸取教訓(xùn) 不應(yīng)該在同一個問題上失敗兩次,每次失敗多進行總結(jié)是不可缺少的。 數(shù)據(jù)庫原則關(guān)系型數(shù)據(jù)庫的ACID屬性: 原子性:一個事務(wù)要么全執(zhí)行,要么都不執(zhí)行, 一致性:事務(wù)開始和結(jié)束時,所有數(shù)據(jù)狀態(tài)要一致, 隔離性:事務(wù)的表現(xiàn),是事務(wù)對數(shù)據(jù)庫唯一的操作, 持久性:事務(wù)完成,操作不能更改。 31 注意代價高的關(guān)系 應(yīng)該在設(shè)計階段完善的設(shè)計表的結(jié)構(gòu),等開發(fā)開始時,在增加某些列,可能會花費很高的代價。 32 使用正確的數(shù)據(jù)庫鎖 數(shù)據(jù)庫有很多鎖的概念,比如隱式鎖、顯式鎖、行鎖、頁鎖、范圍鎖、表鎖、數(shù)據(jù)庫鎖等等。 不合理的使用鎖,會影響網(wǎng)站的吞吐量。 33 不要使用多階段提交 比如兩階段提交:先表決,在提交。這回降低擴展性,因為在其提交事務(wù)完成前,是不能作其他操作的。 34 不要使用select for update 因為FOR UPDATE從句會導(dǎo)致鎖定行,降低事務(wù)處理的速度。 35 不要選擇所有的數(shù)據(jù) 比如select * from xxx; 這種做法第一是不開與數(shù)據(jù)的擴展,比如本來有四列數(shù)據(jù),業(yè)務(wù)處理代碼直接寫死。當(dāng)增加了一列數(shù)據(jù)時,就會導(dǎo)致出錯;另外就是會查詢出不必要的數(shù)據(jù)。 或者inset into xxx values(xxxx); 這是當(dāng)列信息不匹配時,也會出錯。 容錯設(shè)計與故障控制36 采用隔離故障的”泳道“ 服務(wù)與數(shù)據(jù)的劃分有很多種,比如容器,集群,池,分片,泳道。泳道意味著每個業(yè)務(wù)有自己的領(lǐng)域,不能跨泳道調(diào)用。 37 不要信任單點故障 有很多系統(tǒng)設(shè)計成單點模式,當(dāng)整個系統(tǒng)只是用該模塊時,當(dāng)出現(xiàn)單點故障,整個系統(tǒng)也就崩潰了。 38 避免系統(tǒng)串聯(lián) 比如一個系統(tǒng)有很多的組件組成,每個組件99.9%的安全性,當(dāng)串聯(lián)3個組件時,整個系統(tǒng)的可用性就變成了99.7%。 39 確保能夠啟用/禁用功能 對于某些共享庫,第三方服務(wù),應(yīng)該提供開啟或者關(guān)閉的功能。 避免或分發(fā)狀態(tài)40 努力實現(xiàn)無狀態(tài) 實現(xiàn)狀態(tài)會限制擴展性,增大成本 41 盡可能在瀏覽器端維護會話 一方面降低服務(wù)器壓力,另一方面任何的請求可以發(fā)送給任何的服務(wù)器。 42 利用分布式緩存存放狀態(tài) 使用獨立的緩存層,利于擴展。有很多分布式的緩存方案,比如memcached。 異步通信和消息總線43 盡可能使用異步通信 異步通信,可以確保每個服務(wù)和層之間的獨立性,這樣易于早呢更加系統(tǒng)的擴展性和減小耦合度。 44 確保消息總線能夠擴展 盡量采用Y軸或者Z軸擴展,即按業(yè)務(wù)需求和功能擴展。因為單純的復(fù)制或者克隆,反而會增加各個消息訂閱者的監(jiān)聽數(shù)目。按照業(yè)務(wù)隔離,可以分離業(yè)務(wù)壓力。 45 避免讓消息總線過度擁擠 衡量價值與消息的成本。
其他原則46 慎用第三方解決方案擴展 企業(yè)如果出現(xiàn)問題,那么尋找第三方能夠解決燃眉之急。但是卻不是長久之計,因為解決方案的提供商有很多客戶,你的危機并不是他們的危機,所以不可能在關(guān)鍵時刻,盡職盡責(zé)。因此企業(yè)還是應(yīng)該有一定的掌控力(這個詞真是高大上?。?/p> 47 清除、歸檔和成本合理的存儲 有一些不必要的數(shù)據(jù),就應(yīng)該定期的刪除。一些略有價值的數(shù)據(jù)進行定期的歸檔直接刪除。一些很有價值的數(shù)據(jù),應(yīng)該進行備份以及快速訪問。 48 刪除事務(wù)處理中的商業(yè)智能 應(yīng)該把產(chǎn)品系統(tǒng)與業(yè)務(wù)系統(tǒng)分離,提高產(chǎn)品的擴展性。 避免業(yè)務(wù)擴展時,受到系統(tǒng)架構(gòu)的限制。 49 設(shè)計能夠監(jiān)控的應(yīng)用 應(yīng)該設(shè)計全局的監(jiān)控策略,保證回答 ”發(fā)生了 問題了嗎?“ ”哪里發(fā)生了問題?“ ”發(fā)生了什么問題?“ ”會發(fā)生問題嗎?“ ”能自動修復(fù)嗎?“
50 要能勝任 應(yīng)該在每個設(shè)計中涉及到最優(yōu)秀的架構(gòu),不能完全依賴第三方的解決方案。 一個簡單優(yōu)秀的架構(gòu),都是小而精的,如果單純的依靠開源解決架構(gòu),雖然解決了問題,卻會導(dǎo)致應(yīng)用的臃腫。 參考【1】《高擴展性網(wǎng)站的50條原則》 |
|
|