這是鼎叔的第一百一十四篇原創文章。行業大牛和剛畢業的小白,都可以進來聊聊。
歡迎關注本專欄和微信公眾號《敏捷測試轉型》,星標收藏,大量原創思考文章陸續推出。本人新書《無測試組織 - 測試團隊的敏捷轉型》已出版(機械工業出版社),文末有連結。
持續交付和軟體架構的演進是相輔相成的,互相影響,一同發展。
部分觀點參考 Eberhard Wolff 的《持續交付實踐》一書。
從一開始就引入持續交付
如果我們從專案最開始就引入持續交付,即從技術選型和系統架構設計時就開始考慮持續交付了,就能夠一步步完善流水線建設。從一開始就選擇更容易自動化的基礎設施元件技術,並能控制好程式配置和基礎設施搭建的複雜度。讓應用程式能夠即時最佳化。
技術選型會影響持續交付的方方面面,比如程式語言會影響編譯器的速度,進而影響持續交付流水線的耗時,程式設計的決策也會影響流水線的交付質量。
反過來,我們從持續交付的需求來調整技術和架構決策,就會使得流水線的設立更簡單。
大多數現有專案在設計時並沒有考慮持續交付,持續交付是基於快速反饋和精益理論的,價值流對映對於實現快速反饋的理想狀態很有幫助,比如,很多程式碼變更都在等待手工測試,就表明價值流中出現了等待的佇列瓶頸,有待我們逐步去消除。
持續交付和技術協同
持續交付可以讓技術組織主動使用多元化技術,讓開發和運維有協同效應。而傳統技術組織的風格則是相反的,即限制技術的種類數量。
因為不同專業崗位的技術團隊會在同一個流水線上工作(開發人員,測試人員,運維人員),跨越了組織邊界的協作,更容易消除跨團隊的不信任感,哪怕部門牆依然存在。
應用程式的可重複部署和可重複驗證,帶來了更高的質量,也加強了多角色團隊之間的彼此信任。
持續交付和軟體架構
軟體架構包含各個軟體元件和它們之間的關係和特徵,元件的技術實現是軟體架構要呈現的基本決策。一個軟體系統非常複雜,只有合理劃分出多個元件,開發人員才可以逐一理解和更改它們,元件化互相之間的關係才容易被理解。
元件的劃分完全是領域職責驅動的,和具體技術無關,我們需要隨著各個功能來調整結構,以支援最終實現的服務目的。通常,我們的開發者在架構定義中容易丟失這個目標,讓技術悄然走上前臺,而持續交付實踐有利於避免這個問題。
元件可以是類、包或者部署單元,它們的技術實現是必要的,但和領域功能拆分的決策無關。每次元件被修改時,整條持續交付流水線都會被執行和測試,最終被驗收透過,完整的流水線執行可以暴露必須透過其他依賴元件執行才能呈現的問題。
複雜架構團隊總是為介面各版本的聯調傷腦筋,我們可以參考伯斯塔爾健壯性法則,讓所有元件 “嚴於律己,寬以待人”,就是元件被呼叫時能容忍各種錯誤,呼叫其他元件時老老實實遵循指南,系統聯調的互操作性就能得到保障。
當元件更新期間被其他元件呼叫,系統處理元件執行中斷也應該有容錯設計:使用預設值,或者降級服務給一個妥協結果,或者使用斷路器避免進一步的呼叫。這種不傳遞中斷的 “反脆弱” 機制使得整個系統更有彈性。
對於持續交付來說,如果可能的話,元件在記憶體中不應該具有任何的狀態,這種狀態應該儲存在外部系統如資料庫和快取中。
持續部署如何處理資料庫也是一個挑戰,如果軟體中的資料結構被修改,資料庫中的格式也必須被修改,例如新增行或者刪除列。
資料庫的變更通常涉及大量資料,導致回滾風險大,我們必須找到一個保持資料庫穩定的方案,重新部署和修改後的資料庫一起工作的元件,資料庫本身也可以看作一個元件,也要遵循新舊版本訪問的健壯性,等到下一次再更新資料時才徹底刪除舊版本的痕跡。
每個元件也有自己的資料庫或者資料庫模式,資料庫變更如果只需要和單個元件協調,就大幅降低了變更風險。
持續交付和微服務
微服務和持續交付更加有廣泛的協同作用。微服務就是將系統模組化,從而讓每個微服務可以獨立部署。眾多微服務一起構成了整個系統,而它們各自可以提供一部分使用者介面,也可以呼叫外部系統的服務,把整個系統變成 HTML 連結的組合產品。
微服務架構天然適合持續交付:
流水線可以被劃分為多個獨立可部署單元,簡化建立成本,每次部署只變動一個微服務,風險大幅降低。
微服務之間可以透過適當的介面通訊,變更介面時可以分步驟進行:讓微服務先同時支援新舊版本,一段時期後,刪除舊版本介面。
微服務肯定要有容錯設計和彈性,當其他微服務停機時,它仍然能夠工作。微服務也有自己的資料庫,減少了資料庫的更新問題。
因此,微服務不但支援持續交付系統的架構需求,也很容易補充遺留系統,把費時費力的升級工作逐步完成。
由於可部署的工件太多,手動干預的方式太費時費力,所以持續交付對微服務架構也是至關重要的。
持續交付和特性團隊(feature team)
微服務和持續交付,更適合敏捷團隊,支援個體責任制和自組織。
微服務允許技術上的自由,甚至不限制平臺和程式語言,它幫助團隊降低和其他特性團隊的協調成本,而單獨的持續交付流水線還可以讓特性團隊完全獨立地把軟體釋出到生產環境,讓團隊獲益。
真正的特性團隊能讓大型產品能以特性為單位進行 “實驗”,能度量和管控特性級別的成功。持續交付能幫助實驗更快完成,透過單特性發布得到結果,甚至實現 “精益創業” - 客戶沒有付費的功能就是浪費。
在大型敏捷團隊的主幹持續交付過程中,特性開關就有非常好的優點,透過一個開關啟用或者關閉某個特性,讓使用者在特定期限內用上某個特性,風險也較低。
測試團隊需要測試特性開關的運轉是否符合預期,需要採取措施將測試和生產運營分離開。同時團隊可以測試客戶對新特性的喜好程度。
特性開關也有一些缺點,它增加了軟體的複雜度,尤其是特性開關的不同組合和不同測試環境,都給測試人員帶來不小成本。
持續交付和環境
環境問題始終是持續交付發揮價值的攔路虎。持續交付的環境完全相同時,就可以消除軟體外部的錯誤來源。
但是在環境治理上,IT 部門和業務研發部門的態度可能不同。IT 部門更專注統一穩定的環境建設,業務部門更關心易用性和靈活性。
持續交付的環境希望有 “狀態” 的概念,每個當前狀態都可以被追溯,治理中發現的規律會給團隊帶來可靠性。
測試環境的管理職責應該放在哪個團隊?鼎叔認為這要看治理範圍。如果是環境的快速搭建、可用性驗證、紀律、可用性度量,測試團隊可以承擔管理職責,但是底層體驗問題可以讓開發運維團隊先進行專項改進,比如自動化配置和依賴部署,資源自動建立,監控和最佳化等。
最終,持續交付看板上應該有測試環境可用性的實時度量指標,隨時掌握環境。
持續交付的日誌系統
日誌系統對於運維和開發非常重要,日誌看起來是非常簡單的記錄應用程式資訊的方法,實則有不少特點:
寫入很簡單,各種外部技術都可以實現,只需要” 新增 “就可以把資訊納入日誌。無需付出很大的工作量就可以持續儲存。
日誌檔案的覆蓋和拆分,分析和檢索也很容易,我們可以很容易地解讀日誌資訊。日誌檔案可以和具體的分析技術或監控技術無關。
正因為日誌是需要人來處理的,它就應該儘可能容易理解,否則在深夜遇到線上問題,責任人是沒有充分的時間和精力來分析複雜的資訊關係的。
因為日誌有海量的記錄容量,被寫入的資訊重要程度是大相徑庭的,日誌系統會為資訊提供不同的儲存級別,由此過濾掉大多數不重要的資訊,最小化生產系統的資料量和效能影響。比如必須記錄 Error 級別的資訊,放棄部分 Info 級別的資訊,並針對特定的錯誤把 Debug 級別的資訊寫入日誌。
為了生產資料的安全性,日誌信中的敏感資訊不能簡單地傳送給開發人員,可以利用脫敏或者雜湊化工具,讓開發人員不能判斷具體的使用者,但是知道這個日誌對應於同一個人。