為什麼導入微服務架構很容易撞牆?

一次了解微服務架構的各種技術議題和陷阱

Fred Chien(錢逢祥)
Brobridge - 寬橋微服務
9 min readJun 18, 2020

--

Photo by Waldemar Brandt on Unsplash

微服務架構(Microservice Architecture)像是一團迷霧,伸手不見五指,無論怎麼做好像都是錯的,一不小心就撞上了藏在霧中的牆。在一知半解下,有人選擇導入容器平台(如:Kubernetes)走一步算一步,有人選擇觀望或是先了解到底有哪些事需要「超前部署」。但不管怎麼下這盤棋,不管走了多少步,永遠看不透這團迷霧,不知道這盤棋的終點在哪。

尤其是一些已經花了錢做基礎設施(Infrastructure)的客戶比誰都慌張,來找我們時,都希望我們能幫忙指出一條可行的路。雖然就算指出來,仍然是一條不容易走的路,但總比在黑暗中亂摸索,更讓客戶覺得安心。

本文將試著整理出整個微服務架構中,各種關鍵技術議題、被忽略的議題,希望能讓欲導入微服務架構的企業和組織,可以瞭解這條路上將要面臨的考驗。

大多數企業已經做了什麼?

可以說,許多企業在基礎設施上,已經具備了實現微服務架構的基礎(例如:Kubernetes、CI/CD 等)。撇除開發規範、組織政策改造等議題,在部署和維運層面上已經多半沒有問題,接著要面對的是應用開發、服務改造以及落實架構等議題。

在應用開發上,首先是選擇一個夠輕量的應用程式框架(Application Framework),來因應微服務多而散的部署需求。在這種考量下,根據企業原先習慣的語言而有不同的選擇,例如習慣 Java 的企業,通常會選擇 Spring Boot。

另一方面,從架構設計來看,微服務思維的服務拆分就是一個明顯要解決的問題。因此,許多企業亦開始將領域驅動設計(DDD, Domain-Driven Design)當作唯一手段,以梳理既有業務、拆分既有服務。

從各方面來看,似乎一切都已經完備。

大家到底遺漏了什麼?

服務邏輯拆分之下、應用程式框架之上仍有許多議題待解決(圖中只是部分)

乍看之下,多數欲投入微服務架構的企業,在技術選型上,似乎下有應用程式框架,而上有領域驅動設計等方法,理論上在微服務之路上,應該走得順遂。然而,市場上仍不斷聽到有企業導入失敗,或是走到最後走不下去的聲音。

事實上,在「應用程式框架」與「服務邏輯拆分」之間,仍然缺少許多東西,如圖中紅色區塊所示。而缺少的部分,才是微服務架構設計與實作中,最複雜也是陷阱最多的地方。

要有認知,分散式架構下的各種設計,與過去的思維並不太一樣,以往我們可以在單一資料庫、同個記憶體中實現的功能,都會被搬出到不同的機器、節點上,然後跨網路協同作業。這對許多開發人員來說,都是全新的領域、全新的設計模式,舊有的經驗甚至一時無用武之地。

以過去經驗去看待微服務架構,很容易到後來會發現,繞了一大圈搞了半天,結果只是做了一堆分散式的單體架構(Distributed Monolith),沒有得到微服務的半點好處,甚至是招來許多難以解決的問題,掉入難以翻身的陷阱。

忽略了種種議題後,要把微服務架構正確的建構出來,幾乎是不可能的事。

資料解耦是迷霧中的起點

微服務架構設計議題包括邏輯拆分和資料解耦

儘管引入許多設計模式,或是採用領域驅動設計(DDD)來解耦服務,多半重心仍都在討論應用邏輯的拆分,尤其若是缺少了相關技術的知識,通常大多數人面對資料層的解耦工作,都會選擇忽略或是放棄。這也是為什麼很多人找了顧問來導入 DDD 之後,一旦進入技術實作,要不就是做出來成效不好,不然就是實作不出來。

要知道,資料是應用中最具有「重量」的部分,唯有資料解耦才能真正實現微服務架構的服務拆分。若我們在做 DDD 或服務拆分工作時,遷就資料而做了錯誤的聚合(Aggregate),就無法正確的實現微服務架構,最終導致失敗。

至於資料解耦,一定要做高風險的拆表拆庫嗎?不需要。若想要理解資料解耦的真正目的,以及解耦後的資料管理方法,可參考舊文:CQRS 的神奇把戲:微服務資料解耦

在一些 DDD 的書籍之中,通常都會提及如 CQRS 這類技術設計模式,協助 DDD 中的領域邊界進行資料交換或聚合。只不過,很多人只將 DDD 當作純理論的方法看待,而忽略了這些書籍中提及的技術議題,導致徒有形,而缺乏實際的處理手法。

資料一致性是一切核心

圍繞在資料一致性上的議題

