案例:微服務從Java/SpringBoot遷移到Golang

banq發表於2024-02-22

基於 Java 的微服務,特別是那些使用 Spring Boot 的微服務,長期以來因其強大的功能和廣泛的社群支援而聞名。Spring Boot 的約定優於配置方法簡化了微服務的部署和開發,提供了大量開箱即用的功能,例如自動配置、獨立功能和簡單的依賴關係管理,使其成為許多人的首選開發工具。該生態系統為構建有彈性和可擴充套件的服務提供了成熟且有據可查的途徑。

然而,儘管有這些實質性的好處,但仍然存在一些痛點,例如較長的啟動時間、記憶體消耗以及管理基於 JVM 的應用程式帶來的複雜性,這可能會阻礙雲環境中的效能和成本效率。

在維護 Java 生態系統的最後努力中,我們嘗試了 Quarkus,希望它最佳化執行時和減少記憶體佔用的承諾能夠解決我們的擔憂。。Quarkus 能夠將應用程式編譯為本機可執行檔案,這似乎是希望的燈塔。

然而,現實卻是錯綜複雜的。使我們的應用程式本地編譯的過程充滿了許多調整和解決方法。更令人沮喪的是原生構建的脆弱性。

與 Quarkus 的本機映象不完全相容的單個第三方庫可能會破壞整個設定,迫使我們重新將其作為標準 JDK 應用程式執行。效能增益和操作穩定性之間的這種不穩定的平衡凸顯了對更精簡、更少約束的解決方案的需求。

目標
我們需要一個能夠快速構建本機映象的解決方案:

  • 包含 SDK 本身內的所有必要的微服務元件。
  • 它需要擁有令人印象深刻的快速啟動時間,
  • 輕鬆打包到從頭開始生成的 Docker 映像中,並保持輕量級佔用空間,容器映像大小和
  • RAM 使用量均低於 100 MB。

Golang:簡化微服務以提高效率和可靠性
Golang 是一種為現代計算挑戰而設計的語言。與 Java 相關的複雜性和開銷以及 Quarkus 中本機編譯的不穩定性質不同,Golang 提供了一種簡單、高效的方法來構建微服務。

  • 其編譯為本機二進位制檔案消除了對 JVM 的需求,從而大大減少了記憶體佔用和啟動時間。
  • Golang 憑藉其強大的併發支援和簡單、乾淨的語法,簡化了開發過程並增強了效能。
  • 此外,其強大的標準庫和簡約的本質意味著更少的依賴性和更低的相容性問題機會。

Golang 不僅解決了前面提到的痛點,還推動應用程式進入更高效率和可靠性的領域。

如何計劃遷移
最初,我們遵循領域驅動設計 (DDD) 原則將業務分解為各個子域,旨在為每個子域分配專用的微服務。具體來說,我們專注於為人力資源管理、財務管理和資產管理建立獨特的微服務。接下來,我們確定了共享核心微服務來管理多個子域使用的域實體的需求。我們共同使用白板在微服務中描繪了這些域實體,確保了清晰且邏輯的分佈。

為了視覺化並更好地組織我們的架構,我們製作了一個依賴關係圖。該圖根據微服務的相互依賴性將微服務分層,其中共享核心形成基礎層,而更加孤立的、特定於子域​​的微服務佔據較高層。

我們準備階段的最後一步涉及為每個微服務編制完整的用例列表。我們根據測試用例和遺留後端中的現有用例精心對映這些內容,確保徹底、無縫地過渡到我們新的、更高效的微服務架構。

如何執行遷移
我們選擇了 monorepo 方法,將所有微服務組織為名為“ems-backend”的單個儲存庫下的單獨資料夾。此外,我們製作並開源了一個簡單的框架式包。該包有助於實現 Golang 微服務,配有 HTTP 伺服器和 Mongo 資料庫,同時遵循乾淨架構的原則。

利用我們的框架,主要任務是將用例開發為系統內命令和查詢的函式。然而,我們確實為特定的 HTTP 任務(例如檔案上傳)編寫了自定義處理程式。在我們的設定中,用例是後端的核心方面,協調多個域實體以有效地滿足使用者需求。

基於我們的成功,我們還使用 Go 開發了一個異常快速的 API 閘道器。該閘道器執行符合 OWASP 微服務安全標準的邊緣身份驗證。每個微服務都配備了自己的中介軟體,這是一個簡單的功能,可以根據 Passport 令牌中嵌入的角色驗證傳入請求 URL。這確保了服務之間安全、高效的互動。

遷移後我們的成就
我們修改了 Kubernetes 清單來部署應用程式,將 RAM 限制從 500 MB 減少到僅 50 MB。
這次轉變非常顯著:我們的 32 GB 後端現在可以在 8 GB 叢集上順利執行,僅使用 2 GB RAM。
如果您當前正在管理 RAM 限制為 2 GB 或更多的 JDK 應用程式,那麼我們的故事可能會為您帶來希望的燈塔。

相關文章