\\\本文要點
\\
- 當前微服務架構依然是最流行的分布式系統架構風格。Kubernetes和云原生運動已大規模地重新定義了應用設計和開發中的一些方面。\\t
- 在云原生平臺上,服務僅具備可觀測性是不夠的。更基本的先決條件是使用檢查健康、響應信號、聲明資源消耗等手段實現微服務的自動化。\\t
- 在后Kubernetes時代,服務網格(Service Mesh)技術已完全取代了使用軟件庫實現網絡運維(例如Hystrix斷路器)的方式。\\t
- 當前,設計應針對“可恢復性”。為此,微服務需要實現多個維度上的冪等性。\\t
- 現代開發人員必須做到不僅要精通編程語言去實現業務功能,而且同樣也要精通云原生技術去滿足一些非功能性基礎架構層上的需求。\
微服務的關注熱度起源于一大堆極端的想法,涉及組織的結構、團隊的規模、服務的規模、重寫和拋出服務而不是修復、避免單元測試等。依我的經驗看,其中大部分想法已被證明是錯誤的、不實用的,或者至少在一般情況下是不適用的。當前能殘存下來的微服務原則和實踐,大部分是非常通用和寬松定義的。雖然它們適合未來許多年內的發展,但在實踐中并沒有多大的意義。
\\早在Kubernetes橫空出世的幾年前,微服務理念就得到了采用,目前,它仍然是一種最流行的分布式系統架構風格。Kubernetes和云原生運動已大規模地重定義了應用設計和開發的一些方面。在本文中,我試圖提出一些原始的微服務理念。我將指出,這些理念在后Kubernetes時代已不再像以前那樣強大。
\\服務不僅應可觀測,而且應是自動化的
\\可觀測性(Observability) 是微服務自一開始就提出的一個基本原則。可觀測性雖然適用于一般的分布式系統,但是當前,尤其是在Kubernetes上,可觀測性的主要涉及平臺層的開箱即可用,例如進程運行狀況檢查、CPU和內存消耗等。應用能以JSON格式登錄控制臺,這就是可觀測性的最低要求。此外,平臺應可以在無需過多服務層開發的情況下,實現跟蹤資源的消耗、開展請求追蹤、收集全部類型的指標、計算錯誤率等。
\\在云原生平臺上,服務僅具備可觀測性是不夠的。更基本的先決條件是使用檢查健康、響應信號、聲明資源消耗等手段實現微服務的自動化。任何應用都可以置于容器中并運行。但是要創建一個可通過云原生平臺自動化和協調編排容器的應用,則需要遵循一定的規則。遵循這些原則和模式,可確保所生成的容器作為云本地成員在大多數容器編排引擎中表現為優秀,并支持對容器進行自動化的調度、擴展和監視。
\\我們希望平臺不僅可觀測服務中發生的情況,而且希望平臺能檢測到異常,并按照聲明情況做出協調。糾正措施可以是通過停止引導流量到服務實例、重新啟動、向上/向下擴展,也可以是將服務遷移到另一臺健康的主機、重試失敗的請求或是其它一些操作。如果服務實現了自動化,那么所有這些糾正措施都會自動做出,我們只需要描述所需的狀態,而不是去觀測并做出響應。服務應該是可觀測的,但也應在無需人工干預的情況下由平臺實現問題整改。
\\具備正確職責的智能平臺和智能設備
\\在從SOA轉向微服務的過程中,在服務交互上發生的另一個根本轉變就是“智能端點啞管道”(smart endpoints and dumb pipes)這一理念。在微服務領域,服務不依賴于所具有的集中式智能路由層,而是依賴于具有某些平臺級功能的智能端點。服務的實現是通過在每個微服務中嵌入傳統ESB的部分功能,并轉為使用不具有業務邏輯元素的一些輕量級協議。
\\這仍然是一種慣常采用的方法,即在不可靠的網絡層(使用諸如Hystrix之類的庫)實現服務交互,但在當前的后Kubernetes時代,服務交互已完全被服務網格(Sevice Mesh技術取代。服務網格吸引人之處在于,它甚至要比傳統的ESB更智能。網格可以執行動態路由、服務發現、基于延遲的負載平衡、響應類型、指標和分布式跟蹤、重試、超時,以及我們所能想到的所有特性。
\\與ESB的不同,服務網格只有一個集中路由層,每個微服務通常都具有自己的路由器,即一個使用額外中央管理層執行代理邏輯的“跨斗模式容器”(Sidecar Container)。更重要的是,管道(即平臺和服務網格)中并不維持任何業務邏輯。管道完全聚焦于基礎架構問題,而讓服務聚焦于業務邏輯。下圖表示了為適應云環境的動態和不可靠特性,ESB和微服務在認知上的演變情況。
\\圖 從SOA到MSA和CNA
\\如果查看服務的其他一些方面,我們就會注意到云原生不僅影響了端點和服務交互。Kubernetes平臺(及其所有附加技術)還負責資源的管理、調度、部署、配置管理、擴展和服務交互等。與其再次稱之為“智能代理啞管道”,我認為更好的描述應是一種具備正確職責的智能平臺和智能服務。它不僅是與端點相關,而且也是一個完整的平臺,實現主要聚焦于業務功能的服務在所有基礎架構上的自動化。
\\設計不應針對“故障”,而應針對“恢復”
\\毫無疑問,要在基礎架構和網絡本身并非可靠的云原生環境中運行微服務,我們必須針對故障做出設計。但是越來越多的故障是由平臺檢測并處理的,而人們對如何從微服務中捕獲故障的考慮較少。相反,我們應通過考慮從多個維度實現冪等性,設計我們的恢復服務。
\\容器技術、容器編排和服務網格(serive mesh)可以檢測許多故障,并從中進行恢復。例如無限循環(分配CPU份額)、內存泄漏和OOM(運行狀況檢查)、磁盤占用(配額問題)、Fork炸彈(進程限制),批量處理和進程隔離(限制內存份額)、延遲和基于響應的服務發現、重試、超時、自動擴展等。同樣,在過渡到無服務器模型后,服務必須在幾毫秒內處理一個請求。看上去對垃圾回收、線程池、資源泄漏等問題的關注,越來越成為一些毫不相關的問題……
\\使用平臺處理所有諸如此類的問題,會將服務視為一個密封黑盒子。該黑盒子應支持多次啟動和停止(支持服務重新啟動)、服務按比例的放大和縮小(通過將服務成為無狀態的以支持安全擴展)、假定許多傳入請求最終會超時(使端點具有冪等性)、假定許多傳出請求將暫時失敗并且平臺將會做出重試(確保我們使用了冪等服務)。
\\為實現自動化在云原生環境中適用自動化,服務必須滿足下列條件:
\\- 對重啟的冪等(服務支持多次被殺掉并啟動)。\\t
- 對向上/向下擴展冪等(服務可實現多個實例的自動擴展)。\\t
- 對服務生成者冪等(其它服務可重試調用)。\\t
- 對服務消費者冪等(服務或服務網格可以重試傳出請求)。\
如果服務在一次或是多次執行上述行為中總是表現出同一方式,那么平臺就可以在無需人工干預的情況下從故障中恢復服務。
\\最后請記住,平臺提供的所有恢復只是一些本地優化。正如Christian Posta所指出的,分布式系統中應用的安全性和正確性仍然是應用的責任。對于設計一個整體穩定的系統,業務流程整體范圍中的思維模式(可能跨越多個服務)十分重要的。
\\雙重開發職責
\\越來越多的微服務原則已被Kubernetes及一些補充項目實施和提供。因此,現代開發人員必須做到不僅要精通編程語言去實現業務功能,而且同樣也要精通云原生技術去完全滿足一些非功能性基礎架構層上的需求。
\\業務需求和基礎架構(操作上的需求、跨功能的需求,或是一些系統質量屬性)之間的界限通常是模糊不清的,我們不可能只采取其中的某個方面,而期望其他人去實現另一個方面。例如,如果要在服務網格層實現重試邏輯,那么必須使服務中的業務邏輯或數據庫層所使用的服務具有冪等性。如果在服務網格層使用超時,那么必須在服務中實現服務使用者超時的同步。如果必須要實現服務的定期執行,那么必須配置Kubernetes作業去按時間執行。
\\展望未來,一些服務功能應作為業務邏輯實現在服務中,而其它一些服務功能則應作為平臺功能提供。雖然使用正確的工具去完成正確的任務是一種很好的責任分離,但新技術不斷出現極大地增加了整體的復雜性。要在業務邏輯方面實現簡單的服務,我們需要很好地理解分布式技術堆棧,因為開發職責是分散在各個層上的。
\\事實證明,Kubernetes支持向上擴展到數千個節點,數萬個Pod和每秒數百萬事務。但它是否同樣支持向下擴展?對我來說,我并不清楚應用的規模、復雜性或關鍵性的閾值應該是多少,才能證明我們引入復雜的“云原生”是正確的。
\\結論
\\看到微服務運動為采用Docker和Kubernetes等容器技術提供了如此巨大的動力,這是非常有意思的。雖然在一開始是微服務實踐推動了這些技術的發展,但現在是Kubernetes重新定義了微服務架構的原則和實踐。
\\從最近的一些實例看,我們將很快采納功能模型作為有效的微服務原語,而不是將微服務視為納米(nanoservice)服務的反模式。我們并沒有充分質疑云原生技術對于中小型案例的實用性和適用性,而是出于興奮有些隨意地投身到這個領域中。
\\Kubernetes從ESB和微服務中汲取了大量經驗,因此它將會成為最終的分布式系統平臺。它是一種用于定義建筑風格的技術,而不是反之。究竟是好是壞,只有時間才能證明。
\\作者簡介
\\Bilgin Ibryam (@bibryam) 是Red Hat的首席架構師、提交者和ASF成員。他也是一名開源布道師、博客作者,《Camel設計模式》(Camel Design Patterns)和《Kubernetes模式》(Kubernetes Patterns)等書的作者在他的日常工作中,Bilgin 喜歡指導、編碼和領導開發人員成功地構建云解決方案。他目前的工作重點是應用程序集成、分布式系統、消息傳遞、微服務、DevOps 和云原生的挑戰。可通過Twitter、Linkedin和個人博客聯系Bilgin。
查看英文原文: Microservices in a Post-Kubernetes Era