系統設計:關於高可用系統的一些技術方案 可靠的系統是業務穩定、快速發展的基石。那麼,如何做到系統高可靠、高可用呢?下麵從技術方面介紹幾種提高系統可靠性、可用性的方法。 擴展 擴展是最常見的提升系統可靠性的方法,系統的擴展可以避免單點故障,即一個節點出現了問題造成整個系統無法正常工作。換一個角度講,一 ...
系統設計:關於高可用系統的一些技術方案 可靠的系統是業務穩定、快速發展的基石。那麼,如何做到系統高可靠、高可用呢?下麵從技術方面介紹幾種提高系統可靠性、可用性的方法。 擴展 擴展是最常見的提升系統可靠性的方法,系統的擴展可以避免單點故障,即一個節點出現了問題造成整個系統無法正常工作。換一個角度講,一個容易擴展的系統,能夠通過擴展來成倍的提升系統能力,輕鬆應對系統訪問量的提升。 一般地,擴展可以分為垂直擴展和水平擴展:
- 垂直擴展:是在同一邏輯單元里添加資源從而滿足系統處理能力上升的需求。比如,當機器記憶體不夠時,我們可以幫機器增加記憶體,或者數據存不下時,我們為機器掛載新的磁碟。
- 垂直擴展能夠提升系統處理能力,但不能解決單點故障問題。
- 優點:擴展簡單。
- 缺點:擴展能力有限。
- 水平擴展:通過增加一個或多個邏輯單元,並使得它們像整體一樣的工作。
- 水平擴展,通過冗餘部署解決了單點故障,同時又提升了系統處理能力。
- 優點:擴展能力強。
- 缺點:增加系統複雜度,維護成本高,系統需要是無狀態的、可分散式的。
- 通常我們在部署應用伺服器的時候,都會部署多台,然後使用 nginx 來做負載均衡,nginx 使用心跳機制來檢測伺服器的正常與否,無響應的服務就從集群中剔除。這樣的集群中每台伺服器的角色是相同的,同時提供一樣的服務。
- 在資料庫的部署中,為了防止單點故障,一般會使用一主多從,通常寫操作只發生在主庫。不同資料庫之間角色不同。當主機宕機時,一臺從庫可以自動切換為主機提供服務。
- 線程池隔離:不同的業務使用不同的線程池,避免低優先順序的任務阻塞高優先順序的任務。或者高優先順序的任務過多,導致低優先順序任務永遠不會執行。
- 進程隔離:Linux 中有用於進程資源隔離的 Linux CGroup,通過物理限制的方式為進程間資源控制提供了簡單的實現方式,為 Linux Container 技術、虛擬化技術的發展奠定了技術基礎。在工作中的實際應用,可以看看這篇文章:日誌壓縮資源消耗優化: Linux CGroup 的使用。
- 模塊隔離、應用隔離:很多線上故障的發生源於代碼修改後,測試不到位導致。按照代碼或業務的易變程度來劃分模塊或應用,把變化較少的劃分到一個模塊或應用中,變化較多的劃分到另一個模塊或應用中。減少代碼修改影響的範圍,也就減少了測試的工作量,減少了故障出現的概率。
- 機房隔離:主要是為了避免單個機房網路問題或斷電吧。
- 讀寫分離:一方面,將對實時性要求不高的讀操作,放到 DB 從庫上執行,有利於減輕 DB 主庫的壓力。另一方面,將一些耗時離線業務 sql 放到 DB 從庫上執行,能夠減少慢 sql 對 DB 主庫的影響,保證線上業務的穩定可靠。
- 第一種是,模塊A和模塊B只通過介面交互,只要介面設計不變,那麼模塊B內部細節的變化不影響模塊A對模塊B服務能力的消費。
- 面向介面設計下真正實現了將介面契約的定義和介面的實現徹底分離,實現變化不影響到介面契約,自然不影響到基於介面的交互。
- 模塊A和B之間的松耦合,主要通過合理的模塊劃分、介面設計來完成。如果出現迴圈依賴,可以將模塊A、B共同依賴的部分移除到另一個模塊C中,將A、B之間的相互依賴,轉換為A、B同時對C的依賴。
- 第二種是,將同步調用轉換成非同步消息交互。
- 比如在買機票系統中,機票支付完成後需要通知出票系統出票、代金券系統發券。如果使用同步調用,那麼出票系統、代金券系統宕機是會影響到機票支付系統,如果另一個系統比如專車系統也想要在機票支付完成後向用戶推薦專車服務,那麼同步調用模式下機票支付系統就需要為此而改動,容易影響核心支付業務的可靠性。
- 如果我們將同步調用替換成非同步消息,機票支付系統發送機票支付成功的消息到消息中間件,出票系統、代金券系統從消息中間件訂閱消息。這樣一來,出票系統、代金券系統的宕機也就不會對機票支付系統造成任何影響了。專車系統想要知道機票支付完成這一事件,也只需要從消息中間件訂閱消息即可,機票支付系統完全不需要做任何改動。
- 非同步消息解耦,適合那些信息流單向流動(類似發佈-訂閱這樣的),實時性要求不高的系統。常見的開源消息隊列框架有:Kafka、RabbitMQ、RocketMQ。