基本上,微服務架構就是分散式系統的設計,這意味著服務狀態、資料都不是中心化的存在,除了要考慮服務間狀態一致性的問題,也要考慮資料同步、分享等議題。但面對不同的應用,資料一致性的要求也不同,有些應用需要絕對的一致性,有些應用可以接受強一致性,而有些應用場景只要實現最終一致性就可以。

面對不同的資料一致性需求,解決方式也相當多元,主要議題圍繞在分散式資料管理(Distributed Data Management)、狀態及物件生命週期管理、分散式交易(Distributed Transaction)或有狀態服務(Stateful Service)的身上。

唯有妥善設計這些管理機制或進行適當的整合,才有可能在不同應用下,實現微服務架構。只要過於偏重特定的設計模式,或是在不恰當的情境下採用錯誤的方法,都會導致許多後遺症,甚至失敗。

錯誤的設計,可能會導致無法解耦的資料庫、難以擴展的單體式架構,甚至面臨效能衝擊、維護性問題。

搞清楚低延遲需求如何滿足

理論上,分散式架構無法解決的問題就是延遲(Latency),由於程式邏輯、資料分散,導致大多數任務都需要跨服務溝通、同步和交換狀態,這意味著延遲的狀況總會發生,只是目標應用接受延遲的程度為何、是否能接受而已。

雖然現在的電腦、網路效能和速度都非常快,這些延遲都不是使用者可以明顯察覺的狀況,對於大多數應用都是可以接受的。但如果你的應用無法接受這些延遲,需要更極端的即時需求,這時就要依賴有狀態服務(Stateful Service)的設計。

只不過,有狀態服務在擴展能力及容錯能力上並不好,很容易變成效能瓶頸和穩定性的缺口,伴隨而來的單點故障、分散式單體架構問題,都是陷阱。因此如何解耦、優化有狀態服務,最小化其運作風險,就是關鍵。這時,懂得設計狀態管理機制和事件排程機制,來實現具有擴展性、又高吞吐量的低延遲需求,就是一件不得不弄清楚的事。

痛苦的開發人員沒有三頭六臂

待實現的各種微服務議題

許多開發人員原本期望應用程式框架(Application Framework)能夠有完整的解決方案,但現實是仍有一大段路,需要由個開發者自行解決,尚未有一個終極且完整的解決方案存在。

另外,雖然有一些開放原始碼專案,能部分解決或涵蓋一些議題,但因為這些專案的不同發展背景,所以其出發點和著眼點也不盡同,很多不一定能滿足各企業的需求,甚至仍然需要客製化和自行維護。更多還是要依賴著開發人員的經驗和能力,才能把所需的微服務機制實現出來。

但種種議題每一項都不容小覷,一般企業的應用程式開發人員,若要投入任何一項議題,都得花大量精神和人力,很可能無暇再照顧應用程式的開發。尤其是,這種種機制的穩定性和擴展性,是微服務架構能否運作順暢的關鍵,若不好好設計和維護,最終結果可想而知。

這還沒有提到,讓初入微服務架構的開發人員,在一知半解下嘗試完成這些關鍵機制,會有多高風險。對於原本專心於應用程式邏輯的開發人員來說,也是一件痛苦至極的事。

到底如何解決這些議題和避開陷阱?

從基礎機制之上,解決分散式資料和狀態管理以滿足服務解耦的需求

由於資料一致性議題是微服務的核心,所以支撐各類資料一致性的機制,是我們要解決的重中之重,由此下手是最佳的部位。接著,解決大部分資料議題後,再進一步擴展處理服務拆分的技術性問題。

在這種導入途徑下,引入 CQRS、分散式交易機制、物件狀態及生命週期管理機制和事件排程機制,就是技術實現的關鍵核心。而於此之下的事件驅動、通訊機制議題,則是不用太過擔心,可以透過妥善的教育訓練或傳統的解決方案,即可滿足。

示意圖是從 寬橋(Brobridge) 的產品簡報中所截取出來的內容,綠色部分為產品中的各種軟體元件,用於解決本文所提到的種種關鍵議題。這些開箱即用的微服務元件,讓企業可專心於應用開發,無需再自行實作相關機制,而避免掉入微服務的各項陷阱中。

最後強烈建議

如果您到現在對於本文所提及的種種議題和設計模式,仍感到不太熟悉甚至聽都沒聽過。建議您先停下腳步,在還沒出更大問題之前,先理解這些議題背後的意義與解決方法之後,再繼續您的微服務之旅。

本文資料,來源皆參考自 寬橋(Brobridge) 的微服務架構設計教育訓練課程,如果想要暸解更多關於微服務架構設計的議題,可以與我們聯絡。若對特定微服務元件,或是微服務元件套裝感興趣,也歡迎與我們洽詢。

此外,微服務架構在實務上尚有許多可發展和改善的地方,所以未來陸續會持續推出新的元件和解決方案。若您想要得到微服務元件的第一手消息、第一時間取得並使用最新的軟體元件,建議可以購買我們的套裝服務。

--

--