很多公司,技術經常遇到這樣的場景:
1)硬體公升級,要換一台高配機器
2)網路重新規劃,若干伺服器要調整機架
3)伺服器當機,要重新部署恢復服務
由a的調整(資料庫換ip),配合修改和調整的卻是bcde(改配置重啟),bcde內心非常的鬱悶:明明換ip的是你,憑什麼配合重啟的卻是我?
根本上,這是乙個「架構耦合」的問題,是乙個架構設計上「反向依賴」的問題,本文將討論的是架構設計中常見的「反向依賴」的設計,以及對應的優化方案,希望對大夥有所啟示。
方**:
變動方是a,配合方卻是bcde
(或者說需求方是a,改動方確是bcde)
想想「換ip的是你,配合重啟的卻是我」更好理解。
如果系統中經常出現了這類情況,就是「反向依賴」的特徵,往往架構上有優化的空間。
三個服務s1/s2/s3,通過乙個公共的庫biz.jar來實現一段業務邏輯,s1/s2/s3其實間接通過biz.jar耦合在了一起,乙個業務s1修改一塊公共的**,導致影響其他業務s2/s3,架構上是不合理的。
優化方案1:業務垂直拆分
如果biz.jar中實現的邏輯「業務特性」很強,可以拆分為biz1.jar/biz2.jar/biz3.jar,來對s1/s2/s3進行解耦。這樣的話,任何業務的改動,影響範圍只是自己,不會影響其他人。
優化方案2:服務化
如果biz.jar中實現的邏輯「業務共性」很強,可以將biz.jar優化為biz.service服務,來對s1/s2/s3進行解耦。服務化之後,相容性能更好的通過介面自動化回歸測試來保證。
基礎服務的抽象,本身是一種共性聚焦,是系統解耦常見的方案。
服務化是解決「業務共性」元件庫導致系統耦合的常見方案之一,但如果服務化不徹底,service本身也容易成為業務耦合點。
典型的服務化不徹底導致的業務耦合的特徵是,共性服務中,包含大量「根據不同業務,執行不同個性分支」的**。
switch (biz-type)
case biz-1 : exec1
case biz-2 : exec2
case biz-3 : exec3
…在這種架構下,biz-1/biz-2/biz-3有個性的業務需求,可能導致修改**的是共性的biz-service,使其成為研發瓶頸,架構上也是不合理的。
優化方案:業務特性**上浮,業務共性**下沉,徹底解耦
把swithc case中業務特性**放到業務層實現,這樣biz-1/biz-2/biz-3有個性的業務需求,公升級的是自己的業務系統。
《究竟什麼時候該使用mq》一文中有一類業務場景,訊息傳送方不關注訊息接收方的執行結果,如果採用呼叫的方式來實現通知,會導訊息傳送方和訊息接收方耦合。
如何新增訊息接收方biz-4,會發現修改**的是訊息傳送方,新增乙個對biz-4的呼叫,極不合理。
優化方案:通過mq實現解耦
訊息傳送方upper將訊息發布給mq,訊息接收方從mq去訂閱,任何新增對訊息的消費,upper都不需要修改**。
即「緣起」中舉的例子,下游服務換ip,可能導致多個服務呼叫方修改配置重啟。上下游間接的通過ip這個配置耦合在了一起,架構不合理。
優化方案:通過內網網域名稱而不是ip來進行下游連線
如果在配置中使用內網網域名稱來進行下游連線,當下游服務或者資料庫更換ip時,只需要運維層面將內網網域名稱指向新的ip,然後統一切斷原有舊的連線,連線就能夠自動切換到新的ip上來。這個過程不需要所有上游配合,非常帥氣,強烈推薦!
這次不是換換ip這麼簡單了,下游服務提供方原來是集群(ip1/ip2/ip3,當然,上游配置的是內網網域名稱),現在集群要擴容為(ip1/ip2/ip3/ip4/ip5),如果沒有特殊的架構設計,上游往往需要修改配置,新增擴容後的節點,再重啟,導致上下游耦合。
這類case,大夥有什麼好的方案解耦麼?
技術細節,且聽下回分解。
如何發現系統架構中不合理的「反向依賴」設計?
回答:(1)變動方是a,配合方卻是bcde
(2)需求方是a,改動方確是bcde
想想「換ip的是你,配合重啟的卻是我」,此時往往架構上可以進行解耦優化。
常見反向依賴及優化方案?
(1)公共庫導致耦合
優化一:如果公共庫是業務特性**,進行公共庫垂直拆分
優化二:如果公共庫是業務共性**,進行服務化下沉抽象
(2)服務化不徹底導致耦合
特徵:服務中包含大量「根據不同業務,執行不同個性分支」的**
優化方案:個性**放到業務層實現,將服務化更徹底更純粹
(3)notify的不合理實現導致的耦合
特徵:呼叫方不關注執行結果,以呼叫的方式去實現通知,新增訂閱者,修改**的是發布者
優化方案:通過mq解耦
(4)配置中的ip導致上下游耦合
特徵:多個上游需要修改配置重啟
優化方案:使用內網網域名稱替代內網ip,通過「修改dns指向,統一切斷舊連線」的方式來上游無感切換
(5)下游擴容導致上下游耦合
特性:多個上游需要修改配置重啟
架構設計開篇 架構設計的目標與衡量
程式設計即設計,即架構。架構,這個詞比較神秘,以致於很多程式設計師望而卻步,以為要什麼了不得的本事。確實的,架構設計是一種高遠的目標,但千里之行,始於足下。架構的目標是什麼呢?實現所需服務 架構,致力於以更低成本 更高效率 更高質量地實現所需服務。架構,是兼顧質量 效率與成本的魔法。但架構並不研究如...
軟體架構設計系列總結
出處 架構引用 維基百科 軟體體系結構是構建 計算機軟體 實踐的基礎。與建築師設定建築專案的設計原則和目標,作為繪圖員畫圖的基礎一樣,乙個 軟體架構師 或者系統架構師 陳述軟體構架以作為滿足不同客戶需求的實際系統設計方案的基礎。從和目的 主題 材料和結構的聯絡上來說,軟體架構可以和建築物的 架構相比...
架構設計之依賴倒置 控制反轉與依賴注入
名詞解釋 依賴 一種模型元素之間的關係的描述。例如類a呼叫了類b,那麼我們說類a依賴於類b。耦合 一種模型元素之間的關係的描述。例如類a呼叫了類b或類b呼叫了類a,那麼我們說類a與類b有耦合關係。耦合度 模型元素之間的依賴程度的量化描述。控制 一種模型元素之間的關係的描述。例如類a呼叫了類b,那麼我...