微服務是什么?看這一篇就夠了,為微服務正本溯源

微服務這個詞已經在軟件行業變的非常熱門,不了解微服務已經不好意思說自己是IT行業的從業人員,筆者學習和踐行微服務也有一段時間,看了很多人的文章和參與了很多討論,每個人的理解和認識都存在差異,最近一次在機場等待的時機重讀了Martin Fowler(微服務之父,他1999年的著作《重構》在編碼界也是非?;鸨?,影響了很多從業者)的文章,收貨滿滿,再結合最近幾年的實踐經驗,對微服務的認識有了新的提高,對微服務的理解也更加深入。

正值新型冠狀病毒肆虐,國務院延長了春節假期,可以抽時間總結分享出來,給需要的朋友。有條件的同學建議閱讀https://www.martinfowler.com/articles/microservices.html的英文原文,這里是原汁原味的微服務理念介紹和經驗分享,相信讀者更能獲益。

1.微服務的定義

? ? ? ?在開始討論之前,首先明確微服務是一種架構風格,一種開發方法。用來開發一個軟件套件中的單個應用的方法;這種方法具有共同的特點,即——這單個的應用運行在獨立的進程內,和其他應用采用輕量級的通信方式進行通信(通常是HTTP),這些單個應用程序圍繞業務功能構建,獨立的開發和完全自動化的部署;這些應用之間有最少限度的集中管理,可以采用不同的語言開發,不同的存儲技術。

? ? ? 為了更好的理解微服務架構,先認識一下微服務流行之前的架構,這種架構我們稱之為單體架構風格Monolithic,這種架構構建的應用程序整體作為一個單元,通常包含三部分即客戶端界面程序、服務端應用程序和數據庫??蛻舳擞脩艚缑姘琀TML,CSS,Javascript等運行在瀏覽器的程序;數據庫包含數據庫的表,視圖和存儲過程等用以存儲數據;服務端應用程序包含處理HTTP請求,處理業務邏輯和數據訪問等,這個服務端的應用程序就是個單體應用,系統的任何改變都將牽涉到重新構建和部署服務端的一個新版本。

? ? ? ?這種單體應用程序是最自然的構建系統的方式,所有請求的處理都到單體應用程序的進程內,采用應用程序開發語言的基本特性把它拆分成不同的包、類和函數中從而實現模塊化,可以在開發者的便攜機上開發和測試單體應用??梢圆捎貌渴鹆魉€把測試后的應用程序部署到生產環境中,可以增加更多負載均衡器后面的實例數量來水平的擴展服務能力。

? ? ? ?單體應用程序可以做的很好,但人們也越來越發現問題,尤其是把應用程序部署到云上以后。變更被捆綁在一起,單體應用程序中一個小的改變都需要整個程序重新部署,時間長了保持模塊化的架構也會比較困難,本應影響一個模塊的變更也很難做到僅影響單個模塊。單個模塊的伸縮需要整個程序來伸縮,這也導致需要更多的資源。這些問題就導致了人們自然而然地想到了微服務架構,把程序構建成一系列服務,每個服務可以獨立部署和伸縮,每個服務也定義了清晰的邊界,不同的服務可以采用不同的語言編寫,不同的團隊來維護。

? ? ? ?下圖來之martin fowler的官方網站,不同顏色和形狀的色塊代表了不同的功能,單體架構把所有的功能放在一個程序中,微服務將每個功能放入一個一個微服務中,單體架構需要整個程序部署多份以達到伸縮的目的,而單體應用可以根據功能的使用情況再伸縮。

? ? ? ?正是單體架構的這些問題,才使得微服務風格的架構得以發展,微服務除了服務是可獨立部署、可獨立擴展的之外,每個服務都提供一個固定的模塊邊界。甚至允許不同的服務用不同的的語言開發,由不同的團隊管理。下面文章探討一下微服務所具有的共同特征。

2.微服務架構的特征

? ? ? ?微服務之父也無法給出微服務架構風格的一個正式定義,但他嘗試去描述該架構的一些共性。就這些共性來說,并非所有的微服務都具有這些共性,但我們期望大多數微服務都具備大多數特性。

2.1 通過服務的方式組件化

? ? ? ?在軟件開發行業,長期以來都渴望通過插拔、物理世界堆積木的方式實現組件化,最近這幾十年各種語言通過庫的方式已經有很大的進步,一些語言也一定程度地實現了可插拔的模塊化庫。在討論組件化的時候,不可避免的回到一個問題,什么是組件化,它的定義是什么?我們對組件化的定義是可以獨立替換和升級的軟件包

