從單體遷移到微服務的十二種方法
你的團隊決定是時候擺脫那個舊的、笨重的單體了,它運行得很好,但是單體已經變得如此之大,以至於你花費更多的精力來維護它而不是添加功能。這裏有 12 個技巧,可幫助您儘可能順利地過渡到微服務。
#1 確保你知道你在做什麼
重寫從來都不是一件容易的事,但是從單體應用到微服務,你改變的不僅僅是編碼方式;你正在改變公司的運營模式。你不僅需要學習一個新的、更復雜的技術棧,管理層還需要調整工作文化,將人員重組爲更小的跨職能團隊。
如何最好地重組團隊和公司是值得單獨發帖的主題。在本文中,我想重點介紹遷移的技術方面。
首先,在開始之前儘可能多地研究採用微服務所涉及的權衡是很重要的。您希望絕對確定微服務(而不是其他替代解決方案,例如模塊化單體)是適合您的解決方案。
首先學習有關微服務架構的所有知識,並查看一些示例項目以瞭解其工作原理。這裏有些例子
#2 制定計劃
拆除單體應用需要大量準備工作,因爲舊系統必須在過渡期間保持運行。
遷移步驟可以通過工單進行跟蹤,並像任何其他任務一樣在每個 sprint 中進行。這不僅有助於獲得動力(實際上有朝一日實現遷移),而且讓業務所有者瞭解團隊如何計劃實施如此大的變化。
在計劃期間,您必須:
-
解開單體內部的依賴關係。
-
確定所需的微服務。
-
爲微服務設計數據模型。
-
開發一種在單體和微服務數據庫之間遷移和同步數據的方法。
-
設計 API 並計劃向後兼容。
-
捕獲單體應用的基線性能。
-
爲新系統的可用性和性能設定目標。
除非您從一個相當簡單的單體架構遷移,否則您將需要高級技術,例如領域驅動設計 (DDD)。
#3 把所有東西都放在一個 monorepo 中
當你分解單體時,大量代碼將從單體中移出並轉移到新的微服務中。monorepo 可幫助您跟蹤這些類型的更改。此外,將所有東西放在一個地方可以幫助您更快地從故障中恢復。
您的單體應用很可能已經包含在一個存儲庫中。因此,只需爲微服務創建新文件夾即可。
#4 使用共享 CI 管道
在開發過程中,您不僅會不斷推出新的微服務,還會重新部署單體應用。這個過程越快、越輕鬆,你的進步就越快。設置持續集成和交付 (CI/CD) 以自動測試和部署代碼。
如果您使用 monorepo 進行開發,則必須牢記以下幾點:
-
通過啓用基於更改的執行或使用單存儲庫感知構建工具(例如 Bazel 或 Pants )來保持管道快速。通過僅對更新的代碼運行更改,這將使您的管道更加高效。
-
配置多個促銷,每個微服務一個,一個單體。使用這些促銷活動進行持續部署。
配置測試報告以快速發現和排除故障。
#5 確保你有足夠的測試
當我們確定代碼沒有迴歸時,重構會更加令人滿意和有效。自動化測試讓您有信心持續發佈單體更新。
一個很好的起點是測試金字塔。您將需要大量的單元測試、一些集成測試和一些驗收測試。
旨在像在持續集成管道中一樣經常在本地開發機器上運行測試。
#6 安裝 API 網關或 HTTP 反向代理
隨着微服務的部署,您必須隔離傳入流量。遷移的功能由新服務提供,而尚未準備好的功能由單體提供。
有幾種路由請求的方法,具體取決於它們的性質:
-
API 網關允許您根據經過身份驗證的用戶、cookie、功能標誌或 URI 模式等條件轉發 API 調用。
-
HTTP 反向代理的作用相同,但針對的是 HTTP 請求。在大多數情況下,單體實現了 UI,因此大多數流量都會流向那裏,至少一開始是這樣。
使用 API 網關和 HTTP 反向代理將請求路由到適當的端點。您可以在非常細粒度的級別上在單體和微服務之間切換。
遷移完成後,網關和代理將保留——它們是任何微服務應用程序的標準組件,因爲它們提供轉發和負載平衡。如果服務出現故障,它們還可以充當斷路器。
#7 考慮一體成型的模式
好的,這僅適用於您計劃將容器或 Kubernetes 用於微服務的情況。在這種情況下,容器化可以幫助您實現基礎架構的同質化。一體式整體模式包括在 Docker 等容器內運行整體。
如果您以前從未使用過容器,那麼這是熟悉該技術的好機會。這樣一來,您就離了解 Kubernetes 更近了一步。要學習的東西很多,所以要爲陡峭的學習曲線做好計劃:
-
瞭解 Docker 和容器。
-
在容器中運行你的單體應用。
-
在容器中開發和運行您的微服務。
-
完成遷移並掌握容器後,瞭解 Kubernetes。
-
隨着工作的進展,您可以擴展微服務並逐漸將流量轉移到它們。
容器化單體應用是標準化部署的一種方式,也是學習 Kubernetes 的絕佳第一步。
#8 熱身於變化
習慣微服務需要時間,所以最好從小處着手,爲新範式做好準備。留出足夠的時間讓每個人都進入正確的心態、提高技能並從錯誤中吸取教訓,而不會受到最後期限的壓力。
在這些初步的初步步驟中,您將學到很多關於分佈式計算的知識。您必須處理雲 SLA,爲您自己的服務設置 SLA,實施監控和警報,定義跨團隊通信的渠道,並決定部署策略。
選擇一些容易開始的東西,比如與單體架構的其餘部分幾乎沒有重疊的邊緣服務。例如,您可以先構建身份驗證微服務並路由登錄請求。
選擇一些容易開始的東西,比如簡單的邊緣服務。
#9 使用功能標誌
功能標誌是一種無需重新部署即可更改系統功能的軟件技術。您可以使用功能標誌在遷移時打開和關閉部分單體應用、試驗替代配置或運行 A/B 測試。
啓用功能標誌的遷移的典型工作流程是:
-
確定要遷移到微服務的單體功能的一部分。
-
用功能標誌包裝功能。重新部署單體。
-
構建和部署微服務。
-
測試微服務。
-
一旦滿意,通過關閉該功能來禁用單體應用上的該功能。
-
重複直到遷移完成。
因爲功能標誌允許我們將非活動代碼部署到生產環境並隨時切換它,所以我們可以將功能發佈與實際部署分離。這爲開發人員提供了極大的靈活性和控制力。
#10 模塊化單體
如果你的單體應用是一堆代碼,那麼一旦遷移完成,你很可能會得到一堆_分佈式代碼。_就像在全面翻新之前收拾房子一樣,模塊化整體結構是必要的準備步驟。
模塊化單體是一種軟件開發模式,由獨立且可互換的垂直堆疊模塊組成。與模塊化單體相反的是經典的 N 層或分層單體。
分層的單體很難解開——代碼往往有太多的依賴關係(有時是循環的),使得更改難以實現。
模塊化單體是微服務的下一個最佳選擇,也是邁向微服務的墊腳石。規則是模塊只能通過公共 API 進行通信,默認情況下一切都是私有的。因此,代碼的交織更少,關係易於識別,依賴關係清晰。
有兩種模式可以幫助你重構單體:Strangler Fig 和 Anticorruption Layer。
Strangler Fig
在 Strangler Fig 模式中,我們將整體重構從邊緣到中心。我們在邊緣咀嚼,逐步重寫孤立的功能,直到整體重做。
模塊之間的調用通過 “扼殺外觀” 進行路由,該外觀模擬和解釋遺留代碼的輸入和輸出。一點一點地,模塊被創建並慢慢取代舊的單體。
單體是一次模塊化的。最終,舊的巨石消失了,取而代之的是新的。
反腐敗層模式
您會發現,在某些情況下,當您重構整體時,一個模塊中的更改會傳播到其他模塊。爲了解決這個問題,您可以在快速變化的模塊之間創建一個轉換層。此防腐敗層可防止一個模塊中的更改影響其餘模塊。
反腐敗層通過轉換模塊和單體之間的調用來防止更改傳播。
#11 解耦數據
超級強大的微服務使您能夠隨時部署任何微服務,而與其他微服務幾乎沒有協調。這就是爲什麼必須不惜一切代價避免數據耦合的原因,因爲它會在服務之間產生依賴關係。每個微服務都必須有一個私有且獨立的數據庫。
意識到您必須將單體應用的共享數據庫非規範化爲(通常是冗餘的)較小的數據庫,這可能會令人震驚。但數據局部性最終將讓微服務自主工作。
上圖是將數據解耦到獨立的數據庫中。
解耦後,您必須安裝機制以在轉換過程中保持新舊數據同步。例如,您可以設置數據鏡像服務或更改代碼,以便將事務寫入兩組數據庫。
在開發過程中使用數據複製來保持表同步。
#12 添加可觀察性
新系統必須比舊系統更快、性能更高、可擴展性更強。否則,爲什麼要用微服務呢?
您需要一個基線來比較舊的和新的。在開始遷移之前,請確保您有良好的指標和日誌可用。安裝一些集中式日誌記錄和監控服務可能是一個好主意,因爲它是任何微服務應用程序可觀察性的關鍵組件。
結論
微服務之旅絕非易事。但我希望通過這些提示,您可以節省一些時間和挫敗感。
請記住以小增量進行迭代,利用 CI/CD 來保證單體應用程序正在接受迴歸測試,並將所有內容保存在一個存儲庫中,以便在出現問題時隨時回退。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/CpU5yzqrMLp85H8V5NrqBA