架構設計:隔離術
隔離 是通過將系統、資源分開,從而保證在發生問題時使其影響最小化,防止出現雪崩效應。
例如系統中有服務介面 A B C,因為某些原因,介面A的訪問量激增,佔用了大量系統資源,導致 B C 介面也無法正常運行了。如果使用了隔離機制,即使A的訪問量很大,也不會影響 B C,把影響限定在一定範圍,提高了系統的可用性。
隔離術是保證系統高可用的重要手段,常用的隔離方式有以下幾種。
1. 執行緒隔離
比如 Tomcat 有一個執行緒池,接收請求後就從執行緒池中分配一個執行緒進行處理。
比如請求業務A的量很大,執行緒都分給A了,B的請求來了以後就無法快速響應。
這時我們可以進行執行緒隔離,使用多個執行緒池來進行隔離,這樣即使某個執行緒池很忙,也不會影響另一個。
2. 程序隔離
一個應用系統中會包含多個模組,例如有論壇模組、交易模組。
當系統訪問量大了以後,區域性性原理的效果顯現出來,一定會有某個模組的訪問比例是極高的,比如是論壇模組,系統資源大部分都被其佔用,就會影響其他模組的執行效率,而且論壇模組訪問量大,其出現故障的概率也就更大,如果出現故障就可能導致整個系統不可用。
這種情況下較好的解決方案就是使用程序隔離,把系統拆分為多個子系統實現物理隔離,互不影響。
3. 叢集隔離
單例項服務無法滿足需求後,就會部署多個服務,形成服務叢集來提升效能。
例如商品服務,部署多個例項,每個例項都包含相關服務功能:
秒殺是比較特殊的服務,瞬時訪問量會非常大,當發展到一定程度後,勢必會影響其他服務,這時就可以把秒殺提取出來,與其他服務隔離開。
4. 機房隔離
隨著系統規模的增大,對可用性要求的增加,會進行多機房部署。
本機房的服務只調用本機房服務,不進行跨機房呼叫,如果一個機房發生故障,可以通過 DNS/負載均衡將請求切換到另一個機房。
5. 讀寫隔離
比如資料庫,剛開始讀寫都操作一個數據庫例項,當規模上來後,就可以使用讀寫分離模式,提升了效能,而且即使寫入的庫出現故障,也不影響讀操作。
再比如 Redis 叢集,也可以使用讀寫隔離來提升可用性,讀服務只讀取從叢集,主叢集故障後,從叢集還可用,並且當一個從叢集出現故障後,還可以到另一個群中重試。
6. 動靜隔離
Web伺服器中包含靜態資源(例如 JS CSS檔案)、動態資源(例如 JSP PHP 檔案),對於靜態資源,伺服器其實只是儲存的作用,使用者請求時直接返回,無需計算,這就可以將靜態資源放到 CDN 上,既可以提升靜態資源的載入速度,又減輕了伺服器的壓力。
7. 爬蟲隔離
如果爬蟲的訪問量已經對系統性能產生了一定影響,就一定要把爬蟲的訪問隔離出來,可以在負載均衡層面將其路由到單獨叢集,保護系統的正常業務。
Nginx 中配置示例程式碼:
set $flag 0; if ($http_user_agent ~* "spider") { set $flag "1"; } if($flag = "0") { //代理到正常叢集 } if ($flag = "1") { //代理到爬蟲叢集 }
8. 熱點隔離
前面例子中的秒殺就屬於熱點,所以需要對其進行隔離。
對於讀型別的熱點,可以使用 多級快取 來處理。對於寫型別的熱點,可以使用 快取+佇列 的模式。
9. 資源隔離
常見的資源例如CPU、磁碟、網路。
比如使用 docker 容器時,有的容器寫磁碟非常頻繁,就需要考慮為不同的容器掛載不同的磁碟。
比如 redis nginx,我們可以為其繫結CPU來提升效能。
再比如大資料計算叢集、資料庫叢集應該與應用叢集網路隔離。
內容整理自《億級流量網站架構核心技術》
點選:point_down: 閱讀原文 ,檢視 文章列表