google和ebay微服務經驗

摘自:http://www.infoq.com/cn/articles/ecosystems-of-microservices前端

多元化(polyglot)微服務是終極遊戲

  • 大規模系統和多元化微服務最終必定會有所牽連。其中,多元化的意思是多種語言共同編寫。
    • 建立於1995年的eBay共經歷了3次架構變動。
      • eBay最先採用的是創始人花費兩天時間所編寫的Perl程序。
      • 以後,它開始使用由340萬行C++代碼所編寫的程序。
      • 而後,eBay使用Java編寫的分佈式系統。
      • 如今的ebay仍然使用了大量Java,同時也使用了不少由多種代碼編寫的多元化微服務。
    • Twitter的架構變動過程相似。
      • 最先,Twitter採用的是Ruby on Rails。
      • 以後,它開始在前端使用JavaScript和Rails,然後端使用了大量的Scala代碼。
      • 目前,Twitter也一樣依賴於多元化微服務。
    • Amazon的架構變動一樣相似。
      • 首先,它使用的是C++程序。
      • 而後,採用了Java和Scala兩種語言。
      • 目前,Amazon也依靠多元化微服務。

服務的生態系統

  • 擁有多元化微服務的大規模生態系統運行狀況如何呢?
    • eBay和Google採用了數百到數千個單獨的服務來協同工做。
    • 如今的大規模系統都是以圖的形式,而不是層次式或多個鏈接的形式來構成服務。
    • 服務之間相互依賴。
    • 只有舊的大規模系統採用高度集成的方式進行組織。

如何建立服務的生態系統

  • 目前運行良好的系統都是不斷變革的產物。例如,Google歷來沒有對系統進行過集中的設計。當前的系統純粹是適應時代和技術發展演變而成的。
  • 變異和天然選擇。當一個新的問題出現,工程師一般選擇利用已有的產品或服務來解決。所以,一個服務只有在不斷的提供價值、不斷被使用的狀況下,才能避免被淘汰的命運。
  • 這些大規模系統採用了自底向上的設計方法。
  • 以Google App Enginer(GAE)中所使用的一些服務爲例:數據庫

     
    • Cloud Datastore嵌套依賴於如下服務:Megastore(一種結構化數據庫)→Bigtable(一種集羣級的結構化服務)→Colossus(一種集羣化文件系統)→Borg(集羣管理框架)。
    • 層次關係十分清楚。每一層都添加了下一層中不存在的一些東西。
    • 它採用自底向上的方法設計而成。首先是構建Colossus文件系統最後纔是Cloud Datastore。
  • 這是沒有架構師的架構。在Goolge,絕大部分的技術決策都是由小團隊站在本身的角度所採納,而非全局角度。編程

  • 2004年的eBay與之截然相反。當時,eBay採用了架構審查的形式,來對全部的大規模項目進行決策。其結果爲:後端

    • 一般審查人員都是在沒法改變項目的時候才介入。
    • 集中決策很快變成了一個瓶頸。它最大的影響就是在最後關頭投出否決票。
  • eBay後來改成把經驗豐富的工程師的想法放到審查板上,而後執行多個小團隊都會用到的項目。把這些想法封裝爲員工能夠本身使用的一個庫、一個服務或者一些指南,而不是在最後關頭進行決策。緩存

     

沒有架構師的變革如何定義標準

  • 標準化能夠在沒有集中控制的狀況下完成。
    • 標準化傾向於在不一樣服務或者架構之間的通訊中產生。
  • 通訊一般會被標準化爲:
    • 網絡協議。Google採用Stubby協議,而eBay採用REST協議。
    • 數據格式。Google採用Protocol Buffer,而eBay使用JSON。
    • 接口語法標準。Google採用Protocol Buffer,而JSON由本身的語法。
  • 框架中一般會被標準化的通用模塊包括:
    • 源碼控制。
    • 配置管理。
    • 集羣管理者。
    • 監控系統。
    • 警告系統。
    • 診斷工具
    • 全部可以脫離傳統的組件。
  • 在一個充滿變革的環境,標準是強制執行的:編碼、提交、代碼審查和代碼檢索。
  • 鼓勵最佳實踐的最好方式就是用實際的代碼說話。這不是自頂向下的審查或者前衛的設計,而是某我的可以編寫出讓工做盡快完成的代碼。
  • 鼓勵是經過團隊提供庫的方式進行的。
  • 鼓勵也經過工程師在支持X協議或Y協議時所依賴的服務進行。
  • Google在代碼方面廣爲人知的是:任何一行代碼在進行源碼控制時,至少由一個額外的編碼人員進行審查。這就是一種你們交流本身經驗的良好方式。
  • 絕大部分狀況下,Google的每個工程師均可以檢索整個代碼庫。在編程人員規劃如何實施一個事情時,代碼庫能夠提供很好的參考。在1萬個工程師不停工做的狀況下,一個編程人員想作的事情可能已經被其餘人提早完成了。這就使得一個好的項目可以經過代碼庫進行傳播。固然,代碼中的錯誤也一樣可能會傳播。
  • 爲了鼓勵通用項目和標準化的習慣,應使得作正確的事情簡單,而作錯誤的事情要困難不少。
  • 服務之間是相互獨立的。
    • 在Google,服務內部是沒有標準化實現的。對於外部而言,服務就是一個黑盒子。
    • 存在習慣和通用庫,可是沒有編程語言的要求。最經常使用的四種語言爲:C++、Go、Java和Python。不少不一樣的服務也採用各類各樣的語言編寫。
    • 沒有針對框架或持久力機制的標準化工做。
  • 在一個成熟的服務生態系統中,標準化的應該是圖的弧度,而不是節點自己。定義一個通用的形狀,而不是一個通用的實現。

