Google和eBay在建设微服务生态系统中的深刻教训
當我們觀察市場上的大規模系統,它們的系統架構往往都進化為非常相似的:一系列多語言聚合的微系統。比如Google、Twitter、eBay和Amazon。
那么在這種多語言聚合的微系統環境中工作的看法是如何呢?Randy Shoup,作為一個曾經在Google以及eBay高層工作過的過來人,關于Google和eBay在服務架構收縮性的經驗有一些有趣的想法分享。
我非常喜歡Randy演講的是,他善于引導沉浸式的思維幫助聽眾去感受那些可能從來沒有經歷過的,比如創造、使用、延續和保護大規模的系統架構。
在Randy的生態服務領域演說中,他對生態部分提了一個問題:一個大規模的多語言聚合微服務生態系統到底是什么樣的?
- 對于運維服務的問題是:運維這樣的服務對于服務提供者是什么樣的感受?
- 對于開發服務的問題是:當你作為一個服務的所有者是什么樣的感受?
- 對于反面模式服務的問題是:哪些是可能出錯的?
這是一個非常有效的方法。
整個演說的亮點對于我來說是關于激勵機制的想法,一個一致且貫穿始終的主題。雖然從未明確地作為一個單獨的策略被提出。這是一切的背后隱藏激勵因素,包括為什么我們需要小型團隊、并且開發小且簡潔的服務;為什么內部服務按服務器分配策略如此有效;系統架構是如何在沒有架構師的情況下進化;簡潔的設計如何自底向上進化;以及標準規則如何在沒有中央委員會的管控下進化。
我的理解是在實施此類激勵機制之前,我們必須非常深思熟慮。因為我們將要做的是基于大型且動態的代碼基礎,來調整大型且動態的組織架構。假如激勵方向正確,我們并不需要非常明確的管控就可以輕而易舉的實現目標。同樣的,我們也可以更高效的在分布式系統下工作,假如我們能夠消除那些相互依賴鎖,不必依賴狀態共享、消息機制、等來同步所有東西。
讓我們來看看在現代開發模式下的大型可伸縮性系統是如何構建的
多語言聚合微服務是游戲終結者
eBay從1995年開始至今已經演化到了第五代系統架構
- 剛開始是整體Perl實現,由創始人在1995年的一個勞動節周末完成
- 接下來是遷移到整體C++實現,一共包含三百四十萬行左右的單一動態鏈接庫
- 基于之前的經驗,接下來用java遷移到了更加分布式分區的系統架構下
- 今天的eBay仍有大量的java代碼存在,但是一系列的多語言微服務正在崛起
Twitter的演化非常的類似,基本上他們已經有過三代不同的系統架構
- 剛開始是整體Ruby on Rails實現
- 然后前端是Javascript和Ruby的結合,以及大量Scala在后臺
- 最終他們遷移到了我們今天所看到的一系列多語言微服務架構
Amazon也是走的同樣的路子
- 開始是整體的C++實現
- 然后服務轉向Java和Scala
- 最終走向一系列多語言微服務架構
服務的生態系統
當前有成百上千個獨立的服務工作在一起支撐著eBay和Google的業務
- 現代大型系統更傾向于圖狀結構,而非樹狀層級結構
- 當服務被其他很多服務所依賴的同時,其他很多服務也會依賴于它
- 較老的大型系統典型架構遵循嚴格的層級結構
服務生態系統如何創建?
例如,下列一些分層服務的谷歌應用程序引擎。
- 層次是非常清晰的。每一層都會增加一些并不包含在它下一層的內容,這并不是自頂向下的產品設計。
- 這實際上是自底向上的實現結果。Colossus是Google的文件管理系統,所以它必須首先被創建。幾年之后是Bigtable,然后再過幾年是Megastore,之后幾年才是云數據存儲集成在Megastore之上。
- 你完全不必要如此自頂向下的架構設計,就可以擁有像這般優秀的產品
這是沒有架構師的系統架構。沒有人在Google有架構師的頭銜。這里也沒有一個中心來管控技術走向。大多數的技術方案是由各個獨立的本地團隊自己決定,而不是全球總部的決策。
對比2004年的eBay。當時他們有一個架構評審委員會來負責所有的大型項目。
- 通常當任何項目變更需求到達這個委員會被評審時已為時過晚
- 這個集中化的評審結構成了一個瓶頸,經常性的它的唯一作用就是在最后一分鐘說不
對于eBay來說一個更好的方法來處理這種情況是,把這些有經驗的評審委員會專家的經驗歸檔整理,并設計成可由各個團隊重復使用的庫文件或者一系列的指導文件,由此幫助團隊獨立決策而不是在最后一刻才提交給評審流程。
標準如何在沒有架構師的情況下進化?
這是可能的,即在沒有中心控制的情況下形成標準化
- 標準化往往產生于各個服務和通用的基礎設施通信過程中。
- 標準之所以成為標準是因為它們比其他可選項更加合適。
通信部分往往已經標準化
- 網絡協議。Google所使用的自身協議名為Stubby,eBay所使用的是REST。
- 數據格式。Google所使用的協議是Buffers。eBay更傾向于使用JSON。
- 接口架構標準。Google使用Buffers。eBay使用的是JSON
通用基礎設施部分往往也已經是標準化的。
- 源代碼控制。
- 配置管理。
- 群集管理器。
- 監控系統。
- 警報系統。
- 診斷工具。
- 以及所有這些組件演化出來的公共規約
在一個進化的環境中,標準是通過下列強制方式來得到的:編碼,鼓勵,代碼審查,以及代碼搜索。
- 在實踐中所鼓勵的最好最簡單的辦法即實際編碼。這不是自上而下的審查,或預先設計的,而是通過最簡單直接的方式來把工作做好。
- 激勵的方式在于鼓勵團隊通過庫函數形式來實現更高的代碼復用
- 激勵也可以通過鼓勵服務去支持對于更多協議的支持
- Google非常著名的一點就是它的每一行代碼在實際更新到代碼庫之前,都會被至少一個其他程序員審查過。這是一種非常號的通用溝通實踐。
- 在極端情況下,Google的工程師可以去搜索整個代碼庫。這意味著巨大的附加價值,當每個程序員試圖理解如何完成任務時。基于超過一萬個工程師的工作成果,如果你正在嘗試做一些別人已經做過的類似的東西,這可以允許你基于代碼庫參考和學習最佳方案。當然,這也會幫助你避免前人已經犯過的錯誤。
鼓勵共同的做法和規范的約定,讓做正確的事更容易,做錯誤的事更困難。
每個服務相對于其他服務都是獨立的個體
- 在Google,內部服務之間并沒有標準化的東西,每個服務對于外界都是一個黑盒。
- 這里有約定和公共庫,但是并沒有語言上的限制。主要使用的是四種語言:C++,Go,Java,Python。以及其他大量的服務都是由多種不同的語言實現的。
- 這里也沒有標準化的周邊框架或持久層機制。
在一個成熟的服務生態中,我們需要標準化規范的是大局,而非每個具體的點。我們只需要定義通用的交互方式,而非具體的實現。
創造新的服務
通常一個功能因為某個特定用例所創造時,就已經證明該功能是普遍性且有用的。
- 某個團隊會建立并開始拆分這個服務,從而形成獨立的單元。
- 上述動作僅僅發生在當該功能是成功的并且適用于很多不同的用例時。
這些架構的成長完全基于實用主義。沒有人能夠坐在高位來指揮某些服務應該增加。
卸載舊服務
建立服務
一個在大型系統架構中表現良好的服務應該具有如下特征:
- 目的單一性。這指的是簡潔良好定義的接口。
- 模塊化和低耦合度。我們稱之為微服務。
- 不共享一個持久層。這點接下來我們會詳細闡述。
服務所有者的目標是什么
在滿足客戶需求的前提下最小化所需要的成本和工作量。
- 這個目標和我們的激勵方向一致,即鼓勵最大化重用公共基礎庫。
- 每個團隊的資源總是有限的,所以團隊也會對于如何重用已經久經測試的公共工具,流程,組件,服務很有興趣。
- 同時這也會激勵團隊采用更好的部署方式,比如自動化服務的構建和部署。
0 總之這會激勵人們去優化使用他們有限的資源
誰構建誰運行
- 通常來說是某個小團隊來負責具體服務從設計、開發、部署,直至徹底廢棄。
- 沒有單獨的維護工程師或者支持團隊
- 團隊在服務范圍內有權選擇技術,方法和工作環境。
- 團隊為他們的選擇負責。
服務的上下文是有限的,因為:
- 團隊的認知負荷時有限的
- 我們也沒有這樣的需求,需要理解整個生態系統中的所有服務。
- 團隊只需要理解他自己們的服務,以及這些服務所依賴的服務而已。
- 這就意味著團隊可以非常小而靈活。一個典型的團隊就3-5人。(就如美國海軍陸戰隊的一個火力輸出單元就4個人)
- 小的團隊規模也意味這溝通可以非常高效。
- 基于康威定律“設計系統的組織,最終產生的設計等同于組織之內、之間的溝通結構”,因此小團隊最終會導致小服務組件。
什么是服務之間的關系?
- 推薦作為供應商的客戶關系服務之間的關系,即使你們是在同一家公司。
- 合作關系非常友好,但是聯系關系結構非常清晰。
- 所有權清晰。
- 非常清楚誰在負責什么。在很大程度上,這取決于定義和維護清晰的接口。
- 激勵方向清晰。因為客戶可以選擇用或者不用你的服務。這就鼓勵服務必須為客戶著想,某些時候這也是服務被構建觸發的原因。
- 客戶必須為服務付費。
- 付費服務可以從經濟上激勵團隊。這也鼓勵了雙方都會盡力保證資源的高效使用。
- 免費服務會導致工作成果得不到認可,并且也沒有熱情去優化服務。
- 比如:內部客戶曾經可以免費使用Google Apps引擎,他們占用了大量的資源。祈求他們更高效的使用這些資源不是一個合適的策略。當一周后他們收到賬單時,他們就立即采取措施降低了對于Google Apps引擎資源的占用多達90%以上。事實上這些措施僅僅是非常簡單的一兩個小改動。
- 這并不是說Google Apps引擎使用客戶是錯誤的,但是他們會有他們自己的優先級。因此,沒有激勵因素促使他們降低對于Google Apps引擎資源的占用。事實上,這最終導致了更高效的響應速度以及更高效的系統架構。
- 收費策略也會促使服務提供者提供更高質量的服務。否則這些內部客戶就會轉向使用其他服務。這種激勵直接導致了良好的開發和管理實踐。代碼審查就是其中一個案例,Google的龐大的構建和測試系統就是另一個。Google每天需要運行數以百萬計的自動化測試。在每個改動被提交到倉庫之前,驗收測試都必須在所有的代碼依賴路徑上跑過。這有效的幫助了所有小團隊都能保持他們服務的高質量。
- 另外,付費模式也鼓勵增量變化。小的變化更容易被理解。同時,代碼變更的量和最終的產生的影響不具有線性關系。一個上千行的代碼改動的風險不是十倍于一次一百行的改動,實際上要超過一百倍的風險。
維護接口的前后兼容性
- 永遠不要因為底層服務的變更而導致客戶原有代碼出錯
- 這意味這需要維護多個版本的接口。在一些麻煩的情況下,這意味著需要維護多個部署,一個最新的版本和其他多個老版本。
- 通常來說接口不會改變,因為我們會使用小步快跑的增量模型去開發。
需要一個明確的廢棄策略。服務提供者需要強烈推薦所有客戶盡快遷移到某個版本或者這個版本之上。
規模化運營服務
性能的可預測性是基本需求
- 任何服務在大規模系統中運行時的性能表現都可能大幅波動。
- 性能的可預測性甚至比所謂的平均性能要重要的多。
- 低延遲但是不穩定的性能表現,實際上完全不代表真正性能是低延時的。
- 基于一個性能可靠穩定的服務,客戶能夠更加容易的編碼實現。
- 某個服務之中的高延時會導致大量使用該服務的其他服務產生高延時。
- 假設一下,有一個服務的延時中位數是1毫秒,但是它有萬分之一的機會延時是1秒。
- 那么每次運行都意味著會額外損失0.01%的時間。
- 假如你現在在同時跑5000臺機器,就像很多如同Google這樣的大型系統服務一樣。那么你會額外損失50%的時間。
- 再比如,某個百萬份之一概率的內存緩存問題被發現,這會影響底層數據結構重新分配事務。這種罕見的問題暴露出來的表象就是在更高層次上的延遲大幅波動。像這種底層技術細節在大型系統架構中必須被非常重視。
高度彈性的容錯機制
- 服務中斷更多時候是由于人為錯誤,而不是軟硬件問題。
- 服務需要能彈性容錯,無論是機器,集群或者數據中心故障。
- 在調用其他服務時一定要考慮到負載平衡和流量控制。
- 需要能夠快速回滾任意改動。
增量部署
- 使用隔離系統。不要一次性部署所有的機器。選擇某個系統部署你的新版本軟件,然后觀察它在這個新系統中的行為表現。
- 假如工作已經進行到了大規模部署階段。剛開始只升級10%機器,然后是20%,以此類推直到所有。
- 假如在部署階段中發現問題的話,你仍然能夠選擇回滾。
- eBay曾經使用過一種部署機制,是基于功能標志位來分離新功能部署中的影響。典型來說,新功能會被默認部署為非激活狀態,然后它可以被開啟或者關閉。這樣可以保證在新功能開啟之前,這些代碼就可以被正確部署。同時,假如新的功能有Bug,比如說性能問題或者商業上的考量,那么我們可以非常簡便的關閉這個功能而不必再部署一次新代碼。
我們需要盡可能多的提醒,而不是盡可能多的監控。
反模式法設計服務
超大服務
- 不要在同一個服務做實現了太多功能。在這個生態系統中,你所需要的是簡潔精簡的服務。
- 一個同時實現太多功能的服務只是一個障礙。讓你難以理解,難以擴展,難以變更,同時也會產生遠超你所需要的和其他服務太多的上下行依賴關系。
共享持久層
- 在分層模型中,服務往往處于應用層,而持久層是作為一個公共服務提供給所有應用程序。
- eBay曾經嘗試過,并證明這個方法不可行。即嘗試打破服務封裝,應用程序可以通過后門直接更新數據庫。最終他們終止這個行為,重新改寫了若干服務。共享數據庫不再允許松耦合服務。
- 微服務通過小型化,隔離化,獨立化來防止問題產生。這也是如何是你的生態系統保持健康和成長的重點。
相關文章:
- On HackerNews
- Randy Shoup on Twitter
- Microservices - Not A Free Lunch!
- Google On Latency Tolerant Systems: Making A Predictable Whole Out Of Unpredictable Parts
- 10 EBay Secrets For Planet Wide Scaling (2009)
原文鏈接:Deep Lessons From Google And EBay On Building Ecosystems Of Microservices(譯者/王旭敏 審校/朱正貴 責編/仲浩)
譯者介紹:王旭敏,Nokia開發工程師,關注云計算、高性能或可用等架構、容器等。
總結
以上是生活随笔為你收集整理的Google和eBay在建设微服务生态系统中的深刻教训的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第一章 Web MVC简介 —— 跟开涛
- 下一篇: 近几年前端技术盘点以及 2016 年技术