共用方式為


演進的設計

進化設計是持續創新的關鍵

所有成功的應用程式都會隨著時間變更,無論是修正錯誤、新增新功能、引進新技術,還是讓現有系統更具延展性和彈性。 如果應用程式的所有部分緊密結合,就很難將變更導入系統。 變更應用程式的某個部分可能會中斷另一個部分,或影響整個程式碼基底。

不是只有整合型應用程式會遇到這種問題。 應用程式可以被分解成多個服務,但仍然會出現緊密結合的情況,導致系統僵化且脆弱。 但是,當服務被設計為可演化時,團隊就可以予以創新並持續提供新功能。

微服務正變成實現演化設計的流行方法,因為它們能夠解決許多這裡列出的考量因素。

建議

強制實現高內聚和鬆散耦合。 如果服務提供的功能在邏輯上屬於同一類,就是內聚的。 如果變更一個服務不會變更其他服務,那麼這種服務就是鬆散耦合的。 高內聚通常表示變更某功能也需要連帶著變更其他相關功能,而所有這些相關功能都位於同一個服務中。 如果您發現更新服務需要對其他服務進行協調更新,則可能表示該服務不是內聚的。 領域驅動設計 (DDD) 的其中一個目標是識別這些界限。

封裝領域知識。 當用戶端取用服務時,不應由用戶端承擔強制執行網域商務規則的責任。 相反地,該服務應該封裝所有屬於其責任範圍內的所有領域知識。 否則,每個用戶端都必須強制執行商務規則,結果導致領域知識分散在應用程式的不同部分。

使用非同步傳訊。 非同步傳訊是將訊息產生者與取用者分離的方法。 產生者不依賴取用者對訊息作出回應或採取任何特定動作。 使用發佈/訂閱架構時,產生者甚至可能不知道誰正在取用訊息。 新的服務可以輕鬆地取用訊息,而不需要對產生者進行任何修改。

請勿將領域知識建置至閘道。 閘道在微服務架構中很有用,例如要求路線規劃、通訊協定轉譯、負載平衡或驗證。 不過,閘道應限制在這類基礎結構功能中。 它不應該實作任何領域知識,以避免形成高度的相依性。

公開開放介面。 避免建立位於服務之間的自訂轉譯層。 相反地,服務應該使用定義完善的 API 合約來公開 API。 API 應該經過版本設定,讓您可以發展 API,同時維持回溯相容性。 如此一來,您可以更新服務,而無需協調更新所有相依於它的上游服務。 公開的服務應該透過 HTTP 公開 RESTful API。 後端服務可能會基於效能的考量使用 RPC 樣式的傳訊通訊協定。

針對服務合約進行設計和測試。 當服務公開定義完善的 API 時,您可以針對這些 API 進行開發和測試。 如此一來,您就可以開發和測試個別服務,而不需要啟動所有相依於其上的服務。 (當然,您仍會對實際服務執行整合和負載測試。)

使用適應度函式。 適應度函式會測量結果,以查看其離最佳解決方案更近或更遠。 適應度函式有助於保護架構特性,不會因時間而變動。 適應度函式是任何提供架構特性客觀完整性評估的機制。 評量可能包含各種機制,例如計量、單元測試、混沌工程等等。 例如,架構師可能會將頁面載入時間識別為重要的特性。 接著,工作負載應該有一個適應度函式來測試頁面載入時間,並在持續整合時執行測試。

將基礎結構從領域邏輯中抽離。 請勿讓網域邏輯與基礎結構相關的功能混合在一起,例如傳訊或持續性。 否則,變更網域邏輯需要更新基礎結構層,反之亦然。

將跨領域關注點卸載到個別的服務。 例如,如果數個服務需要驗證要求,您可以將此功能移至它自己的服務。 然後,您可以藉由新增驗證流程來發展驗證服務,而不需觸及任何使用它的服務。

獨立部署服務。 當 DevOps 小組可以獨立於應用程式中的其他服務來部署單一服務時,更新可能會更快且安全地進行。 錯誤修正和新功能可以更定期地推出。 設計應用程式和發佈過程,以支援獨立更新。