? ? ? 微服務架構也會使用到現代編程語言提供的各種類庫,但微服務實現組件化的方式是把業務拆分成不同的服務來實現的。我們把庫定義為鏈接到程序并使用內存函數調用的組件,而服務是一種進程外的組件,它通過WEB服務請求或RPC(遠程過程調用)機制來通信。

? ? ? 我們使用微服務做為組件化的原因是微服務可以獨立的部署,如果你的應用程序在一個進程內包含了多個庫作為組件,這些組件中的任何一個變化都需要整個應用程序重新部署。如果是以微服務的方式實現組件化,那么僅對實現變化的這些微服務重新部署就可以了,不需要整個應用重新部署。當然這也不是絕對的,一些變更將會導致服務接口變化,這樣就導致多個服務發生變化,但一個好的微服務架構的目的是通過高內聚和按接口契約演進機制來最小化變更??梢娢⒎蘸蛶斓暮艽笠粋€區別就是是否可以單獨部署。

? ? ?用微服務來實現組件化的一個另一個好處是,微服務之間有清晰的服務接口定義;大多數語言沒有沒有提供定義發布接口的能力,只能通過文檔和原則來約定,這就導致調用方很容易浸入到被調用的內部或者具體實現上去,從而造成了過度耦合(例如JAVA的JAR包,我們提倡面向接口編程,但調用方也可以直接構造實現類);微服務的接口定義方式很好的解決了這一問題,調用方只能通過遠程調用的方式訪問服務提供者,不可能侵入到被調用方的內部。 微服務的這種調用方式也有副作用,遠程的調用比進程內通信代價要高很多,因此微服務的調用方式接口粒度要比進程內調用粒度粗,也即一個請求盡可能多的獲取到所需的信息,而不是像進程內調用那樣,需要的時候獲取一小部分信息。

2.2 圍繞業務能力劃分微服務

? ? ? ? 當想要把大型應用程序拆分開時,通常聚焦在技術層面,導致劃分出UI團隊、服務側團隊、數據庫團隊的劃分。當團隊按這些技術線路劃分時,即使是簡單的更改也會導致跨團隊的協調。按照這個劃分,有新需求UI團隊會把邏輯放到UI層,服務器團隊會放到服務器層。這就導致邏輯無處不在,這是康威法則在起作用的一個例子。

? ? ? ?有什么樣的組織結構,就會有什么樣的軟件架構---?Melvyn Conway, 1967

? ? ? ?而微服務的方式劃分是不同的,圍繞業務能力劃分成不同的微服務,一個組織部門內部包含1到多個微服務,這些微服務里面包含了全面的用來實現這些微服務技術棧的人員,包含UI、服務器和數據庫存儲人員。這樣的一個團隊是跨技術棧團隊,這個團隊的成員能完成微服務的前后臺開發、數據庫開發及項目管理。

? ? ? ?如下圖所示,左邊的圖是微服務團隊,團隊里面包含了微服務所需的技術人才,有UI、服務器和數據庫等,而圍繞技術能力劃分的團隊,將團隊劃分為UI團隊、服務器團隊和數據庫團隊。

? ? ? ?這里提到的微服務團隊,很自然的問題是微服務團隊應該由多大,這里實際上并沒有一個清晰的定義,但根據業界實踐,亞馬遜建議最大不超過2個披薩,也即1個團隊2個披薩能夠喂飽,也意味著這個團隊大小不超過12個人,也有的團隊6個微服務用6個人來維護,也即1個人1個微服務,這樣的粒度無疑太細了,我們不建議太細,但再大也不建議超過12個人。

2.3 做產品而不是做項目

? ? ? 產品和項目的最大區別在于項目是一次性的,目標是交付軟件,完成后的軟件被交接給維護組織,然后它的開發團隊就去干別的事情了,或者說壓根解散了,而產品是長期演進的,是不斷迭代演化的。微服務更傾向于避免項目的模式,而是以產品的模式來運作,一個團隊負責產品的整個生命周期。

? ? ? 亞馬遜的理念?“you build, you run it”?,即誰開發誰維護,開發團隊負責軟件的整個產品周期。這使開發者經常接觸他們的軟件在生產環境如何工作,并增加與他們用戶的聯系,因為他們必須承擔至少部分的支持工作。

? ? ? 這樣的“產品”理念,是與業務功能的聯動綁定在一起的。它不會將軟件看作是一個待開發的功能集合,而是認為這是一個持續迭代的、發展和演進的產品,即軟件如何能助其客戶來持續增進業務功能。

2.4?智能端點和啞管道

? ? ? ?在傳統的SOA架構下,在不同的服務之間通信時,采用的方法是在其通信機制上增加了很多智能化,增加了不少業務邏輯處理。一個典型的例子就是ESB(Enterprise? Service Bus), ESB 往往包含很多高級的功能,比如消息路由、編排、消息轉化、和業務規則處理。

? ? ? 而微服務的則往往采用另一種替代方法,智能的端點和啞管道,也即微服務在通信管道上不處理業務邏輯,僅作為通信方式存在,業務邏輯在通信雙方的微服務上處理。構建成微服務的目的是要做到高內聚和低耦合,每個微服務擁有自己的領域邏輯,而且很像是UNIX的過濾器那樣工作,接受一個輸入請求,對其應用業務邏輯,并產生一個響應。這些微服務之間通信,更傾向于采用簡單的RESTFUL風格協議而不是復雜的協議(如基于SOAP的web service,或者BPEL)。

? ? ?微服務和十幾年前的SOA架構看起來非常相似,很多理念也很類似,但本質上有很大差異,SOA架構通常都有一個龐大、復雜的ESB總線,各個單體應用之間通過ESB來交換數據,ESB也承擔了很多業務邏輯轉換和處理的工作,但在微服務概念里面,沒有ESB,有的只是輕量級的消息通信機制。

? ? 微服務建議采用2種方式來通信,一個是HTTP請求-響應式的API,第二個者輕量級的消息中間件通信。第一種HTTP方式,正是構建萬維網使用的協議,通常使用的資源很容易被緩存起來。第二種方式是通過輕量級消息中間件來通信,比較常見的是RabbitMQ, ZeroMQ, Kafka等,這類消息中間件僅提供一個可靠的異步通信機制,不提供額外的功能,這也就是啞管道,而智能部分在端點側,也就是通信雙方微服務。

? ? ? ?在單體應用中,組件之間通過內存中進程內的方法調用或者函數調用完成,把單體應用拆分為微服務架構的最大問題就是通信方式的變化。簡單的把進程內的方法調用轉換為RPC調用是十分錯誤的,因為在進程內調用開銷非常小,獲取的信息的粒度非常小,可以非常頻繁的通信,但轉換為微服務之間的調用之后,就要切回為更大粒度的通信了。 例如:單體應用里面訂單信息和顧客信息在一個應用內,訂單需要姓名,則調用訂單模塊的getName接口獲取,需要地址信息再調用getAddressInfo接口獲取,但拆分成微服務之后,就不能這么頻繁的調用,顧客信息應該提供一個粗粒度的接口給訂單管理,一次性提供顧客相關的姓名、地址信息。

2.5?去中心化治理

? ? ? ?中心化治理帶來的結果是趨向于標準化到單一的技術、工具、方法和流程,經驗顯示這種方法限制太多了,不是所有的問題都是釘子,也不是所有的解決辦法都是錘子,多樣性的世界和多樣性的業務更趨向于不同的事情采用不同的工具,雖然單體應用也可以這么做,但這在單體應用中并不常見。

? ? ? ?在將單體應用拆分成微服務時,可以根據業務特點和需要選擇合適的技術,報表頁面就用個簡單的Node.js,當然可以,實時處理的需要用C++,當然也可以,想采用特定類型的數據庫來提高讀取性能,當然也沒有問題。這里僅僅是說可以這么做,但不代表應該這么做。拆分成微服務后,不限制每個微服務采用的技術,但作為整個團隊的一部分,技術還是應該盡可能的統一。

? ? ? ?采用微服務的方式不是說就沒有標準要遵守了,微服務的標準不是定義一堆預先選定的技術,而是微服務開發風格。大家共同的標準就是遵從微服務風格。每個微服務團隊更傾向于采用對開發有利的工具,這些工具可以給其他團隊用,當在解決問題時,也是優先采用已有的工具,可能來自于公司內部的開源,也可能來自于互聯網開源。Netflix就是采用此哲學的很好的例子, 他們共享有用的,完整測試的代碼,把這些代碼作為庫共享出來,鼓勵其他開發者用這些庫來解決問題,當然也鼓勵開發者采用其他的方式來更好的解決。

? ? ?對微服務社區而言,大家不愿意消耗太多的時間去做服務契約的管理,這不是說不重視服務契約,相反,非常重視服務的契約,有不同的方法來探索和嘗試管理服務契約。如Tolerant Reader消費者驅動型契約模式經常應用到微服務。這些模式有助于服務契約獨立進化。采用消費者驅動服務契約的方式不但可以給服務團隊增加信心,也能快速獲得微服務是否工作正常反饋的良好方式。有的團隊,先定義服務契約,之后再基于契約自動生成編碼骨架,開發團隊負責實現這些服務,不少團隊采用這種方法,效果不錯。

? ? ? ?可能去中心化的最高境界就是亞馬遜提倡的“誰開發,誰維護”的理念,開發團隊負責軟件的方方面面,包含安裝和運維,這種模式確實很難達到,因為這會造成組織結構的重大調整,一些崗位的消失,開發團隊的壓力變大,這必然會帶來阻力,但越來越多的公司正在這么做,或者走在這么做的路上,典型的就是亞馬遜和? ? NETFLIX; 這種模式給開發團隊的壓力(晚上3點中被叫起來處理問題),才會促進開發團隊注重代碼的質量。這種模式和傳統的開發團隊開發、運維團隊運維想去甚遠。

2.6去中心化的數據管理

? ? ?去中心化的數據管理通過幾個方面表現出來:

(1)最抽象的層次是系統之間的概念模型不同,這會在大企業的系統集成帶來問題,銷售眼中的客戶和技術支持眼中的客戶是不同的,一些銷售眼中看到的屬性,在技術支持眼中可能完全沒有,即使出現也可能具有不同的屬性,或者(更糟糕的)屬性相同,但語義卻有細微的差別。 這個問題在單體應用之間很常見,在應用內部也時常發生,特別是應用被劃分為多個模塊的時候,一個有用的方法是采用領域驅動模型DDD,DDD是把一個復雜的領域劃分為多個有邊界的上下文,然后在這些有界上下文上做映射,這個方法對單體應用和微服務都有用,只是DDD劃分的邊界和微服務更為貼合。

(2)除了上述的概念模型去中心化,數據存儲也去中心化,如下圖所示,單體應用傾向于采用單一的數據存儲技術,比如Oracle來存儲數據,而微服務讓每個微服務自己管理自己的數據,因此各個微服務采用的數據存儲技術也可以相差很大,各自管理各自的數據,采用多數據庫來管理各自的數據。?

? ? ? ?去中心化的數據管理對微服務的數據更新有較大影響,在單體應用中,跨越多個資源的數據更新用數據庫的事務就可以保證一致性,但在微服務領域,由于每個微服務都單獨管理自己的數據庫,數據庫采用的管理軟件,存儲方式都不一樣,所以這是一個很大的難點,分布式事務實現起來難度很大,帶來了很多的額外的復雜度,因此微服務架構強調使用沒有事務的微服務之間的協調機制,這種方式明確的提出一致性只能是最終一致性來保證,可能產生的問題只能通過補償機制來完成。

? ? ?這種去中心帶來的不一致問題會給開發團隊帶來很大的挑戰,但這也是最符合實際的業務實質。在實際的業務處理中為了快速應對需求也會有一些不一致,往往通過逆向的流程來處理。只要處理這種錯誤的代價小于強一致性帶來的業務損失,這種取舍就是值得的。

2.7 基礎設施自動化

? ? ? 基礎設施自動化在過去幾年有了長足的發展,云計算的發展簡化了構建、部署和維護微服務的復雜度。很多產品和系統通過持續集成和持續交付構建,采用這些方法的團隊極大的利用了基礎設施自動化,下面這張圖展示了構建流水線的過程。

單體應用能夠用持續集成和持續交付流程快速的部署到生產環境,只要單體應用完成了這種自動化構建,部署多個微服務也不會更復雜,無非是單體應用是單個少量的應用,但微服務是多個應用,1個和多個之間沒有太大的區別。

2.8 失效設計

? ? ? ?采用微服務這種設計風格,應用本身就應該被設計成能容忍失效,任何服務調用都有可能因為目標服務不可用而失效,調用方必須能夠盡可能優雅的處理,從這一點上來說,這相比單體應用引入了額外的復雜性。所以微服務團隊要考慮微服務的失效,如何影響到用戶體驗。Netflix 通過自生產環境里面注入微服務、數據中心故障來測試應用的韌性和應用的監控能力。這種一周繁忙工作結束后在生產環境的自動化測試足以讓很多的開發團隊不寒而栗,需要很強大的勇氣和技術實力作為保障。

? ? ? ?當然這不是說單體架構就不能做這種類型的失效設計,只是不像微服務架構風格這么常見。因為微服務可能在任何時候失效,所以快速的發現這些失效的微服務,并恢復它們(如果可能)至關重要。微服務架構在服務的監控上需要花費更多的精力,需要監控架構指標(如數據庫每分鐘處理多少請求)和業務指標(每分鐘接收到多少訂單),這種指標層面的監控可以給開發團隊告警,從而讓開發團隊去跟進和調查。這種微服務的監控,在單體應用的設計中可以而且也應該被監控記錄下來,但單體應用往往在單個進程里面,因此某個單體應用中的組件,連接不上、失效的價值就沒有微服務這么大了。

? ? ? 現在越來越多的更高級的監控工具和日志工具已經被開發出來,很多是開源使用的,在這些監控工具下,可以在管理面板上看到各個微服務的運行狀態、吞吐量和業務指標,熔斷狀態、延遲等我們關注的一系列指標。

2.9 演進式設計

? ? ? ?微服務的實踐者,通常具有演進式的設計思路,把服務拆分作為一種工具來控制變更,而不是降低變更的速度??刂谱兏皇钦f減少變更,用正確的工具和態度,不但可以頻繁、快速的,而且可以良好的控制變更。

? ? ? ?如論什么時候,開始拆分系統的時候,都面臨如何劃分的問題,這里一個簡單的原則即可了獨立替換、可獨立升級原則,這也就說我們可以重寫整個微服務而不用影響微服務之間的協作。事實上有的團隊更進一步,認為服務從長遠來看更傾向于走向消亡而不是長期演進。

? ? ? 英國衛報網站是一個單體應用向微服務演進很好的例子,單體應用還是網站的核心部分,但新增加的功能和特性就采用微服務調用單體API的方式實現,這種方式對一些天生就是臨時性的服務特別有用,比如處理某個體育時間的專題頁,這種一次性的專題頁,可以通過快速開發的方式,采用快速開發語言開發出一些服務出來,在事件結束后再廢棄掉。這種方式在財經機構的服務里面也很常見,快速的開發出服務,幾個月以后再廢棄掉。

? ? ?這里強調可替換性,是更通用的模塊化設計的一個特殊場景,我們總應該讓變更同一個時間發生在一個模塊內部,不希望是跨越多個模塊的,如果你發現兩個服務總是同時一起改動,那么這就是這兩個微服務應該合并的信號。把組件組合成一個服務可以形成更粗粒度的版本發布計劃,單體應用需要整個應用全部的構建和發布一遍,但微服務架構風格下,僅需要構建和替換修改的這個微服務,這可以簡化和加速發布過程,缺點是不得不考慮單個服務升級對服務的調用方的影響,傳統的做法是采用版本的概念來管理,但在微服務架構風格下,版本僅作為最后不得已的手段,我們在設計微服務時,應該盡可能的考慮能容忍被調用方的變化。

2.10 微服務是未來的主流趨勢嗎

? ? ? ?微服務是未來的主流趨勢嗎,這個問題沒有人能給出確定的答案,文章本身也是聚焦在闡述微服務的主要特點以及和單體應用的不同,就連微服務之父也不能確定的說微服務就是未來的主流趨勢,他也承認需要更多的時間來觀察,盡管當前微服務帶給我們的積極的正向的影響要多于負面的影響,但可以肯定的是微服務是當前重要的一種架構風格,值得我們去深刻考慮和投資,有一些先驅已經踐行這種風格,并且應用的非常成功,國外的比如亞馬遜、Netflix、英國衛報、英國政府等,國內的阿里巴巴、騰訊、網易、以及筆者供職的華為也都大量的采用了微服務這種架構風格,還有很多的這樣的企業正在是使用這種風格的架構來構建自己的企業IT系統。





最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 微服務最近非常流行,各大互聯網公司紛紛采用微服務架構體系,微服務架構模式正在為敏捷部署以及復雜企業應用實施提供巨大...
    Sting閱讀 9,107評論 0 57
  • ——Martin Fowler[https://martinfowler.com/], James Lewis[h...
    Anor9閱讀 2,411評論 0 2
  • 前言:起初沒有意識到自己選了這么一個對自己來說有一些“宏大”的問題,因為里面涉及到好多知識..所以砍了一些內容.....
    我沒有三顆心臟閱讀 5,021評論 0 7
  • 原文鏈接:Introduction to Microservices 微服務介紹(本文) 構建微服務之使用API網...
    nonumber1989閱讀 15,752評論 9 57
  • 有沒有那樣一個人,讓你小心翼翼地放在心里。不去逾越,不去觸碰,就像一顆水晶球,用愛供養在心底。純凈透亮,潔白無瑕。...
    洪一念閱讀 1,084評論 6 8