第3篇 案例
9 淘寶網的架構演化案例分析 156
初期:2003年馬雲在家裡用買來的C2C交易軟體稍作修改就成了最初的淘寶網
作為剛剛起步的小網站,使用開源、免費、簡單的技術搭建網站可謂一舉多得:免費的技術降低成本、開源的技術能獲取文件支援、簡單的技術快速響應需求,工程師上手快,學習週期短、退一步,如果業務發展不順利,及時關閉網站止損。
中期:應用伺服器使用Weblogic,資料庫使用Oracle,都需要授權使用費。
業務快速發展,寶貴的開發資源應投入到新業務開發上,而不是付費就能搞定的基礎技術上,無後顧之憂可以全力以赴擴充市場。
後期:迴歸MySQL及NoSQL。
技術脫胎換骨。
10 維基百科的高效能架構設計分析 163
10.1 Wikipedia網站整體架構 163
GeoDNS:域名伺服器BIND的增強版本,可將域名解析到距離使用者最近的伺服器。
LVS:基於Linux的負載均衡伺服器。
Squid:基於Linux的反向代理伺服器。
Ligthtpd:圖片伺服器。
PHP:網站建站語言。
Mencached:分散式快取。
Lucene:Apache全文搜尋引擎。
MySQL:關係型資料庫。
10.2 Wikipedia效能優化策略 165
10.2.1 Wikipedia前端效能優化 165
核心:反向代理伺服器Squid叢集
聖盃:CDN服務(CDN加速),熱門頁面快取在CDN伺服器上,而CDN伺服器又部署在離使用者最近的伺服器上(DNS解析為基礎),請求從CDN直接返回,響應速度非常快,減少伺服器壓力,節約資源。
Wikipedia CDN 快取準則:
1.頁面內容不包括動態資訊,以免頁面內容很快失效或過時
2.每個頁面有唯一的URL,以便CDN快速查詢並避免重複快取
3.HTTL響應頭寫入快取控制資訊,通過應用控制內容是否快取及快取有效期等。
10.2.2 Wikipedia服務端效能優化 166
硬體上:最好的伺服器
程式碼層面上
10.2.3 Wikipedia後端效能優化 167
快取策略:
1.熱點集中資料快取到本地伺服器中
2.快取資料內容儘量是可以直接使用的格式
3.儲存session物件
4.Memcached連線相對資料庫連線廉價
MySQL優化:
1.使用較大的伺服器記憶體
2.使用RAID0磁碟陣列加速磁碟訪問,降低了資料可靠性,主從複製、資料非同步備份等手段解決
3.資料庫事務一致性設定在較低水平,加速當機恢復速度
4.如果Master資料庫當機,立即切換到Salve資料庫,同時關閉資料庫寫服務
11 海量分散式儲存系統Doris的高可用架構設計分析 169
Doris設計目標是支援中等高可用,Hadoop略勝一籌,這裡主要看設計思想。
11.1 分散式儲存系統的高可用架構 170
11.2 不同故障情況下的高可用解決方案 171
11.2.1 分散式儲存系統的故障分類 172
瞬時故障:網路通訊瞬時中斷、伺服器垃圾回收、後臺執行緒繁忙停止資料訪問操作;特點是是時間段,秒級甚至毫秒級可自行恢復正常。
臨時故障:交換機當機、網路卡鬆動等導致的網路通訊中斷,系統升級、停機維護等運維引起的服務關閉,記憶體損壞、CPU過熱等硬體導致的伺服器當機;特點是需要人工干預才能恢復正常,持續幾十分鐘甚至幾個小時。
永久故障:硬碟損壞,資料丟失。可以通過更換硬碟重啟伺服器
11.2.2 正常情況下系統訪問結構 172
11.2.3 瞬時故障的高可用解決方案 173
多次重試仍然失敗,可能需要執行臨時故障處理策略。
11.2.4 臨時故障的高可用解決方案 174
11.2.5 永久故障的高可用解決方案 175
12 網購秒殺系統架構設計案例分析 176
秒殺活動帶來的併發訪問使用者是平時的百倍甚至千倍,設計部署專門的秒殺系統。
12.1 秒殺活動的技術挑戰 177
1.對現有業務造成衝擊:秒殺時間短、併發量大,如果和網站原有應用部署在一起,會對現有業務造成衝擊,甚至當機。
2.高併發的應用資料庫負載:不停重新整理頁面,對伺服器,資料庫造成極大壓力。
3.突然增加的網路和伺服器頻寬:假設秒殺頁面200k,需要的網路頻寬是200k*訪問使用者數
4.直接下單:下單是普通URL,如果得到URL可以不用等到秒殺就下單。
12.2 秒殺系統的應對策略 177
1.秒殺系統獨立部署:避免拖垮整個網站
2.秒殺商品頁面靜態化:HTML頁面
3.租借秒殺活動網路頻寬:秒殺商品頁面做CDN快取
4.動態生成隨即下單頁面URL:避免直接訪問URL下單,伺服器端生成隨機引數,秒殺開始才能看到。
12.3 秒殺系統架構設計 178
1.如何控制秒殺商品頁面購買按鈕的點亮:為了減輕伺服器端負載壓力,更好地利用CDN、反向代理等效能優化手段,該頁面被設計為靜態頁面。秒殺開始時,使用者重新整理頁面,請求
根本不會到達應用伺服器。
解決方案:使用JavaScript指令碼控制,在秒殺商品靜態頁面中加入一個JavaScript檔案引用,該JavaScript檔案中包含秒殺開始標誌為否;當秒殺開始的時
候生成一個新的JavaScript檔案(檔名保持不變,只是內容不一樣),更新秒殺開始標誌為是,加入下單頁面的URL及隨機數引數(這個隨機數只會產生一個,即所有人看到的
URL都是同一個,伺服器端可以用redis這種分散式快取伺服器來儲存隨機數),並被使用者瀏覽器載入,控制秒殺商品頁面的展示。這個JavaScript檔案的載入可以加上隨機版本號
(例如xx.js?v=32353823),這樣就不會被瀏覽器、CDN和反向代理伺服器快取。這個JavaScript檔案非常小,即使每次瀏覽器重新整理都訪問JavaScript檔案伺服器也不會對伺服器集
群和網路頻寬造成太大壓力。
2.如何只允許第一個提交的訂單被髮送到訂單子系統:由於最終能夠成功秒殺到商品的使用者只有一個,因此需要在使用者提交訂單時,檢查是否已經有訂單提交。如果已經有訂單提交
成功,則需要更新 JavaScript檔案,更新秒殺開始標誌為否,購買按鈕變灰。事實上,由於最終能夠成功提交訂單的使用者只有一個,為了減輕下單頁面伺服器的負載壓力, 可以控制
進入下單頁面的入口,只有少數使用者能進入下單頁面,其他使用者直接進入秒殺結束頁面。解決方案:假設下單伺服器叢集有10臺伺服器,每臺伺服器只接受最多10個下單請求。
在還沒有人提交訂單成功之前,如果一臺伺服器已經有十單了,而有的一單都沒處理,可能出現的使用者體驗不佳的場景是使用者第一次點選購買按鈕進入已結束頁面,再重新整理一下
頁面,有可能被一單都沒有處理的伺服器處理,進入了填寫訂單的頁面,可以考慮通過cookie的方式來應對,符合一致性原則。當然可以採用最少連線的負載均衡演算法,出現上述情
況的概率大大降低。
12.4 小結 182
即使系統出現故障也不應該出現錯誤頁面,而是秒殺結束頁面。
13 大型網站典型故障案例分析 183
13.1 寫日誌也會引發故障 184
故障現象:伺服器叢集報警磁碟可用空間低於警戒值,log檔案過大
原因分析:log輸出level為dubug
經驗教訓:log輸出級別至少為warm,關閉第三方日誌。
13.2 高併發訪問資料庫引發的故障 184
故障現象:資料庫Load居高不下,持續報警
原因分析:SQL正常,但是被首頁頻繁呼叫
經驗教訓:首頁最好是靜態的,或者需要的資料從快取伺服器獲取
13.3 高併發情況下鎖引發的故障 185
故障現象:響應超時報警,很快又恢復,如此往復
原因分析:某singleton物件中多處使用了synchronized(this),this物件只有一個,所有請求都需要排隊獲取唯一的一把鎖,遠端呼叫長時間執行,其他執行緒需要等待,響應超時。
經驗教訓:鎖操作要慎用
13.4 快取引發的故障 185
故障現象:沒有新應用釋出,資料庫Load突然飆升,並很快失去響應,切換備用資料庫,很快網站癱瘓
原因分析:缺乏經驗的工程師關閉了所有快取伺服器
經驗教訓:對快取的管理提升到跟資料庫一樣的水平
13.5 應用啟動不同步引發的故障 186
故障現象:某種應用釋出後,伺服器立即崩潰
原因分析:後臺伺服器準備好,前臺才能啟動,否則導致故障
經驗教訓:姑娘們穿好衣服,老鴇才開門迎客
13.6 大檔案讀寫獨佔磁碟引發的故障 186
故障現象:圖片上傳時間數倍增加
原因分析:圖片儲存伺服器有幾個檔案非常大
經驗教訓:圖片伺服器不應該和其他型別的檔案伺服器公用
13.7 濫用生產環境引發的故障 187
故障現象:某個時間段內,某些應用突然變慢
原因分析:有工程師線上上進行效能壓力測試
經驗教訓:線上資料庫修改需DBA協助
13.8 不規範的流程引發的故障 187
故障現象:某應用釋出後,load飆升,回滾後告警消除
原因分析:開發為了測試將讀快取的程式碼註釋掉,忘記開啟
經驗教訓:加強程式碼review
13.9 不好的程式設計習慣引發的故障 188
故障現象:某功能一無法正常使用
原因分析:程式根據使用記錄構造物件,使用者都是第一次使用,物件為null
經驗教訓:確保物件不是null,必要時構造空物件
13.10 小結 188
簡單設計,問題越容易被發現,越容易被解決。