如何構建高擴充套件性網站?
本篇通過閱讀《高擴充套件性網站的50條原則》,總結出以下內容。
一方面博主沒有實際的架構經驗,另一方面知識面也不夠寬闊,所以只能系統的總結書中的要點,並根據自己的理解做些歸納。
主要內容
本書從多個方面圍繞高擴充套件性提出了50條建議,一個高擴充套件性的網站會隨著業務的發展、使用者的增加,自由的擴充套件架構,從而輕鬆的應付網站的快速發展。下面看看本書的具體內容:
化簡方程
1 不要過度的設計
過度的設計相當於給系統增加了複雜度與維護的成本。而這些過度的設計,在正常的使用中,卻沒有太大的作用。往往是設計者自己認為很重要或者錦上添花的功能,實際用處不大。
2 設計時考慮到擴充套件性
在設計時要遵循一下的設計原則:設計時考慮20倍的容量,實現時考慮3倍的容量,部署時考慮1.5的容量。一面專案擴大時,臨時擴充套件造成的困難。
3 把方案一簡再簡
應該遵循帕累托法則,20%的設計做了80%的工作,所以80%的時間,都應該放在這20%的設計上。
一個產品主要的功能其實都集中在幾個點上,把這幾個點設計好了,其他的都是些附加的功能而已。所以這核心的業務一定要保證足夠的簡潔易用。
4 減少DNS查詢
每個不同的域下的檔案,載入時都需要查詢DNS。比如cnblogs.com與i.cnblogs.com就屬於不同的域。那麼在查詢DNS的時候,就會查詢兩次。當業務量很大時,就會造成一定的影響。
5 儘可能減少物件
由於物件在瀏覽器訪問時,需要載入。所以可以考慮減少請求檔案的數量(數量與瀏覽器併發載入數有關),把一些物件儘量的合併。比如圖示類的檔案,可以合併成一個大的圖片。合理的檔案數量,會加速瀏覽器的訪問載入。
6 使用同一品牌的網路裝置
由於一個http請求,可能通過很多物理裝置。比如負載均衡器,交換機,路由器。所以儘量使用同一品牌的裝置,會避免一些意外的情況。
分佈工作
7 X軸,橫向複製
這種事最簡單的服務擴充,通過克隆或者複製實現,比如你的應用放在多個伺服器上進行服務。常見的比如叢集,負載均衡等等,資料庫的讀寫分離。
8 Y軸,拆分不同的東西
大型系統中,拆分不同的功能,比如註冊、購買、查詢、雲盤。等等
9 Z軸,拆分不同的相似的東西
比如按照使用者的級別,或者使用者的地理位置等等拆分。
橫向擴充套件設計
10 設計橫向的擴充套件方案
擴充套件包括橫向、縱向。橫向就是通過複製克隆應用,利用小型機叢集擴充套件。縱向就是提高伺服器的硬體以及網路設施。
通過很多的案例都可以發現,單純的升級硬體實現的縱向擴充套件,僅僅能解決一點點現實壓力。而通過橫向的叢集擴充套件,卻能夠自由的實現伸縮。
11 採用經濟型系統
與上面的原則類似,採用高價格的伺服器,並不能保證日後的良好效能。應該使用普通的小型機叢集擴充套件。
12 橫向擴充套件資料中心
資料中心有很多的設計方案,比如
熱冷站配置:使用熱站提供服務,當熱站崩潰時,使用冷站繼續服務。
推薦使用多個實時站點,成本更低,動態呼叫。缺點是增加了運維的難度。
13 利用雲技術進行設計
雲端計算的有點就是虛擬化,可以在業務峰值時,彈性的擴充裝置。並且在日常處理用,歸還該擴充套件。
缺點是提高了應用於虛擬環境的耦合。後面提到利用物理裝置,隔離業務,在虛擬化的雲端計算中,可能會對業務隔離錯誤排查造成一定的干擾。
使用正確的工具
14 合理使用資料庫
目前有許多的資料庫版本,比如傳統的關係型資料庫Oracle、MySQl,還有比較新的非關係型資料庫NoSql,比如MongoDB,以及記憶體資料庫FastDB,還有專門針對SSD固態硬碟的Aerospike等等。
但是到了選型的時候,還是要一句個人的業務需求來定。看你的資料庫要求的是速度,還是安全性等等。
15 防火牆,到處都是防火牆
防火牆可以對一些無效的訪問進行攔截過濾。通常把一些CSS,靜態檔案,圖片,JS等不採用防火牆,而關鍵的業務涉及到個人資訊時採用。合理的設計防火牆,也會對網站的效能產生一定的影響。
16 積極的利用日誌檔案
利用各種日誌以及工具,實時的監控業務。不僅僅是監控伺服器的記憶體CPU,還應該監控業務上的資料。比如splunk(提供日誌的蒐集,儲存,搜尋,圖形化展示)。
不要做重複的工作
17 不要立即檢查剛做過的工作
比如剛剛寫如了資料,不要立即讀取。雖然有些客戶需要保證資料的完整,不能丟失。但是可以通過日誌等記錄,寫完查這種做法,還是不推薦。
18 停止重定向
重定向會消耗一定的延遲,計算資源。應該儘量避免
19 放鬆時序約束
大多數的關係型資料庫講究ACID屬性,擴充套件時就造成一定的困擾。因此某些業務適當的放鬆時序約束,可以提高網站的效能。
比如某站在預定酒店時,使用者預定後,會等待酒店的稽核。比如某寶,在提款時,進行範圍時間的確認。這種就是擴大了時序約束,進而提高網站效能以及事務安全。
積極利用快取
20 利用CDN
可以利用CDN儲存客戶的資料和內容。大概的過程是,使用者在進行網站訪問時,轉到CDN的伺服器,CDN執行DNS查詢,把使用者請求分攤到不同的伺服器。有很多的CDN服務商提供這種服務。
21 使用過期頭
針對不同的物件型別,使用過期頭,減少物件請求。常見的HTTP對應屬性為:public no-cahe max-age等等
22 快取Ajax呼叫
正確修改Http頭Last-Modified Cache-Control Expires等屬性。
23 利用頁面快取
快取響應之前的冬天請求,降低web伺服器的負載。
24 利用應用快取
比如針對某些特殊的使用者,快取其請求資料。
25 利用物件快取
適用於反覆查詢使用的資料物件。比如一個購物網站,快取器熱銷產品資料。
26 把物件快取放在自己的層上
使用單獨的緩層,易於擴充套件和維護。
從錯誤中吸取教訓
27 積極的學習
一個公司有學習的氛圍,才會衍生出更好的產品。學習的內容一方面包括客戶的業務知識,一方面來自技術和運維領域。
28 不要依靠QA發現失誤
僱傭測試或者質量保證人員,最大的目的是為了檢測產品的正確性。它能減少成本,提高開發人員的開發速度,因為開發人員不需要時刻關注程式碼的正確性,可以交給QA來測試。
但是QA只負責發現問題,如何避免為題還是得依靠開發人員。
29 沒有回退的設計是失敗的設計
這裡的回退,指的是產品釋出的回退。如果碰上某些版本的BUG,可能需要交付之前可執行的版本,此時沒有回退,就無法交付產品了。
這裡推薦學習持續整合的相關內容。
30 討論失敗並從中吸取教訓
不應該在同一個問題上失敗兩次,每次失敗多進行總結是不可缺少的。
資料庫原則
關係型資料庫的ACID屬性:
原子性:一個事務要麼全執行,要麼都不執行,
一致性:事務開始和結束時,所有資料狀態要一致,
隔離性:事務的表現,是事務對資料庫唯一的操作,
永續性:事務完成,操作不能更改。
31 注意代價高的關係
應該在設計階段完善的設計表的結構,等開發開始時,在增加某些列,可能會花費很高的代價。
32 使用正確的資料庫鎖
資料庫有很多鎖的概念,比如隱式鎖、顯式鎖、行鎖、頁鎖、範圍鎖、表鎖、資料庫鎖等等。
不合理的使用鎖,會影響網站的吞吐量。
33 不要使用多階段提交
比如兩階段提交:先表決,在提交。這回降低擴充套件性,因為在其提交事務完成前,是不能作其他操作的。
34 不要使用select for update
因為FOR UPDATE從句會導致鎖定行,降低事務處理的速度。
35 不要選擇所有的資料
比如select * from xxx;
這種做法第一是不開與資料的擴充套件,比如本來有四列資料,業務處理程式碼直接寫死。當增加了一列資料時,就會導致出錯;另外就是會查詢出不必要的資料。
或者inset into xxx values(xxxx);
這是當列資訊不匹配時,也會出錯。
容錯設計與故障控制
36 採用隔離故障的”泳道“
服務與資料的劃分有很多種,比如容器,叢集,池,分片,泳道。泳道意味著每個業務有自己的領域,不能跨泳道呼叫。
37 不要信任單點故障
有很多系統設計成單點模式,當整個系統只是用該模組時,當出現單點故障,整個系統也就崩潰了。
38 避免系統串聯
比如一個系統有很多的元件組成,每個元件99.9%的安全性,當串聯3個元件時,整個系統的可用性就變成了99.7%。
39 確保能夠啟用/禁用功能
對於某些共享庫,第三方服務,應該提供開啟或者關閉的功能。
避免或分發狀態
40 努力實現無狀態
實現狀態會限制擴充套件性,增大成本
41 儘可能在瀏覽器端維護會話
一方面降低伺服器壓力,另一方面任何的請求可以傳送給任何的伺服器。
42 利用分散式快取存放狀態
使用獨立的快取層,利於擴充套件。有很多分散式的快取方案,比如memcached。
非同步通訊和訊息匯流排
43 儘可能使用非同步通訊
非同步通訊,可以確保每個服務和層之間的獨立性,這樣易於早呢更加系統的擴充套件性和減小耦合度。
44 確保訊息匯流排能夠擴充套件
儘量採用Y軸或者Z軸擴充套件,即按業務需求和功能擴充套件。因為單純的複製或者克隆,反而會增加各個訊息訂閱者的監聽數目。按照業務隔離,可以分離業務壓力。
45 避免讓訊息匯流排過度擁擠
衡量價值與訊息的成本。
其他原則
46 慎用第三方解決方案擴充套件
企業如果出現問題,那麼尋找第三方能夠解決燃眉之急。但是卻不是長久之計,因為解決方案的提供商有很多客戶,你的危機並不是他們的危機,所以不可能在關鍵時刻,盡職盡責。因此企業還是應該有一定的掌控力(這個詞真是高大上!)。
47 清除、歸檔和成本合理的儲存
有一些不必要的資料,就應該定期的刪除。一些略有價值的資料進行定期的歸檔直接刪除。一些很有價值的資料,應該進行備份以及快速訪問。
48 刪除事務處理中的商業智慧
應該把產品系統與業務系統分離,提高產品的擴充套件性。
避免業務擴充套件時,受到系統架構的限制。
49 設計能夠監控的應用
應該設計全域性的監控策略,保證回答
”發生了 問題了嗎?“
”哪裡發生了問題?“
”發生了什麼問題?“
”會發生問題嗎?“
”能自動修復嗎?“
50 要能勝任
應該在每個設計中涉及到最優秀的架構,不能完全依賴第三方的解決方案。
一個簡單優秀的架構,都是小而精的,如果單純的依靠開源解決架構,雖然解決了問題,卻會導致應用的臃腫。
相關文章
- 大型網站技術架構(七)--網站的可擴充套件性架構網站架構套件
- 如何構建一個優雅擴充套件套件
- 《高擴充套件性網站的50條原則》編輯小記套件網站
- 構建高可用性、高效能和可擴充套件的Zabbix Server架構套件Server架構
- MySQL 高擴充套件架構構建百萬線上系統實踐MySql套件架構
- 《高擴充套件性網站的50條原則》第1章有用連結套件網站
- Velocity China 2016 構建快速、可擴充套件的彈性網站大會套件網站
- kotlin 擴充套件(擴充套件函式和擴充套件屬性)Kotlin套件函式
- Deco 編輯器高擴充套件性技術架構解析套件架構
- 高擴充套件性的學習路線套件
- 如何擴充套件大規模Web網站的效能?套件Web網站
- 如何構建可控,可靠,可擴充套件的 PWA 應用套件
- 可擴充套件性套件
- 【Kotlin】擴充套件屬性、擴充套件函式Kotlin套件函式
- 使用 Zephir 輕鬆構建 PHP 擴充套件PHP套件
- 重構聚合支付案例教你如何寫出高擴充套件性易讀的程式碼套件
- [外掛擴充套件]通用網站統計套件網站
- 構建可擴充套件的有態服務套件
- 構建可擴充套件的應用(一) (轉)套件
- [譯] 如何使用原生 JavaScript 構建簡單的 Chrome 擴充套件程式JavaScriptChrome套件
- 如何設計高擴充套件的線上網頁製作平臺套件網頁
- 如何擴充套件一個網站以支援數百萬使用者?套件網站
- Swift 擴充套件 Storyboard 屬性Swift套件
- 服務的擴充套件性套件
- 基於 Golang 構建高可擴充套件的雲原生 PaaS(附 PPT 下載)Golang套件
- 利用OC物件的訊息重定向forwardingTargetForSelector方法構建高擴充套件性的濾鏡功能物件Forward套件
- 如何利用容器與中介軟體實現微服務架構下的高可用性和彈性擴充套件微服務架構套件
- 網站的可擴性展架構網站架構
- YouTube的架構擴充套件架構套件
- MySQL - 擴充套件性 2 擴充套件策略:氪金氪腦任君選MySql套件
- 可擴充套件性筆記一套件筆記
- bash的特有擴充套件屬性套件
- bgo: 具備擴充套件性的 go 程式構建工具Go套件
- 乾貨丨如何水平擴充套件和垂直擴充套件DolphinDB叢集?套件
- 讀構建可擴充套件分散式系統:方法與實踐09可擴充套件資料庫基礎套件分散式資料庫
- Django與微服務架構:構建可擴充套件的Web應用Django微服務架構套件Web
- 不改表結構如何動態擴充套件欄位套件
- 如何搭建一個高可用、高擴充套件的圖片儲存功能套件