從流暢交付的角度看,架構的目的是讓 DevOps 與 Team Topologies 能真正運作。實體建築的建築師(architect)為人們設計能滿足生活需求的空間;軟體架構師則必須打造一個讓組織能快速、可靠地交付軟體的應用架構。讓另外兩項要素生效,正是採用微服務的根本理由,沒有合適的架構,軟體交付不可能加速。
本節討論流暢交付對架構的兩大關鍵需求,以及為何巨石(monolithic)架構在某些情境下也能達成流暢交付,在另一些情境則會成為阻礙。
架構需求總覽#
談到架構,人們往往只想到可擴展性(scalability)、可用性(availability)、安全性(security)等使用者層面的特質。但軟體有個獨特之處——創造它的人也必須生活在它之內。今天做的設計決策,會直接影響明天開發的難易度。
讓單一團隊能夠快速、獨立地完成工作項目並部署到生產環境,而不需要與其他團隊協調,需要兩個關鍵架構特性:
- 鬆設計期耦合(loose design-time coupling)
- 快速、自動化的部署管線(fast, automated deployment pipeline)
第 5 章會深入討論完整的「流暢交付架構需求」,包括可演化性、可測試性、可觀測性等。本節先聚焦於最關鍵的兩項。
流暢交付需要鬆設計期耦合的架構#
DevOps 與 Team Topologies 都建立在一個前提上:團隊應該是自主(autonomous)的。團隊主要透過 X-aaS 互動方式與其他團隊往來,鮮少需要等其他團隊完工。要做到自主,光靠價值流團隊(stream-aligned team)的組織設計還不夠,還必須有鬆設計期耦合的架構。
鬆設計期耦合(第 4 章詳述)是一個極為重要的軟體屬性。在鬆耦合的架構下:
- 各團隊能改自己負責的部分,不需要其他團隊頻繁修改程式碼。
- 範例:Orders team 擁有 Order Management 模組,並使用 Consumers team 的 Consumer Management 模組。若兩者鬆設計期耦合,Orders team 修改自家模組時,多數情況下不需要與 Consumers team 同步協調。
- 反之,若架構緊耦合,單一變更就會牽動多個團隊,團隊之間陷入無止盡的會議與彼此等待,生產力雙雙下降。

Figure 1.5: For teams to be autonomous, the software elements they develop must be loosely design-time coupled
「設計期耦合」是設計變更時是否會牽動到其他模組或團隊的程度。它與執行期耦合(runtime coupling)是不同的概念。設計期耦合越鬆,團隊自主性越高。
流暢交付需要快速的部署管線#
第一項要求讓開發者容易修改程式碼,第二項要求則處理「程式碼推送或合併之後」會發生什麼事。要讓回饋迴圈夠短,推送/合併必須立刻觸發一條能快速編譯、測試、部署變更的部署管線。
部署管線是 DevOps 第一條原則的核心,負責把變更從開發者的筆電送上生產環境。DORA 指標中的前置時間(lead time),就是變更流經部署管線所花的時間,可拆解為兩部分:
- 等待時間(wait time):變更被排入佇列後,等到部署管線可以處理為止。等待時間和變更頻率以及處理時間成正比。
- 處理時間(processing time):管線實際編譯、測試、分析、部署所花的時間。
對多數 Java 應用而言,編譯時間可忽略,測試才是處理時間的大頭;部署時間則隨技術棧而異。

Figure 1.6: Fast flow requires a fast deployment pipeline that can handle the stream of changes
對於大型應用與大型團隊,等待時間與處理時間會同時拉長,形成雙重風險:測試套件越來越長,提交頻率又越來越高,部署管線就成為整個交付流程的瓶頸。
巨石架構也能支援流暢交付#
巨石(monolithic)應用指的是:
- 單一程式碼庫(codebase)
- 單一可部署單元(例如可執行 JAR 或 WAR 檔)
- 單一部署管線
巨石架構並非反模式,也不必然是「大泥球」(Big Ball of Mud,Brian Foote 與 Joseph Yoder 提出)。對許多應用而言,它是合理且能達成流暢交付的選擇。第 6 章介紹的「模組化巨石(Modular Monolith)」進一步改善傳統三層巨石,提升團隊自主性並縮短部署管線執行時間。
當應用與組織持續成長,即使是模組化巨石,也會碰到兩個問題:團隊自主性下降與部署管線成為瓶頸。
應用與組織成長後,團隊自主性會下降#
第一個問題:某些變更會同時影響很多團隊,難以推動。例子包括:
- 對大量模組共用的 API 做破壞性變更(breaking change)。
- 升級被廣泛使用的第三方函式庫,而升級涉及破壞性 API 變更。
- 升級 JVM 版本。
當 Orders team 要做這類變更,就得跟其他團隊協調——每個團隊各有優先順序與排程,協調成本極高,有時甚至實務上行不通,只能想辦法繞過,放棄真正乾淨的設計。

Figure 1.7: Even a loosely coupled monolith has changes that affect numerous teams (3rd party libs, JVM upgrades)
部署管線會變成瓶頸#
第二個問題:單一部署管線本身會成為瓶頸:
- 應用越大、測試越多,管線處理時間越長。
- 開發者越多、提交頻率越高,管線等待時間越長。
- 把多個變更批次處理可以縮短等待時間,但會違反 DevOps「縮小批次」的原則,也讓建置失敗或生產事故的排查更加困難。
更糟的是,巨石可能大到無法在開發者筆電上完整測試——依賴太多、跑太慢。開發者只好把變更推到部署管線或共用測試環境,失去本地的快速回饋。
對於大型應用與大型組織而言,克服自主性下降與部署管線變慢這兩個問題的方法,就是改採微服務架構。下一節將正式介紹微服務架構。