iT邦幫忙

2025 iThome 鐵人賽

DAY 28
0
Software Development

微服務導入:從觀念到落地的架構實戰地圖系列 第 28

微服務導入 – Day 28 重構 – 分割單體式系統 I

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20251004/20178262xBeQ0WkWyS.png

從昨天的文章推論,依據我過去的經驗來說,確保「應用程式現代化」過程最好的方式是「不大規模地改寫既有系統」。而在今天的文章中,我要分享的是我看過的幾個模式可以符合這個「限制」的條件下來重構我們的應用系統。

做任何的系統遷移,最初的工作不外乎是規劃,而其中要考量的一個點是「你是否有能力來變更現有系統?從技術發展到今天這個進程來看,我們似乎沒有什麼沒辦法改的?就算改不動還有 AI 吧 (這個想法對不對,我正在關注著幾個身邊的案例,有了結果後再來分享 AI 到底是救星還是壓垮你的最後一根稻草)!


風險的思考

我有遇過,一個專案裡面是沒有原始碼的!所以,風險還是要考慮吧!為什麼我們會想要改變一個單體式的系統?通常一個理由是繼續維護這個應用程式的成本過高 (找不到人、或是使用了某些落日的技術造成監管上的問題)。

所以,在這裡提醒你,你有可能改不動,或是系統有太多的依賴導致你不能改動。

計劃改動

所以,依據先前的文章,我們知道「絞殺榕應用程序」的模式是一個好主意來實現應用程式的移轉。假設,我們現在不討論「新服務」僅針對「提取既有業務功能形成微服務」,那麼我們該用「剪下」、「複製」或「重新實現」哪種方式來改動。

到了這裏,我想你應該不會選「重新實現」這個方法吧!除非你沒看到先前文章中提及的失敗案例。所以,我們會透過「剪下、貼上」的方式來重新模組化應用程式,使得其耦合度更低,更適合獨立運作。

在原本「絞殺榕應用程序」中,隨著時間的推演「單體式系統逐步地縮小」,這點我認爲不應該修改既有的應用程序,因為他為我們留下一個可以切回來的選項,所以不要急著刪除既有的應用程式 (而且這樣我還要花時間去修改與維護舊版的應用,將導致開發的資源更加緊張)。

套一句 Clean Code 書中寫的一句話,如果你的應用程式沒辦法應對改變,那就先把它修到可以面對改變後再開始改變。當我們採用漸進式重寫進行微服務的交付時,如果,我們在進行這些的調整工作需要幾天或是幾週的時間,這還算及格。但,如果你需要好幾個月,可能就要檢視一下我們的工作程序了。


模式:絞殺榕應用程序

https://ithelp.ithome.com.tw/upload/images/20250925/20178262c45kpcG6yS.png

絞殺榕模式概念 (參照:單體式系統到微服務)

絞殺榕模式讓我們在做功能移轉的時候無需對既有系統做任何的調整 (可能是很少的調整),所以可以確保在遷移的過程是安全的。

從上面的圖例來看,絞殺榕模式我們需要做的第一個工作是找到一個可以「切入」的介面(現在很多系統是透過 HTTP 的通訊協定來做為公開介面),將其做為「規格」然後開始搬移這一部分。

所以,藉由這樣的假設,我們可以透過「架設 HTTP 反向代理伺服器」來進行這個遷移作業,底下就針對 HTTP 反向代理伺服器的處理方式進行進一步的說明:

範例:HTTP 反向代理伺服器

步驟1:插入代理伺服器
為了將上述找出的公開介面遷移到新的架構中又不影響到現在已經在使用的客戶,所以我們必須先架一層反向代理伺服器讓「介面」維持穩定。後續移轉的時候,客戶端面對的就都是 HTTP Proxy 的介面,所以未來在遷移功能的時候對維運的衝擊相對的就會降低。

https://ithelp.ithome.com.tw/upload/images/20250925/20178262prHfa022E6.png

步驟2:遷移功能
第二段是將既有服務抽出,在新的專案中實現相對應的功能。比較合理的做法是將「既有系統」的程式「複製」到新的專案中。
理想是美好的,現實總是殘酷的 …
在目前我們所經歷的 100% 案例都沒辦法像上述那樣順利。原因是:
(1) 既有系統未充分模組化,導致無法順利找出明確邊界進行遷移
(2) 既有系統算是陳年老酒了,很多技術框架版本都過舊 (end of life)
所以,這段工作可能沒有理論上那麼單純,通常伴隨:
(1) 如果有資訊安全疑慮,相關的框架可能需要升級提升
(2) 先重構到要搬移系統已經具備明確的邊界
(3) 然後再完成功能遷移的作業

https://ithelp.ithome.com.tw/upload/images/20250925/20178262sW4e9FYsyr.png

基本上,這個步驟原理沒錯,應該就像原本所說的那麼簡單「複製、貼上」開箱即用。但是,因為既有系統疏於「維護」而且沒有進行「模組化」,所以才會造成上述額外的作業。
所以,就算沒有要做「微服務」,最好還是對系統做一下良好的設計,以備不時之需。

步驟3:重新導向呼叫
如果,經歷了上述的陣痛,將服務萃取到新的專案後,我們就可以透過改變 HTTP Proxy 的繞送規則讓已經遷移完成的「微服務」上線。

https://ithelp.ithome.com.tw/upload/images/20250925/20178262PskedIPXri.png

此時,我們的「微服務」就已經發佈上線了,如果在上線的過程不順利也可以隨時切回去既有系統。

接著,可能會有人開始思考或是想問「HTTP Proxy」該怎麼做?基本上,我們通常使用 Nginx 來實現反向代理伺服器的機制 (IIS 跟 Apache HTTP Server 也都可以實現),其中 Nginx 支援 Lua 程式語言來添加自定義的行為,所以可以滿足我們絕大部分的需求 (畢竟 Kong 也用 Nginx 的核心搭建了一個 API Management 的平台)。

此時,我們做到了「應用程式的分割」,但還沒套用 Database per service 的模式,所以是「拆分應用程式」但屬於 shared database 的狀態。這是實踐為服務移轉的套用「絞殺榕應用程序」的一種實作的方式,後續我會再介紹兩三種模式來面對不同情境的考驗。


結語

在這篇文章裡面我們談到從既有系統分拆應用出來,此時你會發現我們還沒完全符合先前「微服務」中談的各種應用模式,充其量就是讓服務可以被拆出來獨立部署這件事。但是,資料分拆等相關議題都還沒討論,不過沒關係,服務本來就是一步一步慢慢拆,拆到某個段落就可以部署去驗證概念了!

所以,不用著急,如果你需要完成更多的設計,我們一步一步進行並持續觀察相關的作業是否有滿足你的商業目標,記住技術是手段,不是你關注的目標。


上一篇
微服務導入 – Day 27 重構 – 從單體到微服務
下一篇
微服務導入 – Day 29 重構 – 分割單體式系統 II
系列文
微服務導入:從觀念到落地的架構實戰地圖30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言