建立新的服務

  • 新服務只有在他們的使用被證明的時候才被建立。
  • 一般,一種功能是爲一種特別的使用場景而設計。而後,該功能被發現通用並且有效。
    • 造成一個團隊,而後服務擴展到它本身單獨的單元。
    • 只有當一個功能得到成功,並且適用於多種使用場景時,該狀況纔會發生。
  • 這些架構經過實用主義的方法進行發展。沒有人能夠命令某項服務應該被添加。
    • Google文件系統支持搜索引擎。分佈式文件系統顯然更容易變得通用。
    • Bigtable初始支持搜索引擎,但卻沒有被普遍使用。
    • Megastore設計的初衷是做爲Google應用的存儲機制,卻被普遍使用。
    • GAE初始是由一羣工程師爲幫助設計網站而構建。
    • Gmail來源於Google內部常用的一個項目,而後才被推廣到外部使用。

棄用過期的服務

  • 若是一個服務再也不被使用會怎麼樣?
    • 能夠被從新定義目標的技術能夠被從新使用。
    • 工程師能夠被開除或者分配到其餘組。
    • Google Wave不是一個成功的市場案例,可是其中的一些技術卻應用到了Google App中。例如,支持多人編輯文檔的應用就來自於Wave。
    • 一般狀況下,核心服務會經歷屢次的更新換代,而老的版本就會被拋棄。Google內部就常常發生這樣的事情。

構建一個服務

  • 當服務擁有者在構建大規模多元化微服務的系統時,狀況是什麼樣的呢?
  • 在一個大規模框架中執行很好的服務應該是:
    • 目的單一。它應該擁有一個定義良好的接口。
    • 模塊化和獨立性。也就是所謂的微服務。
    • 不該該共享一個持久層。

服務擁有者的目標是什麼?

  • 知足客戶需求。在合適的質量水平下提供必要的功能,同時知足協議的性能、維護穩定性和可靠性以及不斷的改善服務。
  • 以最小的代價和努力知足需求。
    • 該目標以鼓勵通用框架的使用爲動機。
    • 每個團隊擁有有限的資源,所以應該使用通用的工具、流程、組件和服務。
    • 它也鼓勵好的操做行爲。自動化服務的構建和部署。
    • 它同時鼓勵資源的高效使用。

服務擁有者的責任是什麼?

  • 誰構建誰運行。
    • 通常狀況下,一個團隊,尤爲是一個小的團隊,負責服務的設計、開發、部署和最後的銷燬。
    • 沒有額外的運維團隊。
    • 團隊擁有選擇他們本身的技術、方法和工做環境的自由。
    • 團隊要爲他們的選擇負責任。
  • 做爲一個有限上下文的服務。
    • 一個團隊的認知負載是有限的。
    • 不必理解生態系統中的其餘服務。
    • 一個團隊須要深度理解其服務和他們所依賴的服務。
    • 這意味着團隊規模能夠很小、很靈活。一個典型的團隊是3-5我的。(如同美國海軍陸戰隊,一個小隊包含4個士兵。)
    • 如此小的團隊規模意味着團隊內的溝通能夠很是順暢。
    • Conway法則能夠很好的發揮優點。小團隊一般會構建一些小的組件。

