DevOps 核心能力: 技術篇--架構
DevOps 研究和評估 (DORA) 團隊的研究表明,架構是實現持續交付的重要預測因素。無論您使用的是 Kubernetes 還是大型機,您的架構都可以促成團隊採用提升軟體交付效能的做法。
當團隊採用持續交付做法時,以下架構做法有助於取得成功的結果:
團隊可以在無需團隊外部人員許可或依賴其他團隊的情況下,對其系統設計進行大規模更改。團隊無需與團隊外部人員進行精細的溝通和協調即可完成工作。團隊按需部署和發布其產品或服務,與團隊所依賴的服務或依賴該團隊的其他服務無關。團隊按需執行大部分測試,無需集成式測試環境。團隊可以在正常工作時間進行部署,且停機時間可以忽略不計。通過大型機技術有可能實現這些結果。但即使採用最新、最流行的技術,也有可能無法實現這些結果。許多組織在技術採用方面投入了大量的時間和精力,但由於架構造成的限制,未能實現關鍵的軟體交付結果。
如果系統的架構設計旨在讓團隊能夠在不依賴其他團隊的情況下測試、部署和更改系統,則團隊之間幾乎不需要溝通即可完成工作。換句話說,架構和團隊都是鬆散耦合。
溝通的強度與系統架構之間的這一聯繫最初是由 Melvin Conway 論述的,他提到:「設計系統…的組織受到限制,完成的設計往往是這些組織內部溝通結構的複製」。為抵消緊密耦合的架構並幫助支持更好的溝通模式,團隊和組織可以使用反向康威操縱,通過這一技術,團隊結構和模式的設計可提升預期的架構狀態。這樣,團隊溝通模式可以支持和實施所構建的架構模式。
如果採用緊密耦合的架構,細微更改可能會導致大規模的級聯故障。因此,在系統的某個部門工作的任何人都必須經常性地與在系統其他部門工作的任何其他人協調,包括應付複雜、繁文縟節的變更管理流程。
微服務架構本應該能夠實現這些結果,就像任何真正的面向服務的架構一樣。但實際上,許多所謂的面向服務的架構不允許相互獨立地測試和部署服務,因此不會使團隊達到更高的軟體交付效能。在實現面向服務的架構和微服務架構時,必須嚴格要求取得這些結果。
如何實現持續交付架構
考慮主要的架構原型。Randy Shoup 是 App Engine 前工程總監和 WeWork 前工程副總裁,他注意到以下情況:
「沒有一個完美的架構適用於所有產品和所有規模。任何架構都滿足特定的一組目標或一系列要求和限制條件,例如產品上市期、易於開發功能、擴縮等。任何產品或服務的功能幾乎都必定會隨著時間的推移而不斷演進,因此我們的架構需求也會隨之改變就不足為奇了。架構在規模為 1 倍時適用,但在規模為 10 倍或 100 倍時很少適用」。
考慮到架構原型的優缺點,每個架構原型都符合組織不同的發展需求。
如上表所示,支持精簡產品開發工作的單體式架構(例如,快速設計新功能原型、潛在策略變化或重大策略變化)不同於需要數百個開發者團隊的架構,這些團隊必須能夠獨立為客戶帶來價值。通過允許架構不斷演進,您可以確保架構始終能夠滿足組織的當前需求。無論原型如何,在設計架構以便於持續交付的過程中,團隊都必須有能力實現本文檔簡介中所述的功能。
打造跨職能團隊以及組織中的代表(產品、開發、測試和運營)使團隊能夠獨立開展工作,並有助於圍繞團隊邊界進行構建。如果您的團隊是跨職能團隊,則團隊可以自主行使職責,發揮創意並選擇自己的工具。為有助於跨團隊溝通和測試,最好是明確定義服務之間的合同。
團隊獨立性很重要,產品和服務的獨立性也很重要。服務必須能夠根據需要進行測試。採用有關模擬外部服務和對外部進行存根的技術有助於減少外部依賴性的影響,並讓團隊可以快速創建測試環境。此外,實現外部服務的合同測試有助於確保對團隊服務或其他服務的依賴性仍會得到滿足。為真正實現持續交付,單個團隊的產品或服務必須獨立完成驗收測試,並從所依賴的服務中進行部署。
如需啟用隨時部署功能,請考慮實現藍綠部署模型或滾動部署模型,並實現高度自動化。使用這些模型時,至少有兩個或更多產品或服務版本同時運行。藉助這些部署模型,團隊可以驗證更改並部署到生產環境,並且停機時間極少甚至沒有。一個重要的考慮因素是如何執行數據升級,這意味著數據和架構必須以向後兼容的方式完成。
為有助於獨立部署組件,我們建議您創建向後兼容的版本化 API。確保 API 向後兼容增加了系統的複雜性,但是您在簡化部署方面獲得的靈活性價值要數倍於增加的複雜性。
面向服務的架構和微服務架構能夠實現這些功能,因為它們使用有界限上下文和 API 將大型網域分離成更小、更鬆散的耦合單元,並使用 test doubles 和虛擬化單獨測試服務或組件。
常見架構誤區
同時發布多項服務。在不優先考慮可測試性和可部署性的團隊中,大多數測試都需要使用複雜且昂貴的集成環境。在許多情況下,由於複雜的相互依賴性,部署需要同時發布多項服務。這些「一次性」部署需要團隊協調安排他們的工作,包括數百個或數千個任務之間的許多交接和依賴關係。一次性部署通常需要數小時甚至數天的時間,並且需要安排較長停機時間。將更改與來自數百個甚至數千個其他開發者的更改集成。這些開發者反過來可能依賴於數十、數百或數千個互連繫統。測試是在稀缺的集成測試環境中完成的,通常需要數周時間來獲取和配置。這些環境通常不代表生產環境,降低了測試的價值和準確性。結果不僅變更前的準備時間較長(通常以數周或數月計),並且開發者的工作效率降低,部署結果不佳。在軟體交付流程中存在瓶頸。例如,瓶頸可能是許多其他團隊從手動處理角度(測試、部署等)或服務運營角度所依賴的一個團隊。在這兩個示例中,這些瓶頸會造成單點故障,並需要這些團隊或服務能夠擴縮以滿足眾多依賴團隊的需求。改進架構的方法
藉助可讓小型開發者團隊獨立實現、測試代碼並將其安全快速地部署到生產環境的架構,您可以提高開發者的工作效率並改善部署結果。面向服務的架構和微服務架構的一個關鍵特性是,它們由具有有界限上下文的鬆散耦合服務組成。基於這些原則的現代 Web 架構的一組常見模式是十二要素應用。
Randy Shoup 注意到以下情況:
「具有此類面向服務的架構的組織,如 Google 和 Amazon,具有超高的靈活性和可擴縮性。這些組織中有數以萬計的開發者,而小型團隊的工作效率仍然非常之高」。
在許多組織中,測試和部署服務非常困難。我們建議您採用迭代方法來改進企業系統的設計,而不是重新設計所有內容的架構。此方法稱為演進式架構。在此方法中,假設成功的產品和服務在其生命周期內由於對其需求發生了變化需要重新設計架構。
在此情況下,一種有用的模式是絞殺榕應用。在這種模式中,您可以通過確保按照面向服務的架構的原則完成新工作,以迭代方式將單體式架構替換為一個更加組件化的架構。您應接受新的架構可能會完全委託給要替換的系統。隨著時間的推移,在新架構中執行的功能越來越多,舊系統會被「絞殺」。
產品和服務架構在不斷演進。您可以通過多種方式來決定新模塊或服務,並且是一個迭代過程。在決定是否在服務中創建一項功能時,請考慮該服務是否具有以下特徵:
可以實現單項業務功能或能力。只需與其他服務進行很少的交互即可執行其功能。獨立於其他服務進行構建、擴縮和部署。使用輕量級通信方法(例如消息總線或 HTTP 端點)與其他服務進行交互。可以使用不同工具、程式語言、數據存儲區等實現。改用微服務或面向服務的架構還會改變整個組織的許多方面。在 Steve Yegge 的平臺吐槽中,他提供了在改用 SOA 過程中學到的一些重要的經驗教訓:
指標和監控變得更加重要,並且上報變得更加困難,因為一項服務中出現的問題可能來自許多服務調用。內部服務可能會產生拒絕服務 (DOS) 類型的問題,因此配額和消息限制在每項服務中都很重要。質量檢查和監控開始結合執行,因為監控必須全面,並且必須運用服務的業務邏輯和數據。如果存在多項服務,則服務發現機制對於系統的高效運行至關重要。如果沒有在可調試環境中運行服務的通用標準,則調試他人服務中的問題會更加困難。案例研究:Datastore
緊密耦合的架構可能會妨礙每個人的工作效率和安全進行更改的能力。相比之下,鬆散耦合的架構通過明確定義的接口來強制規定模塊相互連接的方式,從而提高工作效率和安全性。鬆散耦合的架構可讓小型高效團隊進行可以安全、獨立部署的更改。此外,由於每項服務都還有一個明確定義的 API,因此可以更輕鬆地對服務進行測試,並可以在團隊之間創建合同和服務等級協議 (SLA)。
Randy Shoup 對該架構的描述如下:
「這種類型的架構為 Google 帶來了非常出色的結果,對於 Gmail 這樣的服務,它下面還有 5 個或 6 個其他服務層,每個層均針對一個非常具體的功能。每項服務均由小型團隊提供支持,團隊負責構建服務並運行其功能,每個團隊可能會選擇不同的技術。另一個例子是數據存儲區服務,它是全球最大的 NoSQL 服務之一,但僅由大約 8 人組成的團隊支持,這主要是因為該服務是以多層基於彼此而構建的可靠服務為基礎」。
這種面向服務的架構允許小型團隊打造更小、更簡單的開發單元,每個團隊都可以獨立、快速、安全地進行部署。
衡量架構改進的方法
無論是在大型機上還是在微服務中,促成架構改進所需的做法對於提高軟體交付性能(增加部署頻率,同時縮短變更前準備時間、恢復服務時間,並降低變更失敗率)至關重要。在您的服務和產品的耦合性緊密程度降低時,您的部署頻率應該會增加。在衡量改進時,請考慮使用部署速率而不僅僅是計數,因為部署計數自然隨著服務的增加而增加。最後,您應該能夠看到發現問題並從問題恢復的時間減少,並且更改部署到生產環境的時間減少。
除了採取這些部署和服務措施之外,更獨立運營的團隊還表現在工作滿意度和團隊實驗的改進,並且往往根據需要選擇不同的技術和工具。(轉自DevOps教練)