微服務、容器與持續交付

貓飯先生發表於2017-10-12
本檔案的是微服務、容器與持續交付【編者的話】就像木炭、火硝和硫磺遇到了一起。當微服務、容器和持續交付遇到了一起,這注定會掀起一場變革。

微服務

如果非要給微服務找一個理由,單一職責就足夠了。我們把因相同原因而變化的東西聚合到一起,而把因不同原因而變化的東西分離開。我們稱之為單一職責原則SRP。

尤其是大型和長期運營的專案群,隨著時間的推移,需求一定是不斷增加和變更的。但我們不希望掉進“焦油坑”。我們希望我們的專案群是符合“開閉原則”的。在某個時期我們寄希望於一個統一的“平臺”,我們規定專案使用相同的架構和開發語言,使用統一的、集中式的資料庫,我們要求平臺上的每個專案或者模組高度的“標準化”。在一段時間內“平臺”執行的非常良好,一切都在可控範圍內。

直到有一些“怪”需求的出現,直到這些“怪”需求,得要一些“怪”技術才能實現。又直一個新的模組被合併到“平臺”中需要不眠不休幾個晚上,再直到運維的成本突破了“天際”……我們驚醒在《人月神話》的“焦油坑”中。

這道理很簡單,耦合的越是緊密的整體,任何一個部分的失敗,都是整體的失敗。所以我們希望整體中的任何一個部分都和整體是鬆耦合的。整體中的任何一個部分我們都認為是能力的提供者。整體擁有什麼樣的能力,是由它聚合了什麼樣的部分決定的。而非它自己本身的能力。
微服務的理念完美的詮釋了這一切。我們希望整體中的每一個部分是這樣的: 

  • 小而自治

    一個微服務就是一個SRP的獨立個體。根據業務邊界來確定服務邊界。避免與其他服務共用資源,包括,資料庫、程式、IP及埠。服務之間通過標準網路協議進行通訊。服務會暴露出API,所有的呼叫均通過API完成。

  • 技術異構

    上面我們提到了“怪”需求,比如,大資料分析,分散式實時計算等等。其實需求並不怪,只是要實現這些需求要使用的技術不一定就是一個生態中的技術。又比如,你的團隊擅長Java,而他的團隊擅長.Net。只要能多快好省的實現功能,只要你的服務最終暴露出來的API是可用的,用什麼技術又何妨呢?在要求技術統一的大一統時代這是不可想象的。

  • 彈性伸縮

    一個整體中總是有一些部分會被頻繁的呼叫,也是壓力和瓶頸的所在。我們希望這些部分可以實現彈性伸縮,當執行壓力大的時候,這個部分可以被建立多個執行例項,以實現負載均衡。而這如果要在傳統的鐵板一塊的系統中實現,是很笨拙的,因為他的複製是整體的。

  • 適應組織結構

    由多個團隊維護一個耦合性很高的系統是非常困難的。微服務可以很好的將架構與組織結構相匹配。一個微服務由一個小團隊獨立完成。這也更符合康威定律。

  • 簡化部署

    一個鐵板一塊的系統,不論是增加一個模組,還是修改一個模組,這都非易事,而且這個整體越龐大,這個過程會越恐怖。試想一個幾百萬行程式碼的系統,我只改了一行,現在需要釋出,這個場景有多令人頭疼。而一個小而自治的微服務,它的一切,包括程式,包括資料庫,這些都是隻屬於它自己的。它的部署既不依賴其它服務,也不影響其他服務。這又證明了鬆耦合的微服務架構的優勢。

  • 可複用可組合

    在微服務的架構下,應用是面向服務的。服務不再屬於某一應用,而是可以為不同的應用提供相應的能力。換言之,若干個微服務的“組合”會“創生”出一個新的應用。


微服務的架構能幫助我們多團隊、細粒度、更快速的交付軟體。它在技術決策上給了我們極大的自由度,能使我們更快速的響應不可避免的變化。尤其是在當前的雲架構下,微服務更是構建PaaS的最佳實踐。

容器

利用微服務的思想,我們以業務邊界確定服務邊界,構建出若干個小而自治的微服務。這不僅解決了團隊協作問題,也解決了系統的高耦合、複用、擴充套件等問題。但部署問題絕不是簡單的一個“拆”字能解決的。

不管是你的服務還是應用,部署總歸是一個複雜的事情,要考慮的因素太多,比如,硬體環境、作業系統、執行環境、網路、配置等等。在有了虛擬化技術之後這一問題好像有所緩解。我們把作業系統、執行環境、軟體等打包成一個VM映象。需要部署的時候只要啟動這個映象,就完成了部署。

但仍有幾個問題難以解決:第一,組裝應用或服務的VM映象仍然不是一件容易的事情,而且很難自動化完成。第二,VM很重,裡面有作業系統,在服務和應用需要擴充套件的時候,啟動一個VM就是啟動了一個作業系統,這至少是分鐘級的。而且作業系統整個成為了應用或服務的“執行框架”,極大的浪費了資源,這就好比用一艘貨輪運送一個包裹。我們雖然可以有微服務但是很難“微部署”。

容器技術的發展給我們帶來了新的解決方案,以Docker為例。

