《微服務設計》閱讀筆記十一

《微服務設計》,Building Microservices,作者Sam Newman,譯者崔力強、張駿,人民郵電出版社,2016年。

筆記中有些內容直接引用原書。

================================================================

第十一章規模化微服務

1.故障無處不在

要假定故障會發生,以這種想法來處理每一件事情,為故障做好準備。

2.多少是太多

不同的系統對容忍的故障程度、系統的響應速度等都是不一樣的,需要根據這些因素選擇技術,需要讓客戶了解不同級別的服務對應的成本。

響應時間/延遲。可以用不同數量的用戶來測量。“我期望這個網站,當每秒處理200個并發連接時,90%的響應時間在2秒以內。”

可用性。服務能出現故障嗎?是24/7服務嗎?

數據持久性。多大比例的數據丟失是可接受的?數據應該保存多久?

3.功能降級

功能降級的需求要從業務角度出發。

4.架構性安全措施

架構性安全性措施是一些組合的模式,確保如果事情真的出錯了,不會引起嚴重的級聯影響。舉了一個之前網站由于下游服務響應緩慢導致級聯故障的例子,采取的措施是:正確的設置超時;實現艙壁隔離不同的連接池;實現一個斷路器。

5.反脆弱的組織

《反脆弱》一書的作者Nassim Taleb認為事物實際上受益于失敗和混亂。Netflix通過引發故障來確保其系統的容錯性。Netflix開源了混亂猴子(Chaos Monkey)、混亂大猩猩(Chaos Gorilla)以及延遲猴子(Latency Monkey)項目,它們分別用于模擬關閉服務器、關閉可用區以及網絡延遲。讓軟件擁抱和引發故障,從失敗中學習。

超時。下游服務超時,等待太長來決定調用失敗,整個系統會變慢。太短會讓正常工作的調用被認為失敗。沒有超時,一個宕掉的下游系統會讓整個系統掛起。要給所有跨進程調用設置超時,并選擇一個默認時間。超時發生,記錄日志。

斷路器。當對下游資源的請求發生一定數量的失敗后,打開斷路器,請求會迅速失敗。過段時間再發送檢查,如果下游服務恢復正常則關掉斷路器。一些斷路器實現:Netflix的Hystrix庫(基于JVM),.NET的Polly,Ruby的circuit_breaker mixin。

艙壁。艙壁通過隔離避免級聯故障。在第4節的例子中,就是對不同服務使用了不同的連接池來隔離。還可以使用關注點分離,通過把功能分離成獨立的微服務,隔離故障影響。斷路器也算蜜蜂艙壁的一種自動機制。

隔離。服務間加強隔離,最好能做到上游服務可以允許下游服務離線。

6.冪等

多次執行同一操作,與執行一次該操作效果相同。使消息的處理成為冪等能減少很多工作量。

7.擴展

擴展系統的原因:處理失敗;提升性能。

更強大的主機。這是垂直擴展。

拆分負載。單服務單主機模式擴展為多服務多主機模式。

分散風險。不要把雞蛋放在一個籃子里。例如,不要把多個服務放在一臺主機上。要考慮SAN的故障,它會引起所有虛擬機不可用。不要讓所有服務運行在同一個數據中心的同一個機架上。了解云服務商的SLA(Service-Level Agreement)保證,確保和自己的需求相匹配。

負載均衡。使用負載均衡器,有硬件有軟件(如mod_proxy)。能提供SSL終止功能(將HTTPS連接在內部轉換為HTTP連接)的能簡化單個主機運行實例的配置。負載均衡器的配置要和服務的配置一樣通過版本管理系統管理起來,要能自動化應用。

基于worker的系統。該系統也可以像負載均衡一樣分擔負載降低脆弱性。通過待辦作業列表來分配作業到不同的worker,需要一個持久化的消息代理或Zookeeper。

重新設計。前期將精力放在更重要的事情上,當確實有大量負載來了,再去考慮解決,必要時重新設計。

8.擴展數據庫

服務的可用性和數據的可用性。要意識到二者的區別。

擴展讀取。通過主節點副本可以做到擴展讀取,不過建議先采用緩存(簡單并且性能改善顯著),其次才考慮副本。

擴展寫操作。數據分片解決擴展寫。看看Cassandra、Mongo或者Riak這樣的數據庫系統。

共享數據庫基礎設施。可能引起單點故障。

