在過去5年中,微服務架構風格(透過一系列細粒度的、松耦合的、可以獨立部署的服務來組織應用)變得越來越流行。且不論公司規模多大,單就工程團隊來說,微服務也變得越來越可行。
本文主要介紹與微服務應用開發和部署相關的內容,並輔以實際示例來引導讀者體驗從設計到部署微服務的全過程。
透過學習本文的內容,讀者將瞭解如何進行微服務應用的開發和部署、如何透過微服務來實現有效的持續交付,以及如何用Kubernetes、Docker 和Google Container Engine開發例項。
本文適合瞭解企業級應用架構和雲平臺(如AWS和GCP)的中級開發人員和架構師閱讀,也適合對微服務感興趣的讀者參考。
本文內容的目錄主要內容本文總共有13章的內容,帶領大家徹底解讀微服務實戰,因為內容過多,只能把部分知識點拿出來給大家介紹,希望大家能夠理解和喜歡!!
第1章 微服務的設計與執行;
(1)微服務既是一-種架構風格,也是一系列文化習慣的集合。它以五大核心原則為支撐,它們分別是自治性、可恢復性、透明性、自動化和一-致性。(2)微服務減少了開發衝突,實現了自治性、技術靈活性以及松耦合。(3)微服務的設計過程是非常有挑戰性的,因為它不僅需要豐富的業務領域知識,還需要開發者在團隊之間平衡優先順序。(4)服務向其他服務暴露契約。設計良好的契約是簡潔的、完整的和可預測的。(5)在長期執行的軟體系統中,複雜性是不可避免的,但是開發者可以透過-一些決策來減少衝突和風險,進而持續地在這些系統中交付價值。(6)自動化和可驗證的釋出操作能夠讓部署過程更加可靠和“沒有事故發生”,進而降低微服務的風險。(7)容器技術將執行環境中的服務之間的差異進行抽象化,簡化了對型別各異的微服務進行大規模管理的方式。(8)故障是不可避免的:對團隊來說,微服務需要是透明的、易觀測的,這樣團隊才能夠主動地管理、瞭解和真正擁有服務運維;反之亦然。(9)採用微服務的團隊需要在運維方面比較成熟,並且關注於服務的整個生命週期,而不只是關注設計和開發階段。第2章SimpleBank公司的微服務;
(1)微服務非常適合於有多維複雜性的系統,比如產品的供應範圍、全球部署和監管壓力。(2)在設計微服務時,瞭解產品業務領域是至關重要的。(3)服務互動可以是編配型的,也可以是編排型的。後者會增加系統複雜度,但是能夠降低系統中服務之間的耦合度。(4) API閘道器是一-種常 見的模式,它將微服務架構的複雜性進行了封裝和抽象,所以前端或者外部消費者不需要考慮這部分複雜度。(5 )如果開發者充分信任自己的服務能夠處理生產環境上的流量壓力,就可以說這個服務是生產就緒的。(6)如果開發者可以可靠地部署和監控某個服務,就可以對這個服務更有信心。(7)服務監控應該包括日誌聚合以及服務層次的健康檢查。(8)微服務會因硬體、通訊以及依賴項等原因而出現故障,並不是只有程式碼中的缺陷才會導致故障發生。(9)收集業務指標、日誌以及服務間的鏈路跟蹤記錄對於瞭解微服務應用當前和過去的執行表現是至關重要的。(10)隨著微服務以及支援團隊的數量的不斷增加,技術分歧以及孤立會日漸成為技術團隊的挑戰。(11)避免技術分歧和孤立需要在不同團隊間採用相似的標準和最佳實踐,不管採用何種技術基礎。第3章微服務應用的架構;
(1)單獨來講,微服務的內部和單體應用是相似的。(2)微服務應用就像一個街區:它最終的樣子不是指定好的,而是由一系列的準則和高層的概要模型來指導實現的。(3)指導微服務架構的準則會反映出組織的目標並對團隊的實踐產生影響。(4)架構規劃應該促進良性發展,而不是強行指定整個應用的方案。(5)微服務應用是由四層組成的:平臺層、服務層、邊界層和客戶端層。(6)平臺層提供了一系列的工具和基礎設施來支援開發面向生產的服務。(7)在微服務應用中,同步通訊通常是第一 選擇,並且它非常適合命令型的互動,但是也存在缺點一會增 加耦合性和不穩定性。(8)非同步通訊更加靈活,能夠適應快速的系統演化,付出的代價是複雜度增加。(9)常見的非同步通訊模式包括佇列和釋出-訂閱。( 10)邊界層就是微服務應用的一個門面,對於外部消費者來說,這是非常適合的。(11)常見的邊界層模式有API閘道器和消費者驅動的閘道器(如GraphQL)。(12)客戶端應用,比如網站和移動端應用,透過邊界層與移動後端進行互動。(13)客戶端有越來越臃腫龐大的風險,但是現在也開始出現--些將微服務原則應用於前端應用的技術。第4章新功能設計;
(1)瞭解業務問題一識別實體 和用例一劃分服務 責任,我們可以透過這一流程來劃定服務範圍。(2 )可以採用不同的方式來對服務進行劃分:按業務功能劃分、按用例劃分和按易變性劃分。讀者可以綜合運用這些方法。(3)好的劃分決策能夠讓服務滿足微服務的三大關鍵特性:只負責單-職責、 可替換和可獨立部署。(4)限界上下文通常是與服務邊界相對應的,在思考服務的未來發展時,這是一一種很有效的方法。(5)透過對易變領域的深入思考,開發者可以將那些會- -起變化的領域封裝起來,以提高應對未來變化的適應能力。(6)如果服務劃分不好,後期修正的代價是特別大的,因為到那時,開發者需要重構多個程式碼庫,由此產生的工作量會變得特別大。(7)我們也可以將技術功能封裝成一個服務 ,這麼做既能夠簡化業務能力,又可以對業務功能提供支撐,並能最大限度地提高服務的可用性。(8)如果服務邊界還不夠明確,我們寧可選擇粗粒度的服務,但是要主動在服務內部採用模組化的方案來為未來的拆分做準備。(9)服務下線是一件特別有挑戰性的工作,但是隨著微服務應用的不斷髮展,我們未來終有一天會需要這麼做。( 10)在大型組織機構中,將所有權拆分到多個團隊中是很有必要的,但是這又會引入新的問題:控制變弱、設計受限、開發速度不一致。(11)程式碼開放化、介面明確化、溝通持續化以及放寬對DRY原則的要求都可以緩解團隊之間的緊張關係。第5章微服務的事務與查詢;
(1)在跨服務的互動中實現ACID特性是很困難的,微服務需要採用不同的方式來實現一致性。(2)類似兩階段提交這樣的協調方案會引入加鎖操作,擴充套件性不好。(3)基於事件的架構可以解除各個獨立元件之間的耦合,併為微服務應用的業務邏輯和查詢的可擴充套件性打下基礎。(4)傾向於高可用,而非-一 -致性,這會使得架構的可擴充套件性更強。(5) Saga是由- -組訊息驅動的、獨立的本地事務組成的全域性操作。它們透過補償操作來回滾錯誤的狀態,以實現- -致性。(6)在構建反映現實世界環境的微服務時,預見失敗場景並做好準備是非常重要的一部分內容,操作的隔離性反而沒那麼至關重要。(7)我們通常透過組合多個API的結果來實現跨多個微服務的查詢功能。(8)高效的複合型查詢應該採用CQRS模式來實現一套獨立的讀資料模型,特別是在那些查詢模式需要採用另-一種資料儲存系統時。第6章 設計高可靠服務;
(1)在複雜的分散式系統中,故障是不可避免的一 在設計這些系統時,開發者必須考慮容錯能力。(2)每個服務的可用性都會對整個應用的可用性的產生影響。(3)對每個應用制定合適的策略來減輕故障的風險,這需要仔細考慮故障的頻次、影響以及減少這些罕見的故障事件所增加的成本。(4)大部分故障發生在4個領域:硬體、通訊、依賴項和內部。(5)正反饋導致的連鎖故障是微服務應用中一種很常見的故障形式。通常,大部分是連鎖故障由服務過載所導致的。(6)可以使用重試和超時時間的策略來減輕服務互動中出現的故障的影響。在採用重試方法時,開發者要加倍謹慎,以免加重其他服務的故障。(7)可以使用快取、候選服務和預設值等後備方案( fllback )來返回成功的結果,即使服務依賴不可用。(8)應該在服務互動中將超時時間傳播到下游服務,這樣不僅能夠確保在整個系統內超時時間是一致的,還可以少做無用功。(9)當錯誤量達到一定閾值時,服務之間的斷路器會透過快速失敗來避免連鎖故障。(10)服務可以使用限流策略來保護其免於受到突發的超過服務容量承載能力的負載請求高峰的影響。(11)每個服務應該為負載均衡器和監控系統開放健康檢查介面供其使用。( 12)可以透過壓力測試和混沌測試來有效地驗證系統可恢復性。(13)可以採用一些標準一 不管是透過框架還是代理一 來幫助工程師快速(“flall into thepit of sccess”"“) 開發出預設具有容錯性的服務。第7章 構建可複用的微服務框架;
(1)微服務底座能夠加快新服務的啟動速度,擴大試驗領域和降低風險。(2)使用服務底座能夠讓開發者將與某些基礎設施相關的程式碼實現抽取出來。(3)服務發現、可觀測性以及不同的通訊協議都是服務底座所關注的內容,服務底座需要提供這些功能。(4)如果有適合的工具存在,我們可以為下單出售股票這樣的複雜功能快速開發出原型。(5)雖然微服務架構經常和使用任意語言開發系統的可能性聯絡起來,但是在生產環境中,這些系統需要保證並提供機制來讓執行和維護都是可管理的。(6)微服務底座能夠實現上述這些保證,同時能夠讓開發者快速啟動和開發以驗證想法的正確性,如果驗證透過,就可以部署到生產環境。第8章微服務部署;
(1)部署新的應用和變更必須標準化和簡單明確,以免在微服務開發過程中出現摩擦。(2)微服務可以執行在任何地方,但是理想的部署平臺需要支援一系列功能, 包括安全、配置管理、服務發現以及冗餘。(3)開發者將一個典型服務部署為一組完全相同的例項,並與一-個負載 均衡器連線。(4)例項組、負載均衡器以及健康檢查能夠讓所部署的服務實現自愈和自動擴容。(5)服務工件必須是不可變的和可預測的,以將風險控制到最小,降低認知難度,簡化部署抽象。(6)開發者可以將服務打包為特定於語言的包、作業系統軟體包、虛擬機器模板或者容器映象。(7)新增/刪除微服務的單個例項是基本的初級操作,可供開發者組合成更高級別的部署。(8)開發者可以使用金絲雀部署或藍綠部署來降低意外缺陷對可用性的影響。第9章 基於容器和排程器的部署;
(1)將微服務打包為不可變的、可執行的工件能夠讓開發者透過基本操作(增加或移除容器)來對部署過程進行編排。(2)為了方便服務開發和部署,排程器和容器會將底層的機器管理概念抽離出去。(3)排程器的工作是設法將應用的資源需求與叢集機器的資源使用情況匹配起來,同時對執行中的服務進行健康檢查以確保它們正確執行。(4) Kubernetes具備了微服務部署平臺的理想特性,包括密碼憑據管理、服務發現和水平擴容。(5) Kubernetes使用者定義了所期望的叢集服務狀態(或者規格),而Kubermetes會不停地執行“觀測-比較執行”這-迴圈操作來計算如何達到所期望的狀態。(6) Kubernetes的邏輯應用單元是pod:一個容器或者在一起執行的多個容器。(7)複製集管理pod組的生命週期。如果現有的pod出現故障,複製集會啟動新的pod。(8) Kubernetes中的部署物件被設計用來透過對複製集中的pod執行滾動更新來保持服務可用性的。(9)開發者可以使用服務物件來對底層的pod進行分組並供叢集內外的其他應用訪問。第10章構建微服務交付流水線;
(1)微服務部署過程應該滿足兩大目標:節奏安全和- -致性。(2)部署新服務所花費的時間通常是微服務應用中的一大阻礙。(3)對微服務而言,持續交付是理想的部署實踐方式,它透過快速交付小版本的經過驗證的變更集來降低風險。(4)良好的持續交付流水線能夠確保部署過程的可見性、部署結果的正確性,並能夠向工程師團隊反饋豐富的資訊。(5) Jenkins 是非常流行的自動化構建工具,它使用指令碼語言將不同的工具聯絡到一.起並組合成交付流水線。(6)預釋出環境是非常有價值的,但是當面對大量的獨立變更時,維護好預釋出環境也面臨著巨大的挑戰。(7)讀者可以在各個服務上覆用宣告式流水線步驟;積極推動標準化能夠提高不同團隊間部署過程的可預測性。(8)為了對釋出和回滾提供細粒度的控制,讀者應該將部署這一技術活動與功能釋出的業務活動分開管理。第11章構建監控系統;
(1)可靠的微服務監控系統包括度量指標、鏈路追蹤和日誌。(2)從微服務中收集豐富的資料有助於開發者發現故障.調查問題,並理解整個應用的表現。(3)在收集度量指標時,開發者應該重點關注四大黃金標誌:時延、錯誤量、通訊量(吞吐率)和飽和度。(4) Prometheus和StatsD是兩種常見的和具體語言無關的從微服務中收集度量指標的工具。(5)開發者可以使用Grafana將度量指標資料以圖表的形式展示出來,建立人類可讀的儀表盤和觸發告警。(6)如果基於度量指標的告警體現的是系統不正常的症狀而非原因的話,那麼這些告警更具有永續性和可維護性。(7)定義良好的告警應該有明確的優先順序,能夠逐層升級到對應的人員,具有可操作性並且包含簡潔而有價值的資訊。(8)從多個服務中收集和聚合的資料能夠讓開發者將完全不同的度量指標關聯起來並進行比較,從而對系統有進一-步全面的瞭解。第12章使用日誌和鏈路追蹤瞭解系統行為;
(1)讀者可以使用Elasticsearch、 Kibana 和Fluentd 一起搭建一套日誌基礎設施,並使用Jaeger搭建一套分散式鏈路追蹤系統。(2)日誌基礎設施可以生成、轉發和儲存索引的日誌資料以方便檢索和關聯不同請求。(3)分散式鏈路追蹤能夠讓開發者跟蹤不同微服務之間的請求的執行過程。(4)除了度量指標集合,鏈路追蹤能夠讓開發者更好地瞭解系統的執行方式,發現潛在問題並隨時對系統進行審查。第13章微服務團隊建設;
(1)構建優秀的軟體不僅和選擇什麼方案實現有關,還與有效的溝通、協調和協作有關。(2)應用架構和團隊結構有著共生的關係。可以使用後者來改變前者。(3)如果想讓團隊變得高效,就應該將他們組織起來,最大化地實現自治、所有權以及端到端職責。(4)在微服務交付方面,跨職能團隊比傳統的職能團隊速度更快、更有效率。(5)較大型的工程組織應該建立一套具有 基礎設施、平臺和產品團隊的分層模型。較低層次的團隊為較高層次的團隊提供服務以保證其能夠更有效地工作。(6)社群實踐(比如協會和分會),可以分享職能知識。(7)微服務應用很難全部裝進人的大腦,這給全域性決策和值班的工程師帶來了挑戰。(8)架構師應該指導和影響應用的演進,而不是支配應用的方向和結果。(9)內部開源模型能改善跨團隊協作,削弱佔有慾,降低巴士因子的風險。( 10 )設計評審能提高微服務的質量、可訪問性和一致性。(11)微服務文件應該包括概述、 操作手冊、元資料和服務契約。
最新評論