Martin Fowler微服務論文


什么是微服務

簡而言之,微服務架構風格[1]這種開發方法,是以開發一組小型服務的方式來開發一個獨立的應用系統的。其中每個小型服務都運行在自己的進程中,並經常采用HTTP資源API這樣輕量的機制來相互通信。這些服務圍繞業務功能進行構建,並能通過全自動的部署機制來進行獨立部署。這些微服務可以使用不同的語言來編寫,並且可以使用不同的數據存儲技術。對這些微服務我們僅做最低限度的集中管理。

image-20201107155359719

微服務的九大特性

特性一 組件化與多服務

一個組件就是一個可以獨立更換和升級的軟件單元。

微服務架構也會使用軟件庫,但其將自身軟件進行組件化的主要方法是將軟件分解為諸多服務。我們將軟件庫(libraries)定義為這樣的組件,即它能被鏈接到一段程序,且能通過內存中的函數來進行調用。然而,服務(services)是進程外的組件,它們通過諸如web service請求或遠程過程調用這樣的機制來進行通信(這不同於許多面向對象的程序中的service object概念

特性二:圍繞“業務功能”組織團隊

任何設計(廣義上的)系統的組織,都會產生這樣一個設計,即該設計的結構與該組織的溝通結構相一致。

——梅爾文•康威(Melvyn Conway), 1967年

微服務使用不同的方法來分解系統,即根據業務功能(business capability)來將系統分解為若干服務。這些服務針對該業務領域提供多層次廣泛的軟件實現,包括用戶界面、持久性存儲以及任何對外的協作性操作。因此,團隊是跨職能的,它擁有軟件開發所需的全方位的技能:用戶體驗、數據庫和項目管理。

特性三:“做產品”而不是“做項目”

通常認為這一點源自亞馬遜的“誰構建,誰運行”的理念,即一個開發團隊對一個在生產環境下運行的軟件負全責。這會使開發人員每天都會關注軟件是如何在生產環境下運行的,並且增進他們與用戶的聯系,因為他們必須承擔某些支持工作。

這樣的“產品”理念,是與業務功能的聯動綁定在一起的。它不會將軟件看作是一個待完成的功能集合,而是認為存在這樣一個持續的關系,即軟件如何能助其客戶來持續增進業務功能。

特性四:“智能端點”與“傻瓜管道”

微服務社區主張采用另一種做法:智能端點(smart endpoints)和傻瓜管道(dumb pipes)。使用微服務所構建的各個應用的目標,都是盡可能地實現“高內聚和低耦合”——他們擁有自己的領域邏輯,並且更多地是像經典Unix的“過濾器”(filter)那樣來工作——即接收一個請求,酌情對其應用業務邏輯,並產生一個響應。這些應用通過使用一些簡單的REST風格的協議來進行編制,而不去使用諸如下面這些復雜的協議,即"WS-編制"(WS-Choreography)、BPEL或通過位於中心的工具來進行編排(orchestration)。

特性五:“去中心化”地治理技術

相比選用業界一般常用的技術,構建微服務的那些團隊更喜歡采用不同的方法。與其選用一組寫在紙上已經定義好的標准,他們更喜歡編寫一些有用的工具,來讓其他開發者能夠使用,以便解決那些和他們所面臨的問題相似的問題。這些工具通常源自他們的微服務實施過程,並且被分享到更大規模的組織中,這種分享有時會使用內部開源的模式來進行。現在,git和github已經成為事實上的首選版本控制系統。在企業內部,開源的做法正在變得越來越普遍。

特性六:“去中心化”地管理數據

微服務更喜歡讓每一個服務來管理其自有數據庫。其實現可以采用相同數據庫技術的不同數據庫實例,也可以采用完全不同的數據庫系統。這種方法被稱作“多語種持久化”(Polyglot Persistence)

特性七:“基礎設施”自動化

為了盡可能地獲得對正在運行的軟件的信心,需要運行大量的自動化測試。讓可工作的軟件達到“晉級”(Promotion)狀態從而“推上”流水線,就意味着可以在每一個新的環境中,對軟件進行自動化部署

我們所看到的各個團隊在廣泛使用基礎設施自動化實踐的另一個領域,是在生產環境中管理各個微服務。與前面我們對比單塊系統和微服務所說的正相反,只要部署工作很無聊,那么在這一點上單塊系統和微服務就沒什么區別。然而,兩者在運維領域的情況卻截然不同。

特性八:“容錯”設計

因為各個服務可以在任何時候發生故障,所以下面兩件事就變得很重要,即能夠快速地檢測出故障,而且在可能的情況下能夠自動恢復服務。各個微服務的應用都將大量的精力放到了應用程序的實時監控上,來檢查“架構元素指標”(例如數據庫每秒收到多少請求)和“業務相關指標”(例如系統每分鍾收到多少訂單)。當系統某個地方出現問題,語義監控系統能提供一個預警,來觸發開發團隊進行后續的跟進和調查工作。

這對於一個微服務架構是尤其重要的,因為微服務對於服務編制(choreography)和事件協作(http://martinfowler.com/eaaDev/EventCollaboration.html)的偏好,會導致“突發行為”。盡管許多權威人士對於偶發事件的價值持積極態度,但事實上,“突發行為”有時是一件壞事。在能夠快速發現有壞處的“突發行為”並進行修復的方面,監控是至關重要的。

那些微服務團隊希望在每一個單獨的服務中,都能看到先進的監控和日志記錄裝置。例如顯示“運行/宕機”狀態的儀表盤,和各種運維和業務相關的指標。另外我們經常在工作中會碰到這樣一些細節,即斷路器的狀態、當前的吞吐率和延遲,以及其他一些例子。

特性九:“演進式”設計

一個組件的關鍵屬性,是具有獨立更換和升級的特點——這意味着,需要尋找這些點,即想象着能否在其中一個點上重寫該組件,而無須影響該組件的其他合作組件。事實上,許多做微服務的團隊會更進一步,他們明確地預期許多服務將來會報廢,而不是守着這些服務做長期演進。

這種強調可更換性的特點,是模塊化設計一般性原則的一個特例,通過“變化模式”(pattern of change)來驅動進行模塊化的實現。大家都願意將那些能在同時發生變化的東西,放到同一個模塊中。系統中那些很少發生變化的部分,應該被放到不同的服務中,以區別於那些當前正在經歷大量變動(churn)的部分。如果發現需要同時反復變更兩個服務時,這就是它們兩個需要被合並的一個信號。

微服務的未來

有人覺得微服務或許很難成熟起來,這當然是有原因的。在組件化上所做的任何工作的成功與否,取決於軟件與組件的匹配程度。准確地搞清楚某個組件的邊界的位置應該出現在哪里,是一件困難的工作。演進式設計承認難以對邊界進行正確定位,所以它將工作的重點放到了易於對邊界進行重構之上。但是當各個組件成為各個進行遠程通信的服務后,比起在單一進程內進行各個軟件庫之間的調用,此時的重構就變得更加困難。跨越服務邊界的代碼移動就變得困難起來。接口的任何變化,都需要在其各個參與者之間進行協調。向后兼容的層次也需要被添加進來。測試也會變得更加復雜。

另一個問題是,如果這些組件不能干凈利落地組合成一個系統,那么所做的一切工作,僅僅是將組件內的復雜性轉移到組件之間的連接之上。這樣做的后果,不僅僅是將復雜性搬了家,它還將復雜性轉移到那些不再明確且難以控制的邊界之上。當在觀察一個小型且簡單的組件內部時,人們很容易覺得事情已經變得更好了,然而他們卻忽視了服務之間雜亂的連接。

最后,還有一個團隊技能的因素。新技術往往會被技術更加過硬的團隊所采用。對於技術更加過硬的團隊而更有效的一項技術,不一定適用於一個技術略遜一籌的團隊。我們已經看到大量這樣的案例,那些技術略遜一籌的團隊構建出了雜亂的單塊架構。當這種雜亂發生到微服務身上時,會出現什么情況?這需要花時間來觀察。一個糟糕的團隊,總會構建一個糟糕的系統——在這種情況下,很難講微服務究竟是減少了雜亂,還是讓事情變得更糟。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM