歐哥說說

說說興趣 ‧ 說說科技 ‧ 東說西說 ‧ 就是要說  

什麼是微服務 (microservices) 架構

沒有留言
       
     

        微服務架構是一種設計軟體系統的方式與風格。有別於原有的單體式系統,它進一步的將所有軟體元件從運行在單一系統的框架,改變成為分散式的服務結構,進一步地去解決單體式系統的系統痛點。常見的單體式架構有以下的困擾 :

      1.  技術框架僵化

          囿限於大一統的系統框架下,讓各元件的實作方式必須單一化,無法去採用最適的實作語言或者是相關的軟體套件。

       2. 牽一髮而動全身的修改

          單體式系統的任何變更,都將涉及整個系統的更新與變動。大型系統的更新與變動,不僅是在編譯準備或者是測試,都會隨著系統變大而日益痛苦。

       3. 無效率擴容           

          單體式系統含括了系統所有功能項目,有些元件可能是高耗CPU,有些則是高耗I/O;有些工作比較繁重,有些則比較輕鬆。但擴容需求產生時,由於單體式系統的不可切分,通常只能面對全系統的擴容,而無法以有效且針對性的進行效能增加。

       微服務在上述的背景下被提出,並且試著解決這些困擾。本篇文章將以Martin Fowler的專欄內容為參考,簡單扼要地探索微服務的樣貌。

       從Martin fowler的專欄[1]裡可以看到以下簡短的描述:

      the microservice architectural style [2] is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API. These services are built around business capabilities and independently deployable by fully automated deployment machinery. There is a bare minimum of centralized management of these services, which may be written in different programming languages and use different data storage technologies.

     簡單地說就是微服務架構為一群有各自特定目標且獨立運行的服務元件所組成的系統。各元件有獨立的資料存儲空間與事務邏輯,而各元件之間利用標準而輕量的通訊協定進行系統層級的協作,因此各服務均能被獨立的佈署與替換。

     看完上述扼要的定義後,再從Martin Fowler專欄內所提及的微服務特徵來進一步了解微服務的概念,並且了解在建構微服務的系統時,應該考量的要素。系統的設計隨著需求與發展,往往會有相應的取捨,能夠符合所有特徵自然是好,但若無法符合,至少可以知道改善的方向或者是取捨了些什麼。

       1. Componentization via Services

           所謂的元件是指可被獨立升級與替換的軟體元件。因此在設計系統時,我們將有相同業務目標的功能聚集,並且獨立服務化。各服務因此可以被單獨地更換或者是升級,而不會進一步影響其它服務或者是系統的正常運作。以上的設計奠基於完善地介面設計與定義,因此在介面下的更新,並不會對系統或者是其它的元件造成太大的影響。

       2. Organized around Business Capabilities

           常見的組織分工往往會按人員技能不同而進行水平切割。比方說,有專業的UI/UX團隊、專業的前端團隊與專業的後端團隊等,這種分工模式往往會造成較高的溝通成本。基於康威定律,我們也可以進一步觀察到系統設計偏向水平切割,而難以採用微服務的設計概念。一個微服務設計架構下的團隊,可以明顯看見團隊內的技術完整性,也就是垂直分工的協作模式。各服務元件圍繞著本身的業務邏輯,並且由有完整技術鏈的小型團隊各自負責所屬服務元件的開發。小團隊的作戰模式,不僅降低了溝通成本也加深了團隊成員對於服務元件業務邏輯的專業度。說到此,肯定有人會對於微服務的團隊成員數目感到疑惑,到底一個以微服務作為設計原則的團隊有多大,這個答案其實很難有個明確的數字,因為這也牽涉到組織人力資源的配置和服務元件的顆粒度大小。舉個例子來說,Amazon提出所謂的「兩塊pizza」的概念,也就是說一個團隊大小剛好就是兩塊pizza能夠餵飽的大小。而以我自身的經驗來看,大致上是兩周可以妥善完成一個完整功能集的人數。

       3. Products not Projects

          常見資訊系統開發的分工結構為研發工程師負責系統開發,開發完畢後,開發團隊寫下完善的指導手冊,並且交付維運單位進行日後維護,然後研發團隊分派到新的研發專案上。這樣的分工結構,很難有效解決快速變更的開發需求。另外,在溝通成本以及責任釐清上也都會產生不效率的情況。因此在微服務設計架構思維上,強調將相關的服務元件開發當作產品開發而非專案開發,也就是說,由專責的開發團隊負責該元件的一切開發與維運責任直到產品日落為止。

       4. Smart endpoints around dumb pipes

           微服務架構下,更強調服務元件本身的內聚力。也就是說,服務元件應該更妥善地包裹負責的業務邏輯,然後進一步提供簡單的接口讓外部的其它服務取用,其它的服務只管知道如何從接口獲得它要的資訊以及自身的業務邏輯要如何善用該資訊。完善封裝的端口需要搭配的便是有效且簡單的通訊機制,通訊機制本身不應該載負業務邏輯且應該採用更輕量且中性的通訊模式,比方說RESTful或者是Message Queue。

       5. Decentralized Governance       

           有別於單體式系統,微服務架構允許服務去採用各自最適的技術方案解決服務內的業務功能需求,無須捆綁在單一技術堆疊之下而無法動彈。這是一個讓系統設計得到可以進行充份選擇的權利,鬆綁了原先的不自由,但這並不代表研發團隊非得因為這樣而擁抱多樣化的技術堆疊,因為這涉及了人員技術的熟稔程度與日後維護的成本。另外,這樣的概念能夠被落實也有賴於前述第三點所提及的特點,因為團隊對自身的服務元件有妥善負責的義務,因此可以讓元件在技術選擇上,得到一定的彈性與效率。

       6. Decentralized Data Management

           在單體式系統下,設計偏向於單一資料庫系統的建置,然而這往往會導致設計上的一些困擾,比方說一樣物品的屬性,從不同的角度去觀察往往有不同的意涵與表示的樣貌,然而在單體式系統資料庫上要顯示這樣不同的觀點其實並不容易。沿著各自服務邊界所設計的微服務有明確的功能範疇,搭配上獨立的資料庫,便可以輕鬆地以各自業務角度去解釋與存儲資料。然而這樣的好處其實也不是完全無成本,分散式的系統所要面對的就是所謂的資料「最終一致性」的取捨。由於服務資料各自存儲與管理,必然會產生同質不同義資料之間的同步遲延問題,這問題將有賴於各服務對於資料過期的處理方式與準則,讓資料管理去中心化與同步遲延兩者之間取得平衡。 

      7. Infrastructure Automation

           這項特性其實就是目前最為人所樂道的運維技術風格──CI/CD。隨著目前公有雲服務商提供越來越多高彈性的運維環境,將枯燥而重覆性高的運維工作自動化,可以說是一個重要的趨勢。但在自動化思維下,所必須要強調的一個前題則是服務元件的測試周全性。在進行運維佈署自動化的同時,針對測試的自動化執行與監測也相對重要。

      8. Design for failure

           微服務架構設計使得軟體系統內的溝通線更為複雜,使得服務在設計當下需要更積極地去考慮服務請求的失敗和相應的處理,以避免服務停擺、崩潰或者是資料錯誤。除此之外,對於各服務的監測與容錯測試也應該更為積極,讓錯誤的訊息能即早被發現並且處理,而運維系統也應該提供更妥善的自動復原的功能,來進一步加強系統的穩定性。

      9. Evolutionary Design

           由於系統需求的變化、功能演進與快速更迭的需求下,服務的拆分與合併在微服務的概念下,更容易被實現,而微服務的開發者也更能擁抱這種循序漸進地改變方式,讓系統的需求變更,能受到妥善的控制,而不使整體系統產生過大的衝擊。至於拆分的準則,可以從服務功能是否能被獨立替換或者是更新,作為其邊界的要件;抑或者是按照功能本身的業務關聯性進行拆解。如果遇到服務更新,屢屢會產生同時變動的情況下時,也可以進行合併,讓各自服務的內聚力有效地提升。俗話說的好,軟體系統唯一不變的就是它的易變性,漸進且逐步詳細的設計與實作方式,才能更有效地提高系統的完整性。


      微服務的發展既是系統設計上的需要,也是相關技術與流程改善下所催生出的結果。講到這邊,難免又會討論到是否微服務就是軟體的銀色子彈。答案應該仍然是明確的──不是。微服務雖然針對固有的單體式設計缺點而來,進一步改善了原有的缺點,但微服務本身所引進的成本也是明顯的,比方說,分散式系統的管理問題與開發資源問題等。相對於單體式系統的初期運維成本和門檻,微服務架構是明顯高了許多。因此,在系統設計初期,並不建議馬上從微服務架構起手,仍然得按照自身的需求,進行系統的設計並且在合適的時機,進行架構上的轉換與改善,讓業務發展與資訊系統可以相互配合,而此一合適時機則有賴於組織軟體能力的成熟度、軟體設計的模組化和真實需求的發展,才能找到答案。

    

------------------------------------------------------------------------------------------------------------------------- 1: https://martinfowler.com/articles/microservices.html
2: The term "microservice" was discussed at a workshop of software architects near Venice in May, 2011 to describe what the participants saw as a common architectural style that many of them had been recently exploring. In May 2012, the same group decided on "microservices" as the most appropriate name. James presented some of these ideas as a case study in March 2012 at 33rd Degree in Krakow in Microservices - Java, the Unix Way as did Fred George about the same time. Adrian Cockcroft at Netflix, describing this approach as "fine grained SOA" was pioneering the style at web scale as were many of the others mentioned in this article - Joe Walnes, Dan North, Evan Botcher and Graham Tackley.

沒有留言 :

張貼留言