軟體架構的優劣直接影響組織的擴充套件能力。隨著業務發展,系統複雜度提升,單體架構的瓶頸日益顯現,微服務架構成為解決方案。然而,微服務的匯入並非一蹴可幾,需要考量團隊協作、功能劃分、釋出流程等多重因素。組織結構與軟體架構的關聯性也需要重視,避免形成分散式大泥球。透過領域驅動設計的 EventStorming 工作坊,可以有效地梳理業務流程、劃分領域邊界,並將軟體元件與業務領域對映,釐清團隊職責,降低認知負擔。此外,KPI 對映可以將業務目標與軟體架構對齊,確保架構演進方向與組織策略一致。
私有建構的成本與實踐度量
開發者最初對強化本地環境驗證的反對意見,主要在於它對生產力和提交頻率的影響,因為這需要他們花更多時間維護本地環境。
這是一個合理的論點。然而,這裡要強調的是,執行私有建構所付出的努力,仍然遠遠少於持續進行主幹穩定化、QA來回測試以及票務管理的成本。這是因為,正如大量文獻所證明的那樣,從缺陷引入到被發現的時間越長,修復它的成本就呈指數級上升。此外,手動整合驗證應該是暫時的。整個團隊應該迅速致力於自動化那些在私有建構過程中重複進行的活動。手動測試階段應該接近簡單和有針對性的「煙霧測試」,並且應該最佳化以保持盡可能低的成本和簡單性。
實踐中的度量指標
本章的最後一節提供了一些如何解讀前一節提出的度量的例子。
高反饋時間、高可避免整合問題、低主幹穩定時間
這是本文中最常見的組合情況。使用「反饋時間」度量與「可避免的整合問題」結合,經常能提示一個可能的原因。實際上,「可避免的整合問題」指標較高,支援了反饋生命週期較長的假設,因為大多數驗證被轉移到自動化和QA。「主幹穩定時間」較低,與「可避免的整合問題」較高相關,可能表明錯誤在本地環境中未被發現的情況下被提交到主幹。
為了確認或排除這種假設,你可以:
- 在回顧會議中分析報告的整合問題的「可避免性」。
- 確保團隊中的每個人都可以在本地環境中執行完整的測試。
- 讓團隊分享一系列最小功能測試,在提交前手動或自動執行。
- 要求團隊在執行私有建構時更加自律。
- 反覆迭代。
def analyze_integration_issue(evitable_integration_issues):
# 分析可避免的整合問題
if evitable_integration_issues > 0.5:
print("需要改進整合測試")
else:
print("整合測試良好")
# 使用範例
analyze_integration_issue(0.7)
#### 內容解密:
此程式碼範例定義了一個函式 `analyze_integration_issue`,用於分析可避免的整合問題的嚴重程度。根據輸入的 `evitable_integration_issues` 值,函式會輸出是否需要改進整合測試的建議。這樣的分析有助於團隊快速識別並解決整合問題,提高整體開發效率。
#### 低反饋時間、高可避免整合問題、低主幹穩定時間
「反饋時間」是一個定性度量,因此有時會存在偏差。如果「可避免的整合問題」指標較高,則支援上述假設。如果是這種情況,那麼情況與前一種情況相同。
這種情況也可能發生在QA團隊成員高效處理大量工作量的情況下,彌補了團隊其他成員本地驗證的低效率。在這種情況下,要求團隊其他成員更加自律。
#### 高反饋時間、低可避免整合問題、低主幹穩定時間
由於「反饋時間」是一個間接度量,需要進一步分析。其他兩個度量的低值可能表明兩種截然不同的情況。
第一種情況可能是整個QA流程不盡人意,錯誤在交付流程的很晚階段才被發現。這可能是由於整體檢測流程效率低下,或是自動化測試不足,或兩者兼有。為了排除這種假設,需要檢視其他度量指標,如客戶滿意度和每個迭代引入的錯誤數量。
第二種可能的情況是,你擁有高主幹穩定性和適當的流程,但官僚主義、DevOps團隊的排程和QA團隊的工作過載都在導致自動化和QA反饋的延遲。處理這種情況的方法是快速消除開發、DevOps和QA團隊之間的障礙,因為開發團隊在保持主幹穩定性方面已經非常高效。
```mermaid
graph LR;
A[開始] --> B{錯誤是否被發現?};
B -->|是| C[修復錯誤];
B -->|否| D[繼續開發];
C --> E[驗證修復];
E --> D;
圖表翻譯: 此圖表呈現了一個簡化的錯誤處理流程。首先,開發從「開始」點啟動,接著檢查錯誤是否被發現。如果錯誤被發現,則進入修復階段,修復完成後進行驗證。驗證透過後繼續進行開發;若錯誤未被發現,則直接進入繼續開發的階段。
低可避免整合問題和高主幹穩定時間
這種情況經常發生在很多錯誤被提交到主幹,但並未在整合/QA環境中顯現的情況下。可能是某些團隊成員花了很多時間修復錯誤,而其他人則在執行私有建構時不夠自律和主動。如果發現團隊在保持主幹穩定性方面的努力存在顯著不平衡,可以利用團隊內部回顧流程來解決這個問題。
你可能會想知道為什麼這種組合沒有提到「反饋時間」。如果「反饋時間」的值較高,則按照前一段落中分析交付流程中的低效率的方式進行分析。
軟體架構在組織擴充套件中的核心作用
隨著數位公司的快速發展,軟體架構在組織擴張過程中扮演著至關重要的角色。本文將探討軟體架構如何影響組織的擴充套件,以及如何透過有效的架構決策來支援業務目標。
問題的提出
在一家名為YourFinFreedom的金融科技公司中,產品工程部門希望加快交付速度並提高產品品質。該公司正經歷著快速增長,但目前的系統架構無法滿足日益增長的需求,導致服務可用性問題頻發。為瞭解決這些問題,公司決定從單體架構轉向微服務架構。
單體架構 vs 微服務架構
單體架構和微服務架構是兩種不同的架構風格,它們在業務邏輯的組織方式上存在著本質的區別。單體架構將所有功能集中在一個單一的應用程式中,而微服務架構則將功能分解為多個獨立的服務。
graph TD A[單體架構] -->|優點|> B[易於開發和測試] A -->|缺點|> C[擴充套件性差] D[微服務架構] -->|優點|> E[高擴充套件性] D -->|缺點|> F[複雜性高]
圖表翻譯: 此圖示展示了單體架構和微服務架構的優缺點對比。單體架構在開發初期具有優勢,但隨著系統擴充套件,其劣勢逐漸顯現。微服務架構則提供了更好的擴充套件性,但同時也引入了更高的複雜度。
Conway定律的影響
軟體架構通常反映了公司的組織結構和團隊間的溝通方式。這種現象被稱為Conway定律。根據Conway定律,如果軟體架構不是經過精心設計的,那麼它將會反映出組織的溝通結構。
組織結構對軟體架構的影響
在YourFinFreedom的案例中,產品工程部門決定採用微服務架構,以提高開發效率和產品品質。然而,在實施過程中,團隊發現新的架構並未完全滿足業務需求。
有效的軟體架構決策
為了使軟體架構有效地支援業務目標,公司需要採取以下措施:
- 定義清晰的架構目標:根據業務需求和技術能力,定義軟體架構的目標和原則。
- 選擇合適的架構風格:根據業務需求和技術能力,選擇合適的架構風格,例如微服務架構或單體架構。
- 建立有效的溝通機制:建立有效的溝通機制,確保團隊間的協作和溝通。
程式碼範例:微服務架構中的服務註冊
// 服務註冊範例
public class ServiceRegistry {
private Map<String, ServiceInstance> services = new HashMap<>();
public void registerService(String serviceName, ServiceInstance instance) {
services.put(serviceName, instance);
}
public ServiceInstance getService(String serviceName) {
return services.get(serviceName);
}
}
內容解密:
此程式碼範例展示了微服務架構中的服務序號產生器制。ServiceRegistry
類別負責註冊和管理服務例項,提供服務發現功能。透過這個機制,微服務可以動態地註冊和發現彼此,提高了系統的靈活性和可擴充套件性。
隨著業務的持續增長,軟體架構需要不斷演進以滿足新的需求。未來,YourFinFreedom可以考慮採用更先進的技術,如容器化和服務網格,以進一步提高系統的可擴充套件性和可靠性。
graph LR A[單體架構] -->|演進|> B[微服務架構] B -->|進一步演進|> C[容器化] C -->|服務網格|> D[服務網格架構]
圖表翻譯: 此圖示展示了軟體架構的演進路徑。從單體架構到微服務架構,再到容器化和服務網格,軟體架構不斷演進以滿足業務需求和技術發展。
透過有效的軟體架構決策和持續的技術創新,YourFinFreedom可以實作業務的快速增長和技術的持續領先。
軟體架構在企業擴張中的關鍵角色:從大泥球到微服務的挑戰
軟體架構在企業發展過程中扮演著至關重要的角色。良好的架構設計能夠支援業務快速迭代與擴張,而不良的架構則可能成為企業發展的絆腳石。本文將探討軟體架構如何影響企業擴張,並以「YourFinFreedom」公司為案例,分析其從單體架構轉向微服務過程中遇到的挑戰,以及如何透過改進軟體架構來提升企業的競爭力。
大泥球(Big Ball of Mud)現象
軟體系統中的「大泥球」是指那些結構混亂、缺乏清晰設計、且維護困難的系統。這種系統通常是由於快速迭代開發、技術債務累積或架構設計不當所導致。Brian Foote 和 Joseph Yoder 在 1999 年首次提出了這個概念,用來描述那些「雜亂無章、蔓延、邋遢、像膠帶和鐵絲捆綁在一起的、類別似於義大利麵條程式碼的叢林」[2]。
大泥球的特徵
- 結構混亂:缺乏清晰的架構設計,程式碼組織混亂。
- 技術債務累積:由於快速開發或不當設計導致的技術問題累積。
- 維護困難:由於系統複雜度高,維護成本增加。
分散式大泥球(Distributed Big Ball of Mud)
當企業將單體架構轉向微服務架構時,如果沒有適當的設計和治理,就可能形成分散式大泥球。這種架構不僅繼承了單體架構的混亂,還增加了分散式系統的複雜性,使得系統更加難以理解和維護。
案例分析:YourFinFreedom 的挑戰
YourFinFreedom 是一家金融科技公司,最初採用單體架構來支援其業務。然而,隨著業務的快速增長,公司決定將架構轉向微服務,以提高開發效率和系統的可擴充套件性。然而,在實施微服務架構後,公司卻遇到了諸多挑戰。
挑戰一:釋出協調困難
由於微服務眾多,各團隊需要協調才能完成新功能的釋出,這大大增加了釋出的複雜度和時間成本。
// 示例:微服務之間的協調
public class ReleaseCoordinator {
public void coordinateRelease(List<Service> services) {
// 協調各微服務的釋出流程
for (Service service : services) {
service.release();
}
}
}
#### 內容解密:
在上述程式碼中,ReleaseCoordinator
類別負責協調多個微服務的釋出流程。透過迴圈遍歷所有服務,並呼叫每個服務的release()
方法,實作了釋出流程的自動化協調。這種設計可以有效減少人工干預,提高釋出的效率和可靠性。
挑戰二:功能重疊
不同微服務之間存在功能重疊,導致團隊難以明確各自的職責範圍,增加了維護的困難度。
-- 示例:資料函式庫中的功能重疊
SELECT * FROM user_data WHERE condition = 'A';
-- 在不同的微服務中,可能存在相同的查詢邏輯
#### 內容解密:
在資料函式庫查詢中,不同的微服務可能會執行相同的查詢邏輯,如查詢user_data
表。這種功能重疊不僅增加了系統的複雜度,也使得維護變得更加困難。為瞭解決這個問題,可以考慮將共用的查詢邏輯抽象成獨立的服務或函式,以減少重複程式碼。
挑戰三:優先順序頻繁變更
公司的優先順序頻繁變更,導致團隊的工作方向不斷調整,增加了開發的不確定性和浪費。
# 示例:任務優先順序的動態調整
def adjust_priority(tasks, new_priority):
for task in tasks:
task.priority = new_priority
return tasks
#### 內容解密:
在上述Python程式碼中,adjust_priority
函式用於動態調整任務的優先順序。透過遍歷所有任務並更新其優先順序,可以快速回應業務需求的變化。然而,頻繁的優先順序變更可能會導致團隊的工作效率下降,因此需要有效的任務管理和溝通機制來減少這種影響。
解決方案:引入度量指標和清晰的架構邊界
為瞭解決上述挑戰,Anna 提出了引入度量指標和清晰的架構邊界的解決方案。透過定義清晰的 KPI(如每月活躍使用者數,MAU),並將軟體架構與業務目標對齊,可以更好地引導開發團隊的工作方向,提高開發效率和系統的可維護性。
graph LR A[業務目標] --> B[軟體架構] B --> C[度量指標] C --> D[開發團隊] D --> E[業務成果]
圖表翻譯:
此圖示展示了業務目標、軟體架構、度量指標和開發團隊之間的關係。業務目標指導軟體架構的設計,而軟體架構透過度量指標來評估其有效性。開發團隊根據度量指標進行調整,以最終實作業務目標並取得良好的業務成果。
隨著技術的不斷進步,軟體架構將繼續演進。企業需要持續關注新的技術趨勢和最佳實踐,以保持其競爭力。同時,透過持續最佳化和改進軟體架構,企業可以更好地支援業務發展,實作長期的成功。
程式碼最佳化示例
// 最佳化後的程式碼示例:使用設計模式提高程式碼可維護性
public class ServiceFactory {
public static Service createService(String type) {
if (type.equals("A")) {
return new ServiceA();
} else if (type.equals("B")) {
return new ServiceB();
}
// 其他型別服務的建立邏輯
}
}
#### 內容解密:
在上述最佳化後的Java程式碼中,使用了工廠設計模式來建立不同型別的服務。透過ServiceFactory
類別,可以根據輸入的型別引數動態建立相應的服務例項。這種設計提高了程式碼的可擴充套件性和可維護性,使得新增服務型別變得更加容易。
從隨意應付到刻意經營:軟體架構在組織擴充套件中的關鍵角色
軟體架構與組織使命的連結
在探討軟體架構時,我們必須先了解組織的使命(mission)和關鍵績效指標(KPIs)。軟體架構需要與這些元素緊密相連。如果KPIs定義不清晰或團隊成員對其理解不足,軟體架構就會與實際目標脫節。這正是康威定律(Conway’s Law)的體現,說明瞭溝通如何影響軟體架構。軟體架構存在的目的是在不同軟體元件之間建立清晰的責任界限,並定義它們之間的互動方式。它不僅要符合組織當前的各種限制(如技術、人員、法規、市場等),還要使企業保持敏捷。
刻意決策的重要性
Anna 在回顧利益相關者的需求和產品的當前架構狀態時,發現了一個模式。每個人都在「盡力而為」的基礎上工作,試圖滿足所有軟體需求。她意識到,軟體架構的一個重要品質在團隊中缺失:他們的決策應該是刻意的。
EventStorming:協同探索複雜業務領域的靈活工作坊格式
Anna 從不同的軟體社群中瞭解到 EventStorming,這是一種「協同探索複雜業務領域的靈活工作坊格式」,在領域驅動設計(Domain-Driven Design)社群中被廣泛使用,用於視覺化流程和推理邊界及指標。EventStorming 首先給出跨不同責任領域的大局觀,然後邀請來自不同領域的專家分享他們的操作方式。Anna 決定嘗試並學習如何推動這樣的工作坊。
EventStorming 工作坊的實施
Anna 聚集了來自組織不同領域的人員,舉行了一次大圖景 EventStorming 工作坊。該小組繪製了目前的業務流程,專注於業務事件的流程和順序,並建立邊界以顯示工作型別變化或流程結束的地方。他們的輸出結果視覺化了這一流程,以及新興的領域及其邊界。
graph LR A[開始] --> B[流程1] B --> C[流程2] C --> D[結束] D --> E[新興領域1] D --> F[新興領域2]
圖表翻譯: 此圖示展示了業務流程的流程圖,其中包括了新興領域的劃分。每個節點代表不同的階段,箭頭表示流程的推進方向。
工作坊的成果
工作坊的輸出結果類別似於圖6-6。小組視覺化了關鍵的領域事件(小方塊)在新興領域之間。瞭解為何建立軟體(和軟體架構)至關重要,因此 Anna 的第一步是讓小組識別每個領域的業務邏輯。
public class DomainEvent {
private String eventId;
private String eventType;
public DomainEvent(String eventId, String eventType) {
this.eventId = eventId;
this.eventType = eventType;
}
public String getEventId() {
return eventId;
}
public String getEventType() {
return eventType;
}
}
內容解密:
這段程式碼定義了一個名為 DomainEvent
的類別,用於表示領域事件。它包含兩個屬性:eventId
和 eventType
,分別代表事件ID和事件型別。建構函式用於初始化這兩個屬性,並提供了 getter 方法來存取這些屬性值。這樣的設計使得領域事件能夠被明確地表示和處理。
軟體元件與新興領域的對映
在工作坊的幫助下,小組將當前的軟體元件對映到他們的大圖景 EventStorming 輸出(圖6-7)。在工作的過程中,顯而易見的是,流程和實作之間存在不匹配,這解釋了為什麼軟體架構已經漂移成一個分散的大泥球。他們還映射了這些元件的所有權,並且在那個時候,Anna 證實了她對團隊高認知負擔來源的懷疑。
對映的意義
將當前的軟體元件(微服務、單體或其他形式)對映到新興領域上,使小組能夠評估當前的狀況,並理解為什麼 YourFinFreedom 很難發展其架構。他們可以看到軟體元件在新興領域之上,以及這些元件的所有權(為了簡單起見,圖6-7中只顯示了A隊的所有權)。有了這一點,他們就可以推理團隊的認知負擔。Anna 明白,擁有分散在整個領域的不同軟體元件對於任何團隊來說都是一個挑戰:他們需要來自不同領域的知識來理解構建和架構軟體的目的。
KPI 的對映與討論
Anna 希望在結束工作坊之前再採取一個步驟:對映領域的 KPIs,利用室內收集的知識(圖6-8)。小組愉快地進行了這項工作,領域專家闡述了為什麼某些 KPIs 對他們的領域是相關的。他們分享了更多以前只在組織中隱含存在的知識。每個人都對工作坊的結果感到滿意,並對在短時間內獲得的大量資訊感到驚訝。
KPI 對映的價值
大圖景 EventStorming 使組織能夠增強他們原有的符號系統,並捕捉特定背景或案例所需的資訊。它可以解鎖對當前系統狀態和 KPI 或指標相關性的重要知識和反思。對映 KPIs 和指標並討論其目的可以在組織的各個層級上解鎖有力的對話。
未來,YourFinFreedom 可以繼續利用 EventStorming 這種協同工作的方式,不斷最佳化和調整其軟體架構,以更好地支援業務目標。同時,透過持續的溝通和知識分享,組織可以保持敏捷,應對不斷變化的市場和技術環境。
graph TD A[軟體架構] --> B[業務目標] B --> C[EventStorming] C --> D[協同工作] D --> E[持續最佳化]
圖表翻譯: 此圖示展示了軟體架構與業務目標之間的關係,以及 EventStorming 在協同工作和持續最佳化中的作用。每個節點代表不同的概念,箭頭表示它們之間的關聯。