第一,它非常輕量級。Docker容器也是基於映象機制。在Docker映象的底層是一個Linux核心,它遠比作業系統要輕量級的多。啟動一個容器是秒級的。

第二,一個作業系統上可以執行若干的容器。極大的節約了資源。

第三,容器成為了服務和應用的標準輸出,極大的降低了因部署包差異性造成的運維成本。

利用容器技術,可以實現對微服務的“微部署”。進而利用諸如Kubernetes的容器管理平臺,實現對容器的治理。不僅實現容器的編排、管理,還是實現了對容器的多叢集管理、彈性伸縮等。

把原來的部署和運維的問題,由管理個性化的部署包,變更管理標準化的容器。

持續交付

當微服務遇到了容器,小而自治的服務有了小而自治執行框架。這時候的問題就是如何以最快的速度交付軟體,並不斷複製這一過程。

利用敏捷的方法,我們縮小了研發的週期,以快速交付可用的版本,持續的優化我們的產品。持續交付是這一過程的重要理論。

在持續交付中,我們試圖構建一個“交付生態圈”,將開發、測試、運維、實施以及使用者結合成一個整體。我們希望:

  1. 讓軟體構建、部署、測試和釋出過程對所有人可見,促進合作。
  2. 有效的反饋,以便在整個過程中,我們能夠更早地發現並解決問題。
  3. 使團隊能夠通過一個完全自動化的過程在任意環境上部署和釋出軟體的任意版本。


持續交付關注幾個方面:

  • 配置管理

    配置管理是持續交付的先決條件,配置管理策略將決定如何管理專案中發生的一切變化。它記錄了我們的系統以及應用程式的演進過程。更重要的是,也是對團隊成員協作方式的管理。

    在配置管理中我們以版本管理為手段,管理的內容包括:程式碼、依賴、配置以及環境。

    配置管理的第一要務就是管理程式碼。只有頻繁提交程式碼到主幹你才能享受版本控制帶來的眾多好處。我們提倡:1)對所有內容進行版本控制2)頻繁提交程式碼到主幹3)使用意義明顯的提交註釋

  • 持續整合CI

    說到CI,就要說說CI的三個先決條件:版本控制、自動化構建、團隊共識。

    版本控制上面已經說過,其重要性不用贅述。自動化構建不管是使用TFS還是Jenkins,實現自動化構建不是難事。而在CI中最關鍵的其實是團隊共識,團隊共識是CI能夠持續執行下去的一個重要條件。比如這些:

    • 構建失敗之後不要提交新程式碼
    • 提交前在本地執行所有的提交測試,或者讓持續整合伺服器完成此事
    • 等提交測試通過後再繼續工作
    • 回家之前,構建必須處於成功狀態
    • 時刻準備著回滾到前一個版本
    • 在回滾之前要規定一個修復時間
    • 為自己導致的問題負責
    • 測試驅動開發
  • 測試

    將各種測試手段和方法結合到持續交付的各個環節中,是保證交付軟體質量的重要環節。這裡我們推崇TDD的方式,從軟體的設計階段就將測試考慮進來:

    • 客戶、分析師和測試人員定義驗收條件
    • 測試人員和開發人員一起基於驗收條件實現驗收測試的自動化
    • 開發人員編碼來滿足驗收條件
    • 只要自動化測試失敗,無論是單元測試、元件測試還是驗收測試,開發人員都應該把它定為高優先順序並修復它。


不論是單元測試、功能性測試、效能測試還是非功能性測試。絕不是在開發完成之後才開始考慮的。

對於測試,持續交付依然是推崇先立規矩再選工具。

在持續交付中,我們希望構建一個平衡的狀態。在分支版本上進行開發,完成後合併入主幹版本。利用CI,主幹版本可以每日構建併發布到測試環境,期間以自動化的單元測試、功能測試、效能測試工具進行測試。發現問題及時回滾版本並進行反饋。構建的過程不單單是程式碼的編譯,還包括依賴、配置以及環境。當構建和測試完成並通過後,按計劃將標準的部署包釋出到生產環境。在整個這一過程中,所有專案的干係人都將是持續交付團隊的成員。

當持續交付遇到容器的時候,這一切又變得更為完美了。首先是配置管理環節中最為複雜的環境管理和依賴管理一下子就變得單純了。首先由於容器對各種環境的隔離和封裝,使我們在持續交付中可以更關注程式碼本身的版本控制。其次,微服務對整體的解耦可以大大降低依賴管理中對其他服務依賴,從而減輕了持續交付中依賴管理的難度。甚至如果你擁有一個PaaS,那麼這個話題就完全可以拋給“服務治理”這個命題。

我們再來看,當微服務、容器和持續交付相遇的時候。容器使得微服務得以“微部署”。持續交付的整個理念又保證了微服務的交付速度與質量。而容器和微服務又使得持續交付變得單純和可控。

微服務、容器和持續交付的相遇,雲時代的一場變革!

原文連結:微服務、容器與持續交付(作者:劉玉龍)

原文釋出時間為:2016-09-14

本文作者:劉玉龍

本文來自雲棲社群合作伙伴Dockerone.io,瞭解相關資訊可以關注Dockerone.io。

原文標題:微服務、容器與持續交付


相關文章