進化的設計

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

所有成功的應用程式會隨著時間變更,無論是要修正錯誤、加入新功能、納入新技術,或讓現有的系統更可擴充且可復原。 如果應用程式的所有部分都緊密結合,會變得難以在系統中引入變更。 應用程式的一個組件中的變更可能會破壞另一個組件,或導致變更在整個程式碼基底中起漣漪。

此問題並不限於整合型應用程式。 可以將應用程式分解成服務,但仍呈現將導致系統僵化和脆弱的那種緊密結合。 但是,當服務的設計要演化時,小組可以創新和持續提供新功能。

微服務正成為達到演化設計的一種常見方式,因為它們可處理此處所列的許多考量。

建議

強制高一致性和鬆散結合。 如果服務提供邏輯上同屬的功能,則服務具凝聚力。 如果您可以變更一項服務,而不需要其他變更,則服務是鬆散結合。 高融合通常表示某個函式中的變更需要其他相關函式的變更,其中所有相關函式都位於一個服務中。 如果您發現更新服務時需要對其他服務協調更新,它可能是您的服務不具凝聚力的徵兆。 網域導向設計 (DDD) 的目標之一是識別這些界限。

封裝網域知識。 當用戶端取用服務時,強制網域的商務規則的責任應不會在落在用戶端上。 相反地,服務應該封裝屬於其責任的所有網域知識。 否則,每個用戶端必須強制商務規則,而且會獲得到分散在應用程式不同部分的網域知識。

非同步傳訊入門。 非同步傳訊是從使用者中分離訊息產生者的方式。 產生者不相依於取用者回應訊息,或採取任何特殊動作。 利用 pub/sub 架構,產生者可能甚至不知道正在使用訊息的是誰。 新服務可以輕鬆地使用訊息,而不需對產生者進行任何修改。

請勿將網域知識建置到閘道。 閘道在微服務架構中,對於要求路由、通訊協定轉譯、負載平衡或驗證之類可能很有用。 不過,閘道應該限制在這類基礎結構功能。 它不應該實作任何網域知識,以避免成為大量相依性。

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

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

從網域邏輯抽取出基礎結構。 不要將網域邏輯與基礎結構相關的功能 (例如傳訊或持續性) 混合。 否則,網域邏輯中的變更將需要對基礎結構層進行更新,反之亦然。

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

獨立部署服務。 當 DevOps 小組可以部署與應用程式中其他服務無關的單一服務時,更新可以更快速且安全地進行。 錯誤修正和新功能可以以更一般的頻率推出。 設計應用程式和發佈程序以支援獨立更新。