架構設計原則 - 高併發
高併發設計可以從以下幾方面考慮:
1.無狀態
無狀態的應用容易進行水平擴充套件。
實際常用:應用無狀態,配置檔案有狀態,例如,不同的機房讀取不同的配置檔案,通過配置中心指定。
2.拆分
拆分維度:
3.服務化
服務化需要考慮自動服務註冊,和服務發現,還有服務的分組/隔離,例如,有的系統訪問量,導致把整個服務打掛,因此,需要為不同的呼叫方提供不同的服務分組,隔離訪問。
後期隨著呼叫量的增加還要考慮限流、黑白名單等。
還有一些其他的注意點,例如超時時間、重試機制、服務路由、故障補償等。
4.訊息佇列
訊息佇列用來解耦一些不需要同步呼叫的服務,或者訂閱一些自己系統關心的變化。
訊息佇列可以實現服務解耦、非同步處理、流量銷峰等,例如,訂單產生系統、定期推送系統、訂單風控系統等等。
使用訊息佇列,需要考慮如何處理訊息傳送失敗,以及重複消費的情況。
有的訊息佇列有自動重試功能,如果重試多次還未成功,就通知傳送失敗,這時,就要做好後續的資料處理工作,例如持久化資料要同時增加日誌、報警等。
對於訊息重複消費問題,需要在業務層面進行防重處理。
應用示例:電商**時,流量會比平時高出幾倍甚至幾十倍,這就需要特殊的設計來保證系統平穩,一般是犧牲強一致性,保證最終一致性,如扣減庫存,直接在 redis 中扣減,記錄下日誌,通過 worker 同步到資料庫。
再比如訂單系統,可以這樣設計:
結算服務呼叫訂單接單服務,將訂單儲存到 redis 和訂單佇列中。訂單redis用於使用者檢視訂單詳情,通過佇列提公升接單能力。
然後通過同步worker把佇列中的訂單同步到資料庫。
當訂單狀態發生變化,例如使用者支付了,訂單狀態機負責驅動狀態的變更,更新資料庫和redis。
5.資料異構
資料量大了以後,通常會分庫分表,例如訂單表,拆分時通常根據訂單id進行劃分,但如果查詢某個使用者的訂單時,就比較麻煩了,需要聚合多個表,這種情況一般都會生成乙個「使用者id」維度的資料,供業務直接呼叫。或者有跨庫join查詢時,將需要join的多個表按照某個維度又聚合在乙個庫中。這類做法就叫做「資料異構」。
6.快取
(2)cdn 快取
(3)應用層快取
(4)分布式快取,應用示例:
7.併發化
例如乙個讀服務需要如下資料:
如果序列,共需要60ms。
如果 c 依賴 a 和 b,d 沒有任何依賴,e 依賴 c,那麼就可以並行獲取資料:
併發化處理,共需要30ms,效能提公升了一倍。
總結
高併發架構設計原則 拆分
在系統設計初期,是做乙個大而全的系統還是根據模組進行拆分要根據環境和需求進行權衡。訪問量不大 功能簡單 研發資源不多時可以做乙個大而全的系統即可 如果訪問量大資源充足 功能繁多可以考慮按功能拆分系統。下面幾種拆分維度 按照系統功能 業務拆分,比如商品系統 購物車系統 結算系統 訂單系統等。對乙個系統...
高併發架構設計原則 訊息佇列
解耦 消峰 非同步 有abcd四個系統,a系統有一條資料需要傳給bcd,a系統不僅要關心資料傳送還要處理資料傳送bcd其中產生的異常,如b掛掉了怎麼辦,a是否重傳?如果使用訊息佇列,a系統只負責傳送訊息到訊息佇列,bcd消費訊息佇列中的訊息即可,a系統不關心訊息發給誰了,誰消費失敗了等等問題。類似於...
高併發架構設計原則 無狀態
服務端不儲存任何客戶端請求者資訊,客戶端的每次請求必須具備自述資訊,通過這些資訊識別客戶端身份。優點 客戶端請求不依賴服務端的資訊,任何多次請求不需要必須訪問到同一臺服務,這樣為伺服器橫向擴充套件提供了條件。服務端需要記錄每次繪畫的客戶端資訊,從而識別客戶端身份,根據客戶端身份進行對請求的處理,如s...