CQRS。命令查詢職責分離(Command-Query Responsibility Segregation)模式,系統一部分負責獲取修改狀態的請求命令并處理它,另一部分負責處理查詢。內部用于處理命令和查詢的模型是完全獨立的,可以使用不同的服務或在不同的硬件實現,可以使用不同的數據存儲,因此擴展性強。

9.緩存

客戶端、代理和服務器端緩存。代理緩存可以用反響代理或CDN;服務器端緩存可以用Redis或Memcache。

HTTP緩存。cache-control指令,Expires頭部,實體標簽Etag。它們的使用可以參考《REST實戰》。

為寫使用緩存。有爆發式寫操作或同樣數據可能被寫入多次,后寫式緩存很有作用。

為彈性使用緩存。在服務不可用時可以使用緩存代替一些服務。

隱藏源服務。緩存消失時,如果源服務無法應對大量請求,則不要請求。可以由源服務在后臺重建緩存,也可以原始請求快速失敗,避免級聯故障。

保持簡單。避免太多地方使用緩存。

緩存中毒:一個警示。需要了解數據從數據源到終點的完整緩存路徑,從而真正理解它的復雜性以及使它出錯的原因。

10.自動收縮

可以根據負載趨勢變化來觸發自動收縮,以響應負載。另外,自動伸縮被更多應用于響應故障。

11.CAP定理

一致性(consistency)、可用性(availability)、分區容忍性(partition tolerance),三個中最多只能保證兩個。

犧牲一致性。

犧牲可用性。

犧牲分區容忍性。

AP還是CP。需要根據具體情況權衡。

這不是全部或全不。不同的服務可以是不同的性質,有的是AP,有的是CP,并不是整個系統中的所有服務都保持一致。

真實世界。在真實世界中,無論系統本身如何一致,都難以做到和真實世界的一致。因此,很多情況下,AP系統是最終正確的選擇。

12.服務發現

服務實例要能夠注冊,其它服務要能夠找到已經注冊的實例。

DNS。可以使用DNS解決方案。更新DNS條目有些痛苦。亞馬遜的Route53做的不錯,但可選的自托管服務中,沒有那么好的。

13.動態服務注冊

比DNS更適用于高度動態的環境發現節點。

Zookeeper。被用于很多場景:配置管理、服務間的數據同步、leader選舉、消息隊列和命名服務。Zookeeper能確保數據在多個節點之間安全地復制,并且當節點故障后仍能保持一致性。

Consul。也支持配置管理和服務發現,其殺手級特性之一是提供了現成的DNS服務器。還具有對節點進行健康檢查的能力。

Eureka。Netflix開源的系統,提供了基本的負載均衡功能,支持服務實例的基本輪訓和調度查找。

構造你自己的系統。可以使用AWS的API來構造。

別忘了人。要有工具能在注冊中心上顯示報告和儀表盤給人看。

14.文檔服務

要能生成服務的API文檔。

Swagger。提供的終端用戶體驗不錯,為超媒體核心中的增量探索概念做的很少。

HAL和HAL瀏覽器。Hypertext Application Language是一個描述公開的超媒體控制的標準。在使用超媒體的話,建議用HAL,沒使用的話建議用Swagger。

15.自描述系統

Martin Fowler提出的人文注冊表方法,有一個地方可以讓人們記錄組織中有關服務的信息,和維基一樣簡單。從活系統中抽取一些數據,形成靜態Web頁面或維基是一個好的開始。

16.小結

推薦Nygard的書《Release It!》,分享了關于系統故障的故事以及處理它們的模式,對于構建任何規模化系統都強烈推薦。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,993評論 19 139
  • 微軟AzureCAT模式和實踐團隊發布了9個新的設計模式。這9個設計模式在設計和實現微服務時很有用。 下圖展示了這...
    zlup閱讀 2,116評論 0 2
  • 一:微服務概念 1、微服務的產生 隨著領域驅動開發、持續交付、按需虛擬化、基礎設施自動化、容器技術、小型自治團隊、...
    黃無有閱讀 2,693評論 1 7
  • 分布式系統面臨的第一個問題就是數據分布,即將數據均勻地分布到多個存儲節點。另外,為了保證可靠性和可用性,需要將數據...
    olostin閱讀 4,633評論 2 26
  • 記住海邊的一處城堡 讓你愛的人去那里暫住 你沉迷于他的誘惑 要去那里與他同居 聽風在耳畔獵獵作響 讓云在心靈漫步 ...
    江城妖怪閱讀 138評論 0 0