隔離,本質上是對系統或資源進行分割,進而實作當系統發生故障時能限定傳播範圍和影響範圍,即發生故障後隻有出問題的服務不可用,保證其他服務仍然可用。

例如 CDN
小到 CPU 的 cacheline false sharing、資料庫 mysql 表設計中避免 bufferpool 頻繁過期,隔離動靜表,大到架構設計中的圖檔、靜态資源等緩存加速。本質上都展現的一樣的思路,即加速/緩存通路變換頻次小的。比如 CDN 場景中,将靜态資源和動态 API 分離,也是展現了隔離的思路:
降低應用伺服器負載,靜态檔案通路負載全部通過CDN。
對象存儲存儲費用最低。
海量存儲空間,無需考慮存儲架構更新。
靜态CDN帶寬加速,延遲低。
archive: 稿件表,存儲稿件的名稱、作者、分類、tag、狀态等資訊,表示稿件的基本資訊。 在一個投稿流程中,一旦稿件建立改動的頻率比較低。 archive_stat: 稿件統計表,表示稿件的播放、點贊、收藏、投币數量,比較高頻的更新。 随着稿件擷取流量,稿件被使用者所消費,各類計數資訊更新比較頻繁。 MySQL BufferPool 是用于緩存 DataPage 的,DataPage 可以了解為緩存了表的行,那麼如果頻繁更新 DataPage 不斷會置換,會導緻命中率下降的問題,是以我們在表設計中,仍然可以沿用類似的思路,其主表基本更新,在上遊 Cache 未命中,透穿到 MySQL,仍然有 BufferPool 的緩存。
例如主從,除此之外還有常見的 CQRS 模式,分庫分表等
常見的隔離技術,當用于讀取操作的伺服器出現故障時,寫伺服器照常可以運作,反之也一樣。
核心隔離:例如上面講到将核心業務獨立部署,非核心業務共享資源
熱點隔離:例如上面講到的 remote cache 到 local cache
使用者隔離:不同的使用者可能有不同的級别,例如上面講到的外部使用者和管理者
常見的例子就是線程池,這個在 Golang 中一般不用過多考慮,runtime 已經幫我們管理好了
主要通過線程池進行隔離,也是實作服務隔離的基礎。(可将圖中隔離媒介換成線程池即可)
把業務進行分類并交給不同的線程池進行處理,當某個線程池處理一種業務請求發生問題時,不會講故障擴散和影響到其他線程池,保證服務可用。
假設系統存在商品服務、使用者服務和訂單服務3個微服務,通過設定運作時環境得到3個服務一共使用200個線程,用戶端調用這3個微服務共享線程池時可能會引發服務雪崩,将線程分别隔離後則不會觸發整體雪崩。
我們現在一般使用容器化服務,跑在 k8s 上這就是一種程序級别的隔離
将系統拆分為多個子系統來實作實體隔離,各個子系統運作在獨立的容器和JVM中,通過程序隔離使得一個子系統出現問題不會影響其他子系統。
我們目前在 K8s 的基礎上做一些開發,常見的一種做法就是将我們的服務的不同副本盡量的配置設定在不同的可用區,實際上就是雲廠商的不同機房,避免機房停電或者着火之類的影響
如果有條件,對于大型高可用系統,會進行多機房部署,每個機房的服務都有自己的服務分組,本機房的服務應該隻調用同機房服務。
當一個機房出現故障,将請求快速切換到其他機房確定服務繼續可用。
非常重要的服務我們可以部署多套,在實體上進行隔離,常見的有異地部署,也可能就部署在同一個區域
将某些服務單獨部署成叢集,或對于某些服務可以進行分組叢集管理,某一個叢集出現問題之後就不會影響到其他叢集,進而實作隔離。