12種從單體架構向微服務轉型的設計原則與優秀實踐
譯文【51CTO.com快譯】不知您是否還記得,過去傳統的應用程序往往是作為一個整體被開發出來,然后被打包成為一個代碼包,進而作為一個整體單元被部署的。一直以來,這種單體架構本身和與之相關的維護極具復雜性,而且開發與迭代速度也相當緩慢。這些都在促進軟件開發企業去不斷地尋求具有可持續性、靈活性、以及易于集成的新型替代方案。
微服務架構的出現打破了這樣的僵局。它代表了眾多小型、自動化和自包含的服務的單一集合。下圖展示了系統如何通過一個API網關,去訪問多個微服務的邏輯。
微服務架構雖然有著諸多優勢,但是貿然從單體架構切換過去,可能會讓許多企業由于低估了整體的復雜性,而導致成本的激增,以及在研發的關鍵時刻出現災難性的意外錯誤。下面讓我們一起討論十二種值得遵循的,從單體架構向微服務轉型的設計原則與優秀實踐。
1. 提供單獨的數據存儲
在考慮遷移之前,請事先弄清楚將會如何根據各種微服務組件來分離數據的存儲。您可以通過使用諸如“命令與查詢責任隔離”(Command and Query Responsibility Segregation,CQRS,請參考:https://dzone.com/articles/microservices-with-cqrs-and-event-sourcing)之類的架構模式來實現,以使得數據對每一個微服務都是私有的。
如果各個服務都無法成為其數據的唯一所有者,那么就會導致多個服務需要訪問同一個私有數據庫的情況,即:產生了耦合問題。也就是說,我們最好不要在微服務之間直接共享數據,而是要通過API來實現。
2. 建立專門的團隊
微服務的主要優勢體現在云原生的應用上。這就意味著:任何更新,都需要相對快速且實時的發布。也就是說,任何停機都會給業務造成重大的損失。因此,如果您想進行線性且高效的擴展,就需要為每個微服務分配專門的開發團隊。
不過,光靠開發人員則很難掌控大型應用全面的端到端方案。我們需要擁有一支專業的團隊,在熟悉管理細微差別的基礎上,憑借轉換技術與開發效率,進而遵循微服務的各項優秀實踐。
3. 使用自動化進行獨立部署
為了將單體架構分解成為多個單獨的微服務,我們需要確保實現“構建和發布”的自動化結構。這樣不僅可以有助于減少總體的交付時間,而且可以加快發布的速度,進而改善部署的整個過程。可以說,有了自動化,微服務就能夠被妥善地封裝到容器中,并能夠有效地部署到包括云端在內的任何環境里。
4. 利用REST API的好處
開發人員在創建REST(Representational State Transfer,表示性狀態傳輸)API時無需安裝任何其他的軟件與庫,因此它為微服務提供了巨大的靈活性,數據也不再綁定到任何特定的方法或資源之上。通過REST API,微服務可以處理多種類型的調用,返回不同的數據格式,以及具有通過正確地實施超媒體,來修改結構的能力。
5. 了解文化的轉變
對于傳統的開發人員而言,他們習慣了端到端的測試環境。而隨著從單體架構遷移過渡到基于微服務的架構,他們必須突然從大的格局轉為關注一小部分的功能,而且管理層對此還充滿了期望。可見,這更大程度上是文化上的轉變,而不僅僅是開發技術上的變化。也就是說,開發人員需要理解和平衡公司愿景與自身工作方式的轉換。
6. 將遷移分解為多步驟
如果您過去從未處理過此類遷移,那么請您做好無法一蹴而就的準備。單體架構通常會涉及一個包含有存儲庫、部署、監控、以及其他復雜任務的協作網絡。因此,最好的方法之一就是:在暫時保留單體結構的基礎上,并行開發其他作為微服務的功能。一旦實現了新的服務,同時團隊也已對新的流程有所了解,我們就可以在厘清如何將舊的架構分解成為相關組件的基礎上,開始逐一進行遷移。
7. 在混合系統上構建分離系統
定義不同復雜部分之間的交互作用和過程,是微服務的關鍵設計原則與優秀實踐之一。因此,我們在遷移項目的初始階段,就應當考慮到拆分系統。每個拆分系統都應當對于正在構建的架構來說是唯一的。我們可以通過檢查單體結構,來持續監控各個組件的性能,以便了解各個組件之間的差異性,以及在微服務轉換時可能出現的問題。
我們可以參考如下監視過程的工具:
8. 隔離運行時(Runtime)進程
由于我們往往針對不同的垂直細分領域有著不同的流程,因此我們需要在運行時的級別上也具有一定的隔離性。例如,您可以通過某種形式的分布式計算,來分別實現容器化、事件架構、各種HTTP管理方法、服務網格和斷路器(circuit breakers)等。
9. 將正確的技術與正確的微服務相配對
正所謂殊途同歸。也許在您的團隊中,不同的成員會偏好使用不同的技術和編程語言來實現微服務,但是請盡量選用那些易于日后方便更改或替換的技術,來實現快速上手與直接迭代。當然,如果您并不確定哪種技術最適合自己的項目,那么請在決策過程中考慮以下方面:
- 可維護性。
- 容錯性。
- 可擴展性。
- 構建成本。
- 易部署性。
10. 考慮使用域驅動式設計(Domain-Driven Design)
域驅動式設計在某種程度上可以被理解為:應用于業務模型的面向對象編程。作為一種設計原則,它利用實踐規則和思想來表達面向對象的模型。簡單來說:我們需要圍繞著自己的業務領域來設計微服務。例如,Netflix等平臺就是使用不同服務器上的微服務,來進行內容交付和相關的跟蹤服務。
11. 區分專用資源和按需資源
如果您的主要目標是提供卓越的客戶體驗,那么請考慮將專用資源和按需資源區分開來。例如,針對某個電子商務平臺,我們可以通過構建其微服務和云架構,來實現快速且安全地在內部平臺和云環境之間,部署并轉移不同的工作負載。這樣不僅縮短了資源的響應時間,也使得遷移到云端的流量與資源更加直觀。
12. 治理對開源工具的依賴
對于開發人員來說,使用開源的微服務工具進行安全性、監控、調試、以及日志記錄,可謂“家常便飯”。但是,請確保不會以過分依賴某些庫和工具的方式,去干擾架構的性能或安全性。我們可以參考如下方面,同時根據實際的開發需求和所用到工具的類型,來實施各種適當的組織策略。
- 為已批準的軟件版本,建立正式的存儲庫。
- 了解開源軟件的供給關系。
- 建立處理異常的治理方案。
總結
綜上所述,從單體架構向微服務架構轉型的確極富挑戰性。上述設計原則與優秀實踐為您提供了參考的思路與方法,您可以在實際開發與遷移過程中,根據實際情況,按需采取逐步的方法,即:先從整體系統中的一小部分,而且是非關鍵的部分入手,通過厘清當前各個組件的工作原理,以及了解微服務的相關技術與文化,進而建立逐步的遷移計劃。同時,這樣也更容易獲取利益相關者,乃至組織層面上的支持。
原文標題:Break a Monolith to Microservices — 12 Best Practices and Design Principles,作者:Mitul Makadia
【51CTO譯稿,合作站點轉載請注明原文譯者和出處為51CTO.com】