不一樣服務間的關係如何?

  • 即便是在同一公司內,不一樣服務間的關係也如同廠商和客戶的關係。
  • 儘可能友好併合做,可是必定要慎重對待服務間的關係。
  • 必定要清楚所屬關係。
  • 必定要明確每一個人的分工。定義一個明確的接口,並維護好。
  • 客戶能夠選擇是否使用該服務是調整激勵的有效手段。經過客戶來鼓勵服務朝着正確的方向發展。這也是新服務構建的方式之一。
  • 定義SLA。由於服務提供商向客戶提供了必定的保證,客戶能夠依賴該服務。
  • 使用服務的團隊須要支付服務費用。
    • 向服務支付費用能夠帶來經濟上的激勵。它能夠刺激提供商和客戶有效利用資源。
    • 當東西免費時,人們老是不懂得珍惜。
    • 例如,一個內部客戶曾無償使用GAE,並使用了大量資源。要求他們更加高效的使用資源被證明並無論用。可是,在引入收費機制一週後,他們很快就可以經過1-2處的簡單修改,減小GAE 90%的資源消耗。
    • 並不是使用GAE的團隊不懂得珍惜。他們有本身更應該關注的方面,所以優化GAE的使用並不在他們的目標列表中。然而,事實證實,更加高效的架構可以帶來更好的反應時間。
    • 付費也可以刺激服務提供商來保證服務質量。不然,一個內部的客戶也可能轉而使用其餘服務。付費直接帶來好的開發和管理項目。代碼審查就是一個例子。Google的超大規模設計和測試系統是另一個例子。Google天天都會運行百萬次的自動化測試。一旦代碼被版本庫接收,全部相關代碼的接收測試就會被運行。這種方法能夠很好的幫助小團隊維護服務質量。
    • 一個返利模型能夠很好的鼓勵小的迭代式變化。小的變化更容易理解。而代碼變化的影響是非線性的。一千行代碼的變化所帶來的風險毫不止一百行代碼所帶來風險的10倍,而是要100倍左右。
  • 維護接口的全正向/逆向兼容。
    • 絕對不要破壞客戶端代碼。
    • 這意味着維護多個接口版本。在一些狀況下,它意味着維護多個部署:一個用於新版本,其餘的用於老的版本。
    • 由於小的增量變化,模型接口一般不會被修改。
  • 擁有一個顯式的丟棄策略。服務提供商主動把全部的用戶從版本N升級到版本N+1。

操做大規模服務

  • 做爲一個服務提供商,操做多元化微服務的大規模系統中的服務是怎樣的呢?
    • 可預測的性能是基本要求。
      • 大規模服務很容易出現性能上的變化。
      • 性能的可預測性要遠比平均性能重要的多。
      • 沒法保證性能的低延遲根本就不能算是低延遲。
      • 當服務提供可預測的性能時,客戶更容易針對服務進行編程。
      • 當一個服務使用不少其餘的服務來完成相關工做時,延遲最大的服務決定了該服務的性能。
      • 以平均延遲爲1ms、最大延遲以0.001%的機率爲1s的服務爲例:
      • 調用一次該服務就意味着0.01%機率時間延後。
      • 那麼,對於一個Google所採用的包含5000臺機器的大規模服務而言,延後時間機率就爲50%。
      • 例如,內存緩存相關的問題會以百萬分之一的機率被追蹤到一個底層數據結構的從新分配事件。但延遲出現大的抖動時,這個問題就會浮現到較高的層。然而,底層的細節對於大規模系統才十分重要。
    • 深度的可靠性。
      • 服務中斷通常都是人爲操做引發,而非硬件或軟件錯誤。
      • 必定要能夠應對機器、集羣和數據中心的失效。
      • 當使用其餘服務時,要實現負載均衡和流量控制
      • 支持快速回滾操做。
      • 增量部署。
      • 不要一次就部署到全部的機器。選擇一個系統,把新版本的軟件部署上去,而後觀察系統工做狀況如何。
      • 若是工做狀況良好,就把部署的機器規模擴張到10%,而後20%,最後纔是全部的機器。
      • 若是部署到50%時出現問題,要可以進行回滾操做。
      • eBay利用特徵選項來解耦合代碼部署和特徵部署。一般狀況下,首先關閉特徵,而後部署代碼,最後再選擇打開或關閉特徵。這使得代碼能夠在新的特徵打開以前被正確部署。同時,這也意味着,若是新的特徵存在bug、性能問題或者業務問題,特徵能夠在不部署新代碼的狀況下被關閉。
    • 警告可能會多,但監控卻永遠不會多。

反模式服務

  • 超級服務:
    • 其實,客戶想要的是一個擁有小服務的生態系統。
    • 超級服務難以去理清、擴展、變化,也會構造出更多的上游和下游的依賴。
  • 共享的持久化
    • 在分層模型中,服務放置在應用層,而持久化層則是一個提供給應用的通用服務。
    • eBay也採用了一樣的方法,可是無論用。它破壞了服務的封裝。應用程序能夠經過升級數據庫「黑」進服務。它最終會從新引進多個服務。共享數據庫不容許鬆耦合服務。
    • 微服務經過變得小、隔離和獨立來預防該問題,也經過這種方式來保證生態系統健康成長。
相關文章
相關標籤/搜索