應用層的容錯與分層設計

jopen 10年前發布 | 13K 次閱讀 設計

應用層的容錯與分層設計

針對在項目中碰到的一些容錯設計問題,團隊最近進行了一次技術沙龍,討論了以下話題。

為什么需要應用層的容錯設計?

一個完整的系統在內部是由很多小服務構成,服務之間以及服務與資源之間會存在遠程調用。

  • 每個系統的可用性不可能達到100%
  • 各種網絡及硬件問題,如網絡擁堵、網絡中斷、硬件故障……
  • 遠程服務平均響應速度變慢

服務器平均響應速度如果慢下來,慢慢消耗掉系統所有資源,進而導致整個系統不可用。因此在分布式系統中,除了遠程服務本身需要有容錯設計之外,在應用層的遠程調用的環節,需要有良好的容錯設計。

應用層的容錯設計有哪些方法?以下是微博團隊使用過的一些實踐。


訪問MySQL的容錯設計

  • 寫操作:如果master異常,直接拋異常。
  • 讀操作:如果slave有多個,先選擇其中一個slave,如果獲取連接失敗,再選擇其他的slave,如果全部不可用,最后選擇master。


訪問Memcached/Redis的容錯設計

首先設置so_timeout,避免無限制等待;服務器連接如果IO異常,設置錯誤標志,一段時間停止訪問;出錯后定期主動(比如ping Redis)或被動(當被再次訪問時)探測服務是否恢復。

Failover機制:
如果連接某個node失敗, 當前pool啟用一致性hash切換到backup node;如果backup node沒有數據,則通過另外一個服務池(數據副本)獲取數據。


訪問遠程HTTP API的容錯設計

設置so_timeout;部分場景:短超時,重試一次;另外由于HTTP service情況的多樣性,業務層面還有通用的降級機制。


訪問不同資源使用不同方法存在的問題

從上面列舉的部分場景來看,在訪問不同資源時候,每種client訪問都有一些相通的原理,但卻要使用不同的重復實現。由于各個client獨立實 現,實現時候由于各個遠程服務協議及行為的差異,導致這些容錯原理無法直接復用。另外在代碼層面,不同的client也使用了不同年代的一些底層庫,一些 早期client的實現,數據層,連接層,協議層全部耦合在一起,也造成維護成本進一步加大。

比如之前一些服務開發中碰到的類似如下的問題:

  • hbase-client由于沒有實現容錯設計,導致訪問出現了抖動,影響了同一服務池的其他調用,需要增加類似MySQL client的容錯及快速失敗策略;
  • MySQL slave流量出現不均衡了,由于多個slave IP之間沒有使用公用的負載均衡策略,因此需要重新添加、上線及驗證。

另外目前分布式系統中大部分遠程資源都是IO bound而不是CPU bound,而client大部分又是同步調用,造成大部分調用都在等待遠程返回,同時也消耗了工作線程資源,以及大量線程context switch。


有沒有可能統一的client?

這些策略原理上是可以公用的,能否出一個統一的client層來一勞永逸?不過這個需求不是推ter干過嗎?

Finagle,不僅是平時理解的RPC框架,還有目標是想成為一個commons client,從另外一個層面,廣義上訪問遠程資源也都可以理解成RPC,所以Finagle也常稱為RPC框架。

Finagle implements uniform client and server APIs for several protocols, and is designed for high performance and concurrency.

在推ter體系,分布式服務可以從future, service, filter三個層次理解,容錯、超時、授權、tracing、重試等機制都是體現在filter中;而future則將client從多線程、隊列、連 接池、資源管理釋放出來,從關注控制流到關注數據流。并且默認變成異步方式。

應用層的容錯與分層設計

Finagle的FailFast模塊會避免分發請求到出現問題的服務,它通過來記錄到每個host的錯誤來進行標記,當出錯以后,Finagle會通過一個后臺線程定期重連以檢查是否恢復。當host宕機時,相關的service會標記成不可用。


如果來redisign一個通用的網絡client,它應該包括哪些元素?

  • 具有服務的分層設計,借鑒Future/Service/Filter概念
  • 具有網絡的分層設計,區分協議層、數據層、傳輸層、連接層
  • 獨立的可適配的codec層,可以靈活增加HTTP,Memcache,Redis,MySQL/JDBC,Thrift等協議的支持。
  • 將多年各種遠程調用High availability的經驗融入在實現中,如負載均衡,failover,多副本策略,開關降級等。
  • 通用的遠程調用實現,采用async方式來減少業務服務的開銷,并通過future分離遠程調用與數據流程的關注。
  • 具有狀態查看及統計功能
  • 當然,最終要的是,具備以下通用的遠程容錯處理能力,超時、重試、負載均衡、failover……

來自:http://timyang.net/service/application-failure-managment/

     本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
     轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
     本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!