關(guān)于我們
書單推薦
新書推薦
|
持續(xù)交付:發(fā)布可靠軟件的系統(tǒng)方法
《持續(xù)交付:發(fā)布可靠軟件的系統(tǒng)方法》講述如何實(shí)現(xiàn)更快、更可靠、低成本的自動(dòng)化軟件交付,描述了如何通過增加反饋,并改進(jìn)開發(fā)人員、測(cè)試人員、運(yùn)維人員和項(xiàng)目經(jīng)理之間的協(xié)作來達(dá)到這個(gè)目標(biāo)。本書由三部分組成。第一部分闡述了持續(xù)交付背后的一些原則,以及支持這些原則的實(shí)踐。第二部分是本書的核心,全面講述了部署流水線。第三部分圍繞部署流水線的投入產(chǎn)出討論了更多細(xì)節(jié),包括增量開發(fā)技術(shù)、高級(jí)版本控制模式,以及基礎(chǔ)設(shè)施、環(huán)境和數(shù)據(jù)的管理和組織治理。
《持續(xù)交付:發(fā)布可靠軟件的系統(tǒng)方法》適合所有開發(fā)人員、測(cè)試人員、運(yùn)維人員和項(xiàng)目經(jīng)理學(xué)習(xí)參考。
第21屆Jolt大獎(jiǎng)獲獎(jiǎng)作品 馬丁·福勒作序推薦 原著被譽(yù)為2010年最重要的技術(shù)書 軟件開發(fā)的新經(jīng)典 《持續(xù)交付:發(fā)布可靠軟件的系統(tǒng)方法》是一本軟件工程師的職場(chǎng)指南,以大量虛構(gòu)的名字和情景描述了極客的日常工作,對(duì)他們常遇到的各類棘手問題給予了巧妙回答。作者以自己在蘋果、網(wǎng)景等公司中面臨的生死攸關(guān)的時(shí)刻所做的抉擇為例,總結(jié)了在硅谷摸爬滾打的經(jīng)驗(yàn),旨在為軟件工程師更好地規(guī)劃自己的職業(yè)生涯提供幫助。
Jez Humble ToughtWorks公司首席咨詢顧問,致力于幫助企業(yè)快速、可靠地交付高質(zhì)量軟件,經(jīng)常在各種敏捷技術(shù)大會(huì)上發(fā)表演講,擁有牛津大學(xué)物理學(xué)學(xué)士學(xué)位和 倫敦大學(xué)民族音樂學(xué)的碩士學(xué)位。2000年至今,他曾在各行業(yè)和不同技術(shù)領(lǐng)域擔(dān)任系統(tǒng)管理員、開發(fā)人員、培訓(xùn)人員、咨詢師和經(jīng)理人員。
第一部分 基礎(chǔ)篇
第1 章 軟件交付的問題 1.1 引言 1.2 一些常見的發(fā)布反模式 1.2.1 反模式:手工部署軟件 1.2.2 反模式:開發(fā)完成之后才向類生產(chǎn)環(huán)境部署 1.2.3 反模式:生產(chǎn)環(huán)境的手工配置管理 1.2.4 我們能做得更好嗎 1.3 如何實(shí)現(xiàn)目標(biāo) 1.3.1 每次修改都應(yīng)該觸發(fā)反饋流程 1.3.2 必須盡快接收反饋 1.3.3 交付團(tuán)隊(duì)必須接收反饋并作出反應(yīng) 1.3.4 這個(gè)流程可以推廣嗎 1.4 收效 1.4.1 授權(quán)團(tuán)隊(duì) 1.4.2 減少錯(cuò)誤 1.4.3 緩解壓力 1.4.4 部署的靈活性 1.4.5 多加練習(xí),使其完美 1.5 候選發(fā)布版本 1.6 軟件交付的原則 1.6.1 為軟件的發(fā)布創(chuàng)建一個(gè)可重復(fù)且可靠的過程 1.6.2 將幾乎所有事情自動(dòng)化 1.6.3 把所有的東西都納入版本控制 1.6.4 提前并頻繁地做讓你感到痛苦的事 1.6.5 內(nèi)建質(zhì)量 1.6.6 “DONE”意味著“已發(fā)布” 1.6.7 交付過程是每個(gè)成員的責(zé)任 1.6.8 持續(xù)改進(jìn) 1.7 小結(jié) 第2 章 配置管理 2.1 引言 2.2 使用版本控制 2.2.1 對(duì)所有內(nèi)容進(jìn)行版本控制 2.2.2 頻繁提交代碼到主干 2.2.3 使用意義明顯的提交注釋 2.3 依賴管理 2.3.1 外部庫文件管理 2.3.2 組件管理 2.4 軟件配置管理 2.4.1 配置與靈活性 2.4.2 配置的分類 2.4.3 應(yīng)用程序的配置管理 2.4.4 跨應(yīng)用的配置管理 2.4.5 管理配置信息的原則 2.5 環(huán)境管理 2.5.1 環(huán)境管理的工具 2.5.2 變更過程管理 2.6 小結(jié) 第3 章 持續(xù)集成 3.1 引言 3.2 實(shí)現(xiàn)持續(xù)集成 3.2.1 準(zhǔn)備工作 3.2.2 一個(gè)基本的持續(xù)集成系統(tǒng) 3.3 持續(xù)集成的前提條件 3.3.1 頻繁提交 3.3.2 創(chuàng)建全面的自動(dòng)化測(cè)試套件 3.3.3 保持較短的構(gòu)建和測(cè)試過程 3.3.4 管理開發(fā)工作區(qū) 3.4 使用持續(xù)集成軟件 3.4.1 基本操作 3.4.2 鈴聲和口哨 3.5 必不可少的實(shí)踐 3.5.1 構(gòu)建失敗之后不要提交新代碼 3.5.2 提交前在本地運(yùn)行所有的提交測(cè)試,或者讓持續(xù)集成服務(wù)器完成此事 3.5.3 等提交測(cè)試通過后再繼續(xù)工作 3.5.4 回家之前,構(gòu)建必須處于成功狀態(tài) 3.5.5 時(shí)刻準(zhǔn)備著回滾到前一個(gè)版本 3.5.6 在回滾之前要規(guī)定一個(gè)修復(fù)時(shí)間 3.5.7 不要將失敗的測(cè)試注釋掉 3.5.8 為自己導(dǎo)致的問題負(fù)責(zé) 3.5.9 測(cè)試驅(qū)動(dòng)的開發(fā) 3.6 推薦的實(shí)踐 3.6.1 極限編程開發(fā)實(shí)踐 3.6.2 若違背架構(gòu)原則,就讓構(gòu)建失敗 3.6.3 若測(cè)試運(yùn)行變慢,就讓構(gòu)建失敗 3.6.4 若有編譯警告或代碼風(fēng)格問題,就讓測(cè)試失敗 3.7 分布式團(tuán)隊(duì) 3.7.1 對(duì)流程的影響 3.7.2 集中式持續(xù)集成 3.7.3 技術(shù)問題 3.7.4 替代方法 3.8 分布式版本控制系統(tǒng) 3.9 小結(jié) 第4 章 測(cè)試策略的實(shí)現(xiàn) 4.1 引言 4.2 測(cè)試的分類 4.2.1 業(yè)務(wù)導(dǎo)向且支持開發(fā)過程的測(cè)試 4.2.2 技術(shù)導(dǎo)向且支持開發(fā)過程的測(cè)試 4.2.3 業(yè)務(wù)導(dǎo)向且評(píng)價(jià)項(xiàng)目的測(cè)試 4.2.4 技術(shù)導(dǎo)向且評(píng)價(jià)項(xiàng)目的測(cè)試 4.2.5 測(cè)試替身 4.3 現(xiàn)實(shí)中的情況與應(yīng)對(duì)策略 4.3.1 新項(xiàng)目 4.3.2 項(xiàng)目進(jìn)行中 4.3.3 遺留系統(tǒng) 4.3.4 集成測(cè)試 4.4 流程 4.5 小結(jié) 第二部分 部署流水線 第5 章 部署流水線解析 5.1 引言 5.2 什么是部署流水線 5.3 部署流水線的相關(guān)實(shí)踐 5.3.1 只生成一次二進(jìn)制包 5.3.2 對(duì)不同環(huán)境采用同一部署方式 5.3.3 對(duì)部署進(jìn)行冒煙測(cè)試 5.3.4 向生產(chǎn)環(huán)境的副本中部署 5.3.5 每次變更都要立即在流水線中傳遞 5.3.6 只要有環(huán)節(jié)失敗,就停止整個(gè)流水線 5.4 提交階段 5.5 自動(dòng)化驗(yàn)收測(cè)試之門 5.6 后續(xù)的測(cè)試階段 5.6.1 手工測(cè)試 5.6.2 非功能測(cè)試 5.7 發(fā)布準(zhǔn)備 5.7.1 自動(dòng)部署與發(fā)布 5.7.2 變更的撤銷 5.7.3 在成功的基礎(chǔ)上構(gòu)建 5.8 實(shí)現(xiàn)一個(gè)部署流水線 5.8.1 對(duì)價(jià)值流進(jìn)行建模并創(chuàng)建簡(jiǎn)單的可工作框架 5.8.2 構(gòu)建和部署過程的自動(dòng)化 5.8.3 自動(dòng)化單元測(cè)試和代碼分析 5.8.4 自動(dòng)化驗(yàn)收測(cè)試 5.8.5 部署流水線的演進(jìn) 5.9 度量 5.10 小結(jié) 第6 章 構(gòu)建與部署的腳本化 6.1 引言 6.2 構(gòu)建工具概覽 6.2.1 Make 6.2.2 Ant 6.2.3 NAnt 與 MSBuild 6.2.4 Maven 6.2.5 Rake 6.2.6 Buildr 6.2.7 Psake 6.3 構(gòu)建部署腳本化的原則與實(shí)踐 6.3.1 為部署流水線的每個(gè)階段創(chuàng)建腳本 6.3.2 使用恰當(dāng)?shù)募夹g(shù)部署應(yīng)用程序 6.3.3 使用同樣的腳本向所有環(huán)境部署 6.3.4 使用操作系統(tǒng)自帶的包管理工具 6.3.5 確保部署流程是冪等的(Idempotent) 6.3.6 部署系統(tǒng)的增量式演進(jìn) 6.4 面向JVM 的應(yīng)用程序的項(xiàng)目結(jié)構(gòu) 6.5 部署腳本化 6.5.1 多層的部署和測(cè)試 6.5.2 測(cè)試環(huán)境配置 6.6 小貼士 6.6.1 總是使用相對(duì)路徑 6.6.2 消除手工步驟 6.6.3 從二進(jìn)制包到版本控制庫的內(nèi)建可追溯性 6.6.4 不要把二進(jìn)制包作為構(gòu)建的一部分放到版本控制庫中 6.6.5 “test”不應(yīng)該讓構(gòu)建失敗 6.6.6 用集成冒煙測(cè)試來限制應(yīng)用程序 6.6.7 .NET 小貼士 6.7 小結(jié) 第7 章 提交階段 7.1 引言 7.2 提交階段的原則和實(shí)踐 7.2.1 提供快速有用的反饋 7.2.2 何時(shí)令提交階段失敗 7.2.3 精心對(duì)待提交階段 7.2.4 讓開發(fā)人員也擁有所有權(quán) 7.2.5 在超大項(xiàng)目團(tuán)隊(duì)中指定一個(gè)構(gòu)建負(fù)責(zé)人 7.3 提交階段的結(jié)果 7.4 提交測(cè)試套件的原則與實(shí)踐 7.4.1 避免用戶界面 7.4.2 使用依賴注入 7.4.3 避免使用數(shù)據(jù)庫 7.4.4 在單元測(cè)試中避免異步 7.4.5 使用測(cè)試替身 7.4.6 最少化測(cè)試中的狀態(tài) 7.4.7 時(shí)間的偽裝 7.4.8 蠻力 7.5 小結(jié) 第8 章 自動(dòng)化驗(yàn)收測(cè)試 8.1 引言 8.2 為什么驗(yàn)收測(cè)試是至關(guān)重要的 8.2.1 如何創(chuàng)建可維護(hù)的驗(yàn)收測(cè)試套件 8.2.2 GUI 上的測(cè)試 8.3 創(chuàng)建驗(yàn)收測(cè)試 8.3.1 分析人員和測(cè)試人員的角色 8.3.2 迭代開發(fā)項(xiàng)目中的分析工作 8.3.3 將驗(yàn)收條件變成可執(zhí)行的規(guī)格說明書 8.4 應(yīng)用程序驅(qū)動(dòng)層 8.4.1 如何表述驗(yàn)收條件 8.4.2 窗口驅(qū)動(dòng)器模式:讓測(cè)試與GUI 解耦 8.5 實(shí)現(xiàn)驗(yàn)收測(cè)試 8.5.1 驗(yàn)收測(cè)試中的狀態(tài) 8.5.2 過程邊界、封裝和測(cè)試 8.5.3 管理異步與超時(shí)問題 8.5.4 使用測(cè)試替身對(duì)象 8.6 驗(yàn)收測(cè)試階段 8.6.1 確保驗(yàn)收測(cè)試一直處于通過狀態(tài) 8.6.2 部署測(cè)試 8.7 驗(yàn)收測(cè)試的性能 8.7.1 重構(gòu)通用任務(wù) 8.7.2 共享昂貴資源 8.7.3 并行測(cè)試 8.7.4 使用計(jì)算網(wǎng)格 8.8 小結(jié) 第9 章 非功能需求的測(cè)試 9.1 引言 9.2 非功能需求的管理 9.3 如何為容量編程 9.4 容量度量 9.5 容量測(cè)試環(huán)境 9.6 自動(dòng)化容量測(cè)試 9.6.1 通過UI 的容量測(cè)試 9.6.2 基于服務(wù)或公共API 來錄制交互操作 9.6.3 使用錄制的交互模板 9.6.4 使用容量測(cè)試樁開發(fā)測(cè)試 9.7 將容量測(cè)試加入到部署流水線中 9.8 容量測(cè)試系統(tǒng)的附加價(jià)值 9.9 小結(jié) 第10 章 應(yīng)用程序的部署與發(fā)布 10.1 引言 10.2 創(chuàng)建發(fā)布策略 10.2.1 發(fā)布計(jì)劃 10.2.2 發(fā)布產(chǎn)品 10.3 應(yīng)用程序的部署和晉級(jí) 10.3.1 首次部署 10.3.2 對(duì)發(fā)布過程進(jìn)行建模并讓構(gòu)建晉級(jí) 10.3.3 配置的晉級(jí) 10.3.4 聯(lián)合環(huán)境 10.3.5 部署到試運(yùn)行環(huán)境 10.4 部署回滾和零停機(jī)發(fā)布 10.4.1 通過重新部署原有的正常版本來進(jìn)行回滾 10.4.2 零停機(jī)發(fā)布 10.4.3 藍(lán)綠部署 10.4.4 金絲雀發(fā)布 10.5 緊急修復(fù) 10.6 持續(xù)部署 10.7 小貼士和竅門 10.7.1 真正執(zhí)行部署操作的人應(yīng)該參與部署過程的創(chuàng)建 10.7.2 記錄部署活動(dòng) 10.7.3 不要?jiǎng)h除舊文件,而是移動(dòng)到別的位置 10.7.4 部署是整個(gè)團(tuán)隊(duì)的責(zé)任 10.7.5 服務(wù)器應(yīng)用程序不應(yīng)該有GUI 10.7.6 為新部署留預(yù)熱期 10.7.7 快速失敗 10.7.8 不要直接對(duì)生產(chǎn)環(huán)境進(jìn)行修改 10.8 小結(jié) 第三部分 交付生態(tài)圈 第11 章 基礎(chǔ)設(shè)施和環(huán)境管理 11.1 引言 11.2 理解運(yùn)維團(tuán)隊(duì)的需要 11.2.1 文檔與審計(jì) 11.2.2 異常事件的告警 11.2.3 保障IT 服務(wù)持續(xù)性的計(jì)劃 11.2.4 使用運(yùn)維團(tuán)隊(duì)熟悉的技術(shù) 11.3 基礎(chǔ)設(shè)施的建模和管理 11.3.1 基礎(chǔ)設(shè)施的訪問控制 11.3.2 對(duì)基礎(chǔ)設(shè)施進(jìn)行修改 11.4 服務(wù)器的準(zhǔn)備及其配置的管理 11.4.1 服務(wù)器的準(zhǔn)備 11.4.2 服務(wù)器的持續(xù)管理 11.5 中間件的配置管理 11.5.1 管理配置項(xiàng) 11.5.2 產(chǎn)品研究 11.5.3 考查中間件是如何處理狀態(tài)的 11.5.4 查找用于配置的API 11.5.5 使用更好的技術(shù) 11.6 基礎(chǔ)設(shè)施服務(wù)的管理 11.7 虛擬化 11.7.1 虛擬環(huán)境的管理 11.7.2 虛擬環(huán)境和部署流水線 11.7.3 用虛擬環(huán)境做高度的并行測(cè)試 11.8 云計(jì)算 11.8.1 云中基礎(chǔ)設(shè)施 11.8.2 云中平臺(tái) 11.8.3 沒有普適存在 11.8.4 對(duì)云計(jì)算的批評(píng) 11.9 基礎(chǔ)設(shè)施和應(yīng)用程序的監(jiān)控 11.9.1 收集數(shù)據(jù) 11.9.2 記錄日志 11.9.3 建立信息展示板 11.9.4 行為驅(qū)動(dòng)的監(jiān)控 11.10 小結(jié) 第12 章 數(shù)據(jù)管理 12.1 引言 12.2 數(shù)據(jù)庫腳本化 12.3 增量式修改 12.3.1 對(duì)數(shù)據(jù)庫進(jìn)行版本控制 12.3.2 聯(lián)合環(huán)境中的變更管理 12.4 數(shù)據(jù)庫回滾和無停機(jī)發(fā)布 12.4.1 保留數(shù)據(jù)的回滾 12.4.2 將應(yīng)用程序部署與數(shù)據(jù)庫遷移解耦 12.5 測(cè)試數(shù)據(jù)的管理 12.5.1 為單元測(cè)試進(jìn)行數(shù)據(jù)庫模擬 12.5.2 管理測(cè)試與數(shù)據(jù)之間的耦合 12.5.3 測(cè)試獨(dú)立性 12.5.4 建立和銷毀 12.5.5 連貫的測(cè)試場(chǎng)景 12.6 數(shù)據(jù)管理和部署流水線 12.6.1 提交階段的測(cè)試數(shù)據(jù) 12.6.2 驗(yàn)收測(cè)試中的數(shù)據(jù) 12.6.3 容量測(cè)試的數(shù)據(jù) 12.6.4 其他測(cè)試階段的數(shù)據(jù) 12.7 小結(jié) 第13 章 組件和依賴管理 13.1 引言 13.2 保持應(yīng)用程序可發(fā)布 13.2.1 將新功能隱蔽起來,直到它完成為止 13.2.2 所有修改都是增量式的 13.2.3 通過抽象來模擬分支 13.3 依賴 13.3.1 依賴地獄 13.3.2 庫管理 13.4 組件 13.4.1 如何將代碼庫分成多個(gè)組件 13.4.2 將組件流水線化 13.4.3 集成流水線 13.5 管理依賴關(guān)系圖 13.5.1 構(gòu)建依賴圖 13.5.2 為依賴圖建立流水線 13.5.3 什么時(shí)候要觸發(fā)構(gòu)建 13.5.4 謹(jǐn)慎樂觀主義 13.5.5 循環(huán)依賴 13.6 管理二進(jìn)制包 13.6.1 制品庫是如何運(yùn)作的 13.6.2 部署流水線如何與制品庫相結(jié)合 13.7 用Maven 管理依賴 13.8 小結(jié) 第14 章 版本控制進(jìn)階 14.1 引言 14.2 版本控制的歷史 14.2.1 CVS 14.2.2 SVN 14.2.3 商業(yè)版本控制系統(tǒng) 14.2.4 放棄悲觀鎖 14.3 分支與合并 14.3.1 合并 14.3.2 分支、流和持續(xù)集成 14.4 DVCS 14.4.1 什么是DVCS 14.4.2 DVCS 簡(jiǎn)史 14.4.3 企業(yè)環(huán)境中的DVCS 14.4.4 使用DVCS 14.5 基于流的版本控制系統(tǒng) 14.5.1 什么是基于流的版本控制系統(tǒng) 14.5.2 使用流的開發(fā)模型 14.5.3 靜態(tài)視圖和動(dòng)態(tài)視圖 14.5.4 使用基于流的版本控制系統(tǒng)做持續(xù)集成 14.6 主干開發(fā) 14.7 按發(fā)布創(chuàng)建分支 14.8 按功能特性分支 14.9 按團(tuán)隊(duì)分支 14.10 小結(jié) 第15 章 持續(xù)交付管理 15.1 引言 15.2 配置與發(fā)布管理成熟度模型 15.3 項(xiàng)目生命周期 15.3.1 識(shí)別階段 15.3.2 啟動(dòng)階段 15.3.3 初始階段 15.3.4 開發(fā)與發(fā)布 15.3.5 運(yùn)營(yíng)階段 15.4 風(fēng)險(xiǎn)管理流程 15.4.1 風(fēng)險(xiǎn)管理基礎(chǔ)篇 15.4.2 風(fēng)險(xiǎn)管理時(shí)間軸 15.4.3 如何做風(fēng)險(xiǎn)管理的練習(xí) 15.5 常見的交付問題、癥狀和原因 15.5.1 不頻繁的或充滿缺陷的部署 15.5.2 較差的應(yīng)用程序質(zhì)量 15.5.3 缺乏管理的持續(xù)集成工作流程 15.5.4 較差的配置管理 15.6 符合度與審計(jì) 15.6.1 文檔自動(dòng)化 15.6.2 加強(qiáng)可跟蹤性 15.6.3 在筒倉中工作 15.6.4 變更管理 15.7 小結(jié) 參考書目
軟件交付的問題
1.1 引言 作為軟件從業(yè)人員,我們面臨的最重要問題就是,如果有人想到了一個(gè)好點(diǎn)子,我們?nèi)绾我宰羁斓乃俣葘⑺桓督o用戶?本書將給出這個(gè)問題的答案。 我們將專注于構(gòu)建、部署、測(cè)試和發(fā)布過程,因?yàn)橄鄬?duì)于軟件生產(chǎn)全過程的其他環(huán)節(jié)來說,這部分內(nèi)容的論著較為稀少。確切地說,我們并不認(rèn)為軟件開發(fā)方法不重要,如果沒有對(duì)軟件生命周期中其他方面的關(guān)注,只把它們作為全部問題的次要因素草率對(duì)待的話,就不可能實(shí)現(xiàn)可靠、迅速且低風(fēng)險(xiǎn)的軟件發(fā)布,無法以高效的方式將我們的勞動(dòng)成果交到用戶手中。 現(xiàn)在有很多種軟件開發(fā)方法,但它們主要關(guān)注于需求管理及其對(duì)開發(fā)工作的影響。市面上也有很多優(yōu)秀的書,它們?cè)敿?xì)討論了在軟件設(shè)計(jì)、開發(fā)和測(cè)試方面各種各樣的方法,但它們都僅僅講述了將軟件交付給作為客戶的人或組織這一完整價(jià)值流的一部分。 一旦完成了需求定義以及方案的設(shè)計(jì)、開發(fā)和測(cè)試,我們接下來做什么?我們?nèi)绾螀f(xié)調(diào)這些活動(dòng),盡可能地使交付過程更加可靠有效呢?我們?nèi)绾巫岄_發(fā)人員、測(cè)試人員,以及構(gòu)建和運(yùn)維人員在一起高效地工作呢? 本書描述了軟件從開發(fā)到發(fā)布這一過程的有效模式。書中講述了幫助大家實(shí)現(xiàn)這種模式的技術(shù)和最佳實(shí)踐,展示了它與軟件交付中其他活動(dòng)是如何聯(lián)系的。 本書的中心模式是部署流水線。從本質(zhì)上講,部署流水線就是指一個(gè)應(yīng)用程序從構(gòu)建、部署、測(cè)試到發(fā)布這整個(gè)過程的自動(dòng)化實(shí)現(xiàn)。部署流水線的實(shí)現(xiàn)對(duì)于每個(gè)組織都將是不同的,這取決于他們對(duì)軟件發(fā)布的價(jià)值流的定義,但其背后的原則是相同的。 部署流水線的示例如圖1-1所示。 部署流水線大致的工作方式如下。對(duì)于應(yīng)用程序的配置、源代碼、環(huán)境或數(shù)據(jù)的每個(gè)變更都會(huì)觸發(fā)創(chuàng)建一個(gè)新流水線實(shí)例的過程。流水線的首要步驟之一就是創(chuàng)建二進(jìn)制文件和安裝包,而其余部分都是基于第一步的產(chǎn)物所做的一系列測(cè)試,用于證明其達(dá)到了發(fā)布質(zhì)量。每通過一步測(cè)試,我都會(huì)更加相信這些二進(jìn)制文件、配置信息、環(huán)境和數(shù)據(jù)所構(gòu)成的特殊組合可以正常工作。如果這個(gè)產(chǎn)品通過了所有的測(cè)試環(huán)節(jié),那么它就可以發(fā)布了。 圖1-1 一個(gè)簡(jiǎn)單的部署流水線 部署流水線以持續(xù)集成過程為其理論基石,從本質(zhì)上講,它是采納持續(xù)集成原理后的自然結(jié)果。 部署流水線的目標(biāo)有三個(gè)。首先,它讓軟件構(gòu)建、部署、測(cè)試和發(fā)布過程對(duì)所有人可見,促進(jìn)了合作。其次,它改善了反饋,以便在整個(gè)過程中,我們能夠更早地發(fā)現(xiàn)并解決問題。最后,它使團(tuán)隊(duì)能夠通過一個(gè)完全自動(dòng)化的過程在任意環(huán)境上部署和發(fā)布軟件的任意版本。 1.2 一些常見的發(fā)布反模式 軟件發(fā)布的當(dāng)天往往是緊張的一天。為什么會(huì)這樣呢?對(duì)于大多數(shù)項(xiàng)目來說,在整個(gè)過程中,發(fā)布時(shí)的風(fēng)險(xiǎn)是比較大的。 在許多軟件項(xiàng)目中,軟件發(fā)布是一個(gè)需要很多手工操作的過程。首先,由運(yùn)維團(tuán)隊(duì)獨(dú)自負(fù)責(zé)安裝好該應(yīng)用程序所需的操作系統(tǒng)環(huán)境,再把應(yīng)用程序所依賴的第三方軟件安裝好。其次,要手工將應(yīng)用程序的軟件產(chǎn)物復(fù)制到生產(chǎn)主機(jī)環(huán)境,然后通過Web服務(wù)器、應(yīng)用服務(wù)器或其他第三方系統(tǒng)的管理控制臺(tái)復(fù)制或創(chuàng)建配置信息,再把相關(guān)的數(shù)據(jù)復(fù)制一份到環(huán)境中,最后啟動(dòng)應(yīng)用程序。假如這是個(gè)分布式的或面向服務(wù)的應(yīng)用程序,可能就需要一部分一部分地完成。 如上所述,發(fā)布當(dāng)天緊張的原因應(yīng)該比較清楚了:在這個(gè)過程中有太多步驟可能出錯(cuò)。假如其中有一步?jīng)]有完美地執(zhí)行,應(yīng)用程序就無法正確地運(yùn)行。一旦發(fā)生這種情況,我們很難一下子說清楚哪里出了錯(cuò),或到底是哪一步出了錯(cuò)。 本書其他部分將討論如何避免這些風(fēng)險(xiǎn),如何減少發(fā)布當(dāng)天的壓力,以及如何確保每次發(fā)布的可靠性都是可預(yù)見的。 在此之前,讓我們先明確到底要避免哪類失敗。下面列出了與可靠的發(fā)布過程相對(duì)應(yīng)的幾種常見的反模式,它們?cè)谖覀冞@個(gè)行業(yè)中屢見不鮮。 1.2.1 反模式:手工部署軟件 對(duì)于現(xiàn)在的大多數(shù)應(yīng)用程序來說,無論規(guī)模大小,其部署過程都比較復(fù)雜,而且包含很多非常靈活的部分。許多組織都使用手工方式發(fā)布軟件,也就是說部署應(yīng)用程序所需的步驟是獨(dú)立的原子性操作,由某個(gè)人或某個(gè)小組來分別執(zhí)行。每個(gè)步驟里都有一些需要人為判斷的事情,因此很容易發(fā)生人為錯(cuò)誤。即便不是這樣,這些步驟的執(zhí)行順序和時(shí)機(jī)的不同也會(huì)導(dǎo)致結(jié)果的差異性,而這種差異性很可能給我們帶來不良后果。 這種反模式的特征如下。 · 有一份非常詳盡的文檔,該文檔描述了執(zhí)行步驟及每個(gè)步驟中易出錯(cuò)的地方。 · 以手工測(cè)試來確認(rèn)該應(yīng)用程序是否運(yùn)行正確。 · 在發(fā)布當(dāng)天開發(fā)團(tuán)隊(duì)頻繁地接到電話,客戶要求解釋部署為何會(huì)出錯(cuò)。 · 在發(fā)布時(shí),常常會(huì)修正一些在發(fā)布過程中發(fā)現(xiàn)的問題。 · 如果是集群環(huán)境部署,常常發(fā)現(xiàn)在集群中各環(huán)境的配置都不相同,比如應(yīng)用服務(wù)器的連接池設(shè)置不同或文件系統(tǒng)有不同的目錄結(jié)構(gòu)等。 · 發(fā)布過程需要較長(zhǎng)的時(shí)間(超過幾分鐘)。 · 發(fā)布結(jié)果不可預(yù)測(cè),常常不得不回滾或遇到不可預(yù)見的問題。 · 發(fā)布之后凌晨?jī)牲c(diǎn)還睡眼惺忪地坐在顯示器前,絞盡腦汁想著怎么讓剛剛部署的應(yīng)用程序能夠正常工作。 相反,隨著時(shí)間的推移,部署應(yīng)該走向完全自動(dòng)化,即對(duì)于那些負(fù)責(zé)將應(yīng)用程序部署到開發(fā)環(huán)境、測(cè)試環(huán)境或生產(chǎn)環(huán)境的人來說,應(yīng)該只需要做兩件事:(1)挑選版本及需要部署的環(huán)境,(2)按一下“部署”按鈕。對(duì)于套裝軟件的發(fā)布來說,還應(yīng)該有一個(gè)創(chuàng)建安裝程序的自動(dòng)化過程。 我們將在本書中討論很多自動(dòng)化問題。當(dāng)然,并不是所有的人都熱衷于這個(gè)想法。那么,我們先來解釋一下為什么把自動(dòng)化部署看做是一個(gè)必不可少的目標(biāo)。 · 如果部署過程沒有完全自動(dòng)化,每次部署時(shí)都會(huì)發(fā)生錯(cuò)誤。唯一的問題就是“該問題嚴(yán)重與否”而已。即便使用良好的部署測(cè)試,有些錯(cuò)誤也很難追查。 · 如果部署過程不是自動(dòng)化的,那么它就既不可重復(fù)也不可靠,就會(huì)在調(diào)試部署錯(cuò)誤的過程中浪費(fèi)很多時(shí)間。 · 手動(dòng)部署流程不得不被寫在文檔里?墒俏臋n維護(hù)是一項(xiàng)復(fù)雜而費(fèi)時(shí)的任務(wù),它涉及多人之間的協(xié)作,因此文檔通常要么是不完整的,要么就是未及時(shí)更新的,而把一套自動(dòng)化部署腳本作為文檔,它就永遠(yuǎn)是最新且完整的,否則就無法進(jìn)行部署工作了。 · 自動(dòng)部署本質(zhì)上也是鼓勵(lì)協(xié)作的,因?yàn)樗袃?nèi)容都在一個(gè)腳本里,一覽無遺。要讀懂文檔通常需要讀者具備一定的知識(shí)水平。然而在現(xiàn)實(shí)中,文檔通常只是為執(zhí)行部署者寫的備忘錄,是難以被他人理解的。 · 以上幾點(diǎn)引起的一個(gè)必然結(jié)果:手工部署過程依賴于部署專家。如果專家去度假或離職了,那你就有麻煩了。 · 盡管手工部署枯燥且極具重復(fù)性,但仍需要有相當(dāng)程度的專業(yè)知識(shí)。若要求專家做這些無聊、重復(fù),但有技術(shù)要求的任務(wù)則必定會(huì)出現(xiàn)各種我們可以預(yù)料到的人為失誤,同時(shí)失眠,酗酒這種問題也會(huì)接踵而至。然而自動(dòng)化部署可以把那些成本高昂的資深高技術(shù)人員從過度工作中解放出來,讓他們投身于更高價(jià)值的工作活動(dòng)當(dāng)中。 · 對(duì)手工部署過程進(jìn)行測(cè)試的唯一方法就是原封不動(dòng)地做一次(或者幾次)。這往往費(fèi)時(shí),還會(huì)造成高昂的金錢成本,而測(cè)試自動(dòng)化的部署過程卻是既便宜又容易。 · 另外,還有一種說法:自動(dòng)化過程不如手工過程的可審計(jì)性好。我們對(duì)這個(gè)觀點(diǎn)感到很疑惑。對(duì)于一個(gè)手工過程來說,沒人能確保其執(zhí)行者會(huì)非常嚴(yán)格地遵循文檔完成操作。只有自動(dòng)化過程是完全可審核的。有什么會(huì)比一個(gè)可工作的部署腳本更容易被審核的呢? · 每個(gè)人都應(yīng)該使用自動(dòng)化部署過程,而且它應(yīng)該是軟件部署的唯一方式。這個(gè)準(zhǔn)則可以確保:在需要部署時(shí),部署腳本就能完成工作。在本書中我們會(huì)提到多個(gè)原則,而其中之一就是“使用相同的腳本將軟件部署到各種環(huán)境上”。如果使用相同的腳本將軟件部署到各類環(huán)境中,那么在發(fā)布當(dāng)天需要向生產(chǎn)環(huán)境進(jìn)行部署時(shí),這個(gè)腳本已經(jīng)被驗(yàn)證過成百上千次了。如果發(fā)布時(shí)出現(xiàn)任何問題的話,你可以百分百地確定是該環(huán)境的具體配置問題,而不是這個(gè)腳本的問題。 當(dāng)然,手工密集型的發(fā)布工作有時(shí)也會(huì)進(jìn)行得非常順利。有沒有可能是糟糕的情況剛巧都被我們撞見了呢?假如在整個(gè)軟件生產(chǎn)過程中它還算不上一個(gè)易出錯(cuò)的步驟,那么為什么還總要這么嚴(yán)陣以待呢?為什么需要這些流程和文檔呢?為什么團(tuán)隊(duì)在周末還要加班呢?為什么還要求大家原地待命,以防意外發(fā)生呢? 1.2.2 反模式:開發(fā)完成之后才向類生產(chǎn)環(huán)境部署 在這一模式下,當(dāng)軟件被第一次部署到類生產(chǎn)環(huán)境(比如試運(yùn)行環(huán)境)時(shí),就是大部分開發(fā)工作完成時(shí),至少是開發(fā)團(tuán)隊(duì)認(rèn)為“該軟件開發(fā)完成了”。 這種模式中,經(jīng)常出現(xiàn)下面這些情況。 · 如果測(cè)試人員一直參與了在此之前的過程,那么他們已在開發(fā)機(jī)器上對(duì)軟件進(jìn)行了測(cè)試。 · 只有在向試運(yùn)行環(huán)境部署時(shí),運(yùn)維人員才第一次接觸到這個(gè)新應(yīng)用程序。在某些組織中,通常是由獨(dú)立的運(yùn)維團(tuán)隊(duì)負(fù)責(zé)將應(yīng)用程序部署到試運(yùn)行環(huán)境和生產(chǎn)環(huán)境。在這種工作方式下,運(yùn)維人員只有在產(chǎn)品被發(fā)布到生產(chǎn)環(huán)境時(shí)才第一次見到這個(gè)軟件。 · 有可能由于類生產(chǎn)環(huán)境非常昂貴,所以權(quán)限控制嚴(yán)格,操作人員自己無權(quán)對(duì)該環(huán)境進(jìn)行操作,也有可能環(huán)境沒有按時(shí)準(zhǔn)備好,甚至也可能根本沒人去準(zhǔn)備環(huán)境。 · 開發(fā)團(tuán)隊(duì)將正確的安裝程序、配置文件、數(shù)據(jù)庫遷移腳本和部署文檔一同交給那些真正執(zhí)行部署任務(wù)的人員,而所有這些都沒有在類生產(chǎn)環(huán)境或試運(yùn)行環(huán)境中進(jìn)行過測(cè)試。 · 開發(fā)團(tuán)隊(duì)和真正執(zhí)行部署任務(wù)的人員之間的協(xié)作非常少。 每當(dāng)需要將軟件部署到試運(yùn)行環(huán)境時(shí),都要組建一個(gè)團(tuán)隊(duì)來完成這項(xiàng)任務(wù)。有時(shí)候這個(gè)團(tuán)隊(duì)是一個(gè)全功能團(tuán)隊(duì)。然而在大型組織中,這種部署責(zé)任通常落在多個(gè)分立的團(tuán)隊(duì)肩上。DBA、中間件團(tuán)隊(duì)、Web團(tuán)隊(duì),以及其他團(tuán)隊(duì)都會(huì)涉及應(yīng)用程序最后版本的部署工作。由于部署工作中的很多步驟根本沒有在試運(yùn)行環(huán)境上測(cè)試過,所以常常遇到問題。比如,文檔中漏掉了一些重要的步驟,文檔和腳本對(duì)目標(biāo)環(huán)境的版本或配置作出錯(cuò)誤的假設(shè),從而使部署失敗。部署團(tuán)隊(duì)必須猜測(cè)開發(fā)團(tuán)隊(duì)的意圖。 若不良協(xié)作使得在試運(yùn)行環(huán)境上的部署工作問題重重,就會(huì)通過臨時(shí)撥打電話、發(fā)電子郵件來溝通,并由開發(fā)人員做快速修復(fù)。一個(gè)嚴(yán)格自律的團(tuán)隊(duì)會(huì)將所有這類溝通納入部署計(jì)劃中,但這個(gè)過程很少有效。隨著部署壓力的增大,為了能夠在規(guī)定的時(shí)間內(nèi)完成部署,開發(fā)團(tuán)隊(duì)與部署團(tuán)隊(duì)之間這種嚴(yán)格定義的協(xié)作過程將被顛覆。 在執(zhí)行部署過程中,我們常常發(fā)現(xiàn)系統(tǒng)設(shè)計(jì)中存在對(duì)生產(chǎn)環(huán)境的錯(cuò)誤假設(shè)。例如,部署的某個(gè)應(yīng)用軟件是用文件系統(tǒng)做數(shù)據(jù)緩存的。這在開發(fā)環(huán)境中是沒有什么問題的,但在集群環(huán)境中可能就不行了。解決這類問題可能要花很長(zhǎng)時(shí)間,而且在問題解決之前,根本無法完成應(yīng)用程序的部署。 一旦將應(yīng)用程序部署到了試運(yùn)行環(huán)境,我們常常會(huì)發(fā)現(xiàn)新的缺陷。遺憾的是,我們常常沒有時(shí)間修復(fù)所有問題,因?yàn)樽詈笃谙揆R上就到了,而且項(xiàng)目進(jìn)行到這個(gè)階段時(shí),推遲發(fā)布日期是不能被人接受的。所以,大多數(shù)嚴(yán)重缺陷被匆忙修復(fù),而為了安全起見,項(xiàng)目經(jīng)理會(huì)保存一份已知缺陷列表,可是當(dāng)下一次發(fā)布開始時(shí),這些缺陷的優(yōu)先級(jí)還是常常被排得很低。 有的時(shí)候,情況會(huì)比這還糟。以下這些事情會(huì)使與發(fā)布相關(guān)的問題惡化。 · 假如一個(gè)應(yīng)用程序是全新開發(fā)的,那么第一次將它部署到試運(yùn)行環(huán)境時(shí),可能會(huì)非常棘手。 · 發(fā)布周期越長(zhǎng),開發(fā)團(tuán)隊(duì)在部署前作出錯(cuò)誤假設(shè)的時(shí)間就越長(zhǎng),修復(fù)這些問題的時(shí)間也就越長(zhǎng)。 · 交付過程被劃分到開發(fā)、DBA、運(yùn)維、測(cè)試等部門的那些大型組織中,各部門之間的協(xié)作成本可能會(huì)非常高,有時(shí)甚至?xí)䦟l(fā)布過程拖上“地獄列車”。此時(shí)為了完成某個(gè)部署任務(wù)(更糟糕的情況是,為了解決部署過程中出現(xiàn)的問題),開發(fā)人員、測(cè)試人員和運(yùn)維人員總是高舉著問題單(不斷地互發(fā)電子郵件)。 · 開發(fā)環(huán)境與生產(chǎn)環(huán)境差異性越大,開發(fā)過程中所做的那些假設(shè)與現(xiàn)實(shí)之間的差距就越大。雖然很難量化,但我敢說,如果在Windows系統(tǒng)上開發(fā)軟件,而最終要部署在Solaris集群上,那么你會(huì)遇到很多意想不到的事情。 · 如果應(yīng)用程序是由用戶自行安裝的(你可能沒有太多權(quán)限來對(duì)用戶的環(huán)境進(jìn)行操作),或者其中的某些組件不在企業(yè)控制范圍之內(nèi),此時(shí)可能需要很多額外的測(cè)試工作。 那么,我們的對(duì)策就是將測(cè)試、部署和發(fā)布活動(dòng)也納入到開發(fā)過程中,讓它們成為開發(fā)流程正常的一部分。這樣的話,當(dāng)準(zhǔn)備好進(jìn)行系統(tǒng)發(fā)布時(shí)就幾乎很少或不會(huì)有風(fēng)險(xiǎn)了,因?yàn)槟阋呀?jīng)在很多種環(huán)境,甚至類生產(chǎn)環(huán)境中重復(fù)過很多次,也就相當(dāng)于測(cè)試過很多次了。而且要確保每個(gè)人都成為這個(gè)軟件交付過程的一份子,無論是構(gòu)建發(fā)布團(tuán)隊(duì)、還是開發(fā)測(cè)試人員,都應(yīng)該從項(xiàng)目開始就一起共事。 我們是測(cè)試的狂熱者,而大量使用持續(xù)集成和持續(xù)部署(不但對(duì)應(yīng)用程序進(jìn)行測(cè)試,而且對(duì)部署過程進(jìn)行測(cè)試)正是我們所描述的方法的基石。 1.2.3 反模式:生產(chǎn)環(huán)境的手工配置管理 很多組織通過專門的運(yùn)維團(tuán)隊(duì)來管理生產(chǎn)環(huán)境的配置。如果需要修改一些東西,比如修改數(shù)據(jù)庫的連接配置或者增加應(yīng)用服務(wù)器線程池中的線程數(shù),就由這個(gè)團(tuán)隊(duì)登錄到生產(chǎn)服務(wù)器上進(jìn)行手工修改。如果把這樣一個(gè)修改記錄下來,那么就相當(dāng)于是變更管理數(shù)據(jù)庫中的一條記錄了。 這種反模式的特征如下。 · 多次部署到試運(yùn)行環(huán)境都非常成功,但當(dāng)部署到生產(chǎn)環(huán)境時(shí)就失敗。 · 集群中各節(jié)點(diǎn)的行為有所不同。例如,與其他節(jié)點(diǎn)相比,某個(gè)節(jié)點(diǎn)所承擔(dān)的負(fù)載少一些,或者處理請(qǐng)求的時(shí)間花得多一些。 · 運(yùn)維團(tuán)隊(duì)需要較長(zhǎng)時(shí)間為每次發(fā)布準(zhǔn)備環(huán)境。 · 系統(tǒng)無法回滾到之前部署的某個(gè)配置,這些配置包括操作系統(tǒng)、應(yīng)用服務(wù)器、關(guān)系型數(shù)據(jù)庫管理系統(tǒng)、Web服務(wù)器或其他基礎(chǔ)設(shè)施設(shè)置。 · 不知道從什么時(shí)候起,集群中的某些服務(wù)器所用的操作系統(tǒng)、第三方基礎(chǔ)設(shè)施、依賴庫的版本或補(bǔ)丁級(jí)別就不同了。 · 直接修改生產(chǎn)環(huán)境上的配置來改變系統(tǒng)配置。 相反,對(duì)于測(cè)試環(huán)境、試運(yùn)行環(huán)境和生產(chǎn)環(huán)境的所有方面,尤其是系統(tǒng)中的任何第三方元素的配置,都應(yīng)該通過一個(gè)自動(dòng)化的過程進(jìn)行版本控制。 本書描述的關(guān)鍵實(shí)踐之一就是配置管理,其責(zé)任之一就是讓你能夠重復(fù)地創(chuàng)建那些你開發(fā)的應(yīng)用程序所依賴的每個(gè)基礎(chǔ)設(shè)施。這意味著操作系統(tǒng)、補(bǔ)丁級(jí)別、操作系統(tǒng)配置、應(yīng)用程序所依賴的其他軟件及其配置、基礎(chǔ)設(shè)施的配置等都應(yīng)該處于受控狀態(tài)。你應(yīng)該具有重建生產(chǎn)環(huán)境的能力,最好是能通過自動(dòng)化的方式重建生產(chǎn)環(huán)境。虛擬化技術(shù)在這一點(diǎn)上可能對(duì)你有所幫助。 你應(yīng)該完全掌握生產(chǎn)環(huán)境中的任何信息。這意味著生產(chǎn)環(huán)境中的每次變更都應(yīng)該被記錄下來,而且做到今后可以查閱。部署失敗經(jīng)常是因?yàn)槟硞(gè)人在上次部署時(shí)為生產(chǎn)環(huán)境打了補(bǔ)丁,但卻沒有將這個(gè)修改記錄下來。實(shí)際上,不應(yīng)該允許手工改變測(cè)試環(huán)境、試運(yùn)行環(huán)境和生產(chǎn)環(huán)境,而只允許通過自動(dòng)化過程來改變這些環(huán)境。 應(yīng)用軟件之間通常會(huì)有一些依賴關(guān)系。我們應(yīng)該很容易知道當(dāng)前發(fā)布的是軟件的哪個(gè)版本。 發(fā)布可能是一件令人興奮的事情,也可能變成一件累人而又沉悶的工作。幾乎在每次發(fā)布的最后都會(huì)有一些變更,比如修改數(shù)據(jù)庫的登錄賬戶或者更新所用外部服務(wù)的URL。我們應(yīng)該使用某種方法來引入此類變更,以便這些變更可以被記錄并測(cè)試。這里我們?cè)俅螐?qiáng)調(diào)一下,自動(dòng)化是關(guān)鍵。變更首先應(yīng)該被提交到版本控制系統(tǒng)中,然后通過某個(gè)自動(dòng)化過程對(duì)生產(chǎn)環(huán)境進(jìn)行更新。 我們也應(yīng)該有能力在部署出錯(cuò)時(shí),通過同一個(gè)自動(dòng)化過程將系統(tǒng)回滾到之前的版本。 1.2.4 我們能做得更好嗎 當(dāng)然可以,本書就是來講如何做好這件事的。即使是在一個(gè)非常復(fù)雜的企業(yè)環(huán)境中,我們所說的這些原則、實(shí)踐和技術(shù)的目標(biāo)都是將軟件發(fā)布工作變成一個(gè)沒有任何突發(fā)事件且索然無味的事情。軟件發(fā)布能夠(也應(yīng)該)成為一個(gè)低風(fēng)險(xiǎn)、頻繁、廉價(jià)、迅速且可預(yù)見的過程。這些實(shí)踐在過去的幾年中已經(jīng)被使用,并且我們發(fā)現(xiàn)它們令很多項(xiàng)目變得非比尋常。本書所提到的所有實(shí)踐既在具有分布式團(tuán)隊(duì)的大型企業(yè)項(xiàng)目中驗(yàn)證過,也在小型開發(fā)組中驗(yàn)證過。我們確信它們是有效的,而且可以應(yīng)用在大項(xiàng)目中。 自動(dòng)化部署的威力 曾經(jīng)有個(gè)客戶,他們?cè)谶^去每次發(fā)布時(shí)都會(huì)組建一個(gè)較大的專職團(tuán)隊(duì)。大家在一起工作七天(包括周末的兩天)才能把應(yīng)用程序部署到生產(chǎn)環(huán)境中。他們的發(fā)布成功率很低,要么是發(fā)現(xiàn)了錯(cuò)誤,要么是在發(fā)布當(dāng)天需要高度干預(yù),且常常要在接下來的幾天里修復(fù)在發(fā)布過程中引入的問題或者是配置新軟件時(shí)導(dǎo)致的人為問題。 我們幫助客戶實(shí)現(xiàn)了一個(gè)完善的自動(dòng)構(gòu)建、部署、測(cè)試和發(fā)布系統(tǒng)。為了讓這個(gè)系統(tǒng)能夠良好運(yùn)行下去,我們還幫助他們采用了一些必要的開發(fā)實(shí)踐和技術(shù)。我們看到的最后一次發(fā)布,只花了七秒鐘就將應(yīng)用程序部署到了生產(chǎn)環(huán)境中。根本沒有人意識(shí)到發(fā)生了什么,只是感覺突然間多了一些新功能。假如部署失敗了,無論是什么原因,我們都可以在同樣短的時(shí)間里回滾。 本書的目標(biāo)是描述如何使用部署流水線,將高度自動(dòng)化的測(cè)試和部署以及全面的配置管理結(jié)合在一起,實(shí)現(xiàn)一鍵式軟件發(fā)布。也就是說,只需要點(diǎn)擊一下鼠標(biāo),就可以將軟件部署到任何目標(biāo)環(huán)境,包括開發(fā)環(huán)境、測(cè)試環(huán)境或生產(chǎn)環(huán)境。 接下來,我們會(huì)描述這種模式及其所需的技術(shù),并提供一些建議幫你解決將面臨的某些問題。實(shí)現(xiàn)這種方法,實(shí)在是磨刀不誤砍柴工。 所有這些工作并不會(huì)超出項(xiàng)目團(tuán)隊(duì)的能力范圍。它不需要?jiǎng)傂缘牧鞒獭⒋罅康奈臋n或很多人力。我們希望,讀完本章以后,你會(huì)理解這種方法背后的原則。 1.3 如何實(shí)現(xiàn)目標(biāo) 正如我們所說,作為軟件從業(yè)者,我們的目標(biāo)是盡快地向用戶交付有用的可工作的軟件。 速度是至關(guān)重要的,因?yàn)槲唇桓兜能浖鸵馕吨鴻C(jī)會(huì)成本。軟件發(fā)布之時(shí)就是投資得到回報(bào)之時(shí)。因此,本書有兩個(gè)目標(biāo),其中之一就是找到減少周期時(shí)間(cycle time)的方法。周期時(shí)間是從決定進(jìn)行變更的時(shí)刻開始,包括修正缺陷或增加特性,直至用戶可以使用本次變更后的結(jié)果。 快速交付也是非常重要的,因?yàn)檫@使你能夠驗(yàn)證那些新開發(fā)的特性或者修復(fù)的缺陷是否真的有用。決定開發(fā)這個(gè)應(yīng)用程序的人(我們稱為客戶)會(huì)猜測(cè)哪些特性或缺陷修復(fù)對(duì)用戶是有用的。然而,直到使用者真正使用之前,這些全是未經(jīng)過驗(yàn)證的假設(shè)。這也是為什么減少周期時(shí)間并建立有效反饋環(huán)如此重要的原因。 有用性的一個(gè)重要部分是質(zhì)量。我們的軟件應(yīng)該滿足它的業(yè)務(wù)目的。質(zhì)量并不等于完美,正如伏爾泰所說“追求完美是把事情做好的大敵”,但我們的目標(biāo)應(yīng)該一直是交付質(zhì)量足夠高的軟件,給客戶帶來價(jià)值。因此,盡快地交付軟件很重要,保證一定的質(zhì)量是基礎(chǔ)。 因此,我們來調(diào)整一下目標(biāo),即找到可以以一種高效、快速、可靠的方式交付高質(zhì)量且有價(jià)值的軟件的方法。 我們及我們的同修發(fā)現(xiàn),為了達(dá)到這些目標(biāo)(短周期、高質(zhì)量),我們需要頻繁且自動(dòng)化地發(fā)布軟件。為什么呢? · 自動(dòng)化。如果構(gòu)建、部署、測(cè)試和發(fā)布流程不是自動(dòng)化的,那它就是不可重復(fù)的。由于軟件本身、系統(tǒng)配置、環(huán)境以及發(fā)布過程的不同,每次做完這些活動(dòng)以后,其結(jié)果可能都會(huì)有所不同。由于每個(gè)步驟都是手工操作,所以出錯(cuò)的機(jī)會(huì)很大,而且無法確切地知道具體都做了什么。這意味著整個(gè)發(fā)布過程無法得到應(yīng)有的控制來確保高質(zhì)量。常常說軟件發(fā)布像是一種藝術(shù),但事實(shí)上,它應(yīng)該是一種工程學(xué)科。 · 頻繁做。如果能夠做到頻繁發(fā)布,每個(gè)發(fā)布版本之間的差異會(huì)很小。這會(huì)大大減少與發(fā)布相關(guān)的風(fēng)險(xiǎn),且更容易回滾。頻繁發(fā)布也會(huì)加快反饋速度,而客戶也需要它。本書很多內(nèi)容都聚焦于如何盡快得到對(duì)軟件及其相關(guān)配置所做變化的反饋,這包括其環(huán)境、部署過程及數(shù)據(jù)等。 對(duì)于頻繁地自動(dòng)化發(fā)布來說,反饋是至關(guān)重要的。下面關(guān)于反饋的三個(gè)標(biāo)準(zhǔn)是很有用的: · 無論什么樣的修改都應(yīng)該觸發(fā)反饋流程; · 反饋應(yīng)該盡快發(fā)出; · 交付團(tuán)隊(duì)必須接收反饋,并依據(jù)它作出相應(yīng)的行動(dòng)。 讓我們逐一審視一下這三個(gè)標(biāo)準(zhǔn),考慮如何能達(dá)到這樣的標(biāo)準(zhǔn)。 1.3.1 每次修改都應(yīng)該觸發(fā)反饋流程 一個(gè)可工作的軟件可分成以下幾個(gè)部分:可執(zhí)行的代碼、配置信息、運(yùn)行環(huán)境和數(shù)據(jù)。如果其中任何一部分發(fā)生了變化,都可能導(dǎo)致軟件的行為發(fā)生變化。所以我們要能夠控制這四部分,并確保任何修改都會(huì)被驗(yàn)證。 當(dāng)修改了源代碼后,可執(zhí)行代碼當(dāng)然也就會(huì)隨之發(fā)生變化。因此每當(dāng)修改源代碼后,都要進(jìn)行構(gòu)建和測(cè)試。為了能夠控制這個(gè)流程,構(gòu)建可執(zhí)行代碼并對(duì)其進(jìn)行測(cè)試都應(yīng)該是自動(dòng)化的。每次提交都對(duì)應(yīng)用程序進(jìn)行構(gòu)建并測(cè)試,這稱作持續(xù)集成。我們會(huì)在第3章詳細(xì)描述它。 之后的部署活動(dòng)中都應(yīng)該使用這個(gè)構(gòu)建并測(cè)試后的可執(zhí)行代碼,無論是部署至測(cè)試環(huán)境,還是生產(chǎn)環(huán)境。如果你的應(yīng)用軟件需要編譯,你應(yīng)該確保在所有需要可執(zhí)行代碼的地方都使用在構(gòu)建流程中已生成的這個(gè),而不是再重新編譯一次生成一個(gè)新的。 對(duì)環(huán)境的任何修改都應(yīng)該作為配置信息來管理。無論在什么環(huán)境下,對(duì)于應(yīng)用程序配置的變更都應(yīng)該被測(cè)試。如果用戶自己安裝軟件的話,任何可能的配置項(xiàng)都應(yīng)該在各種具有代表性的環(huán)境上測(cè)試。 配置管理將在第2章中討論。 如果需要修改該應(yīng)用程序所要被部署的運(yùn)行環(huán)境,那么整個(gè)系統(tǒng)都應(yīng)該在修改后的環(huán)境中進(jìn)行測(cè)試。這包括對(duì)操作系統(tǒng)配置、該應(yīng)用程序所依賴的軟件集、網(wǎng)絡(luò)配置,以及任何基礎(chǔ)設(shè)施和外部系統(tǒng)的修改。第11章會(huì)講基礎(chǔ)設(shè)施和環(huán)境的管理,包括自動(dòng)化地創(chuàng)建及維護(hù)測(cè)試環(huán)境和生產(chǎn)環(huán)境。 如果是數(shù)據(jù)結(jié)構(gòu)發(fā)生了變化,這些變化也同樣要經(jīng)過測(cè)試。我們?cè)诘?2章討論數(shù)據(jù)管理。 什么是反饋流程?它是指完全以自動(dòng)化方式盡可能地測(cè)試每一次變更。根據(jù)系統(tǒng)的不同,測(cè)試會(huì)有所不同,但通常至少包括下面的檢測(cè)。 · 創(chuàng)建可執(zhí)行代碼的流程必須是能奏效的。這用于驗(yàn)證源代碼是否符合語法。 · 軟件的單元測(cè)試必須是成功的。這可以檢查應(yīng)用程序的行為是否與期望相同。 · 軟件應(yīng)該滿足一定的質(zhì)量標(biāo)準(zhǔn),比如測(cè)試覆蓋率以及其他與技術(shù)相關(guān)的度量項(xiàng)。 · 軟件的功能驗(yàn)收測(cè)試必須是成功的。這可以檢查應(yīng)用是否滿足業(yè)務(wù)驗(yàn)收條件,交付了所期望的業(yè)務(wù)價(jià)值。 · 軟件的非功能測(cè)試必須是成功的。這可以檢查應(yīng)用程序是否滿足用戶對(duì)性能、有效性、安全性等方面的要求。 · 軟件必須通過了探索性測(cè)試,并給客戶以及部分用戶做過演示。這些通常在一個(gè)手工測(cè)試環(huán)境上完成。此時(shí),產(chǎn)品負(fù)責(zé)人可能認(rèn)為軟件功能還有缺失,我們自己也可能發(fā)現(xiàn)需要修復(fù)的缺陷,還要為其寫自動(dòng)化測(cè)試來避免回歸測(cè)試。 運(yùn)行測(cè)試的這些環(huán)境應(yīng)該盡可能與生產(chǎn)環(huán)境相似,從而驗(yàn)證對(duì)于環(huán)境的任何修改都不會(huì)影響應(yīng)用程序的正常運(yùn)行。 1.3.2 必須盡快接收反饋 快速反饋的關(guān)鍵是自動(dòng)化。對(duì)于實(shí)現(xiàn)完全自動(dòng)化過程來說,唯一的約束條件就是你能夠使用的硬件數(shù)量。如果是手工過程,我們可以通過人力來完成這個(gè)工作。然而,手工操作會(huì)花更長(zhǎng)的時(shí)間,可能引入更多的錯(cuò)誤,并且無法審計(jì)。另外,持續(xù)做手工構(gòu)建、測(cè)試和部署非?菰锒矣兄貜(fù)勞動(dòng),與人力資源利用率的準(zhǔn)則相悖。人力資源是昂貴且非常有價(jià)值的,所以我們應(yīng)該集中人力來生產(chǎn)用戶所需要的新功能,盡可能快速地交付這些新功能,而不是做枯燥且易出錯(cuò)的工作。像回歸測(cè)試、虛擬機(jī)的創(chuàng)建和部署這類工作最好都由機(jī)器來完成。 當(dāng)然,實(shí)現(xiàn)這樣的部署流水線是需要大量資源的,尤其是當(dāng)有了全面的自動(dòng)化測(cè)試套件之后。部署流水線的關(guān)鍵目的之一就是對(duì)人力資源利用率的優(yōu)化:我們希望將人力釋放出來做更有價(jià)值的工作,將那些重復(fù)性的體力活交給機(jī)器來做。 對(duì)于整個(gè)流水線中的提交(commit)階段,其測(cè)試應(yīng)具有如下特征。 · 運(yùn)行速度快。 · 盡可能全面,即75%左右的代碼庫覆蓋率。只有這樣,這些測(cè)試通過以后,我們才對(duì)自己寫的軟件比較有信心。 · 如果有測(cè)試失敗的話,就表明應(yīng)用程序有嚴(yán)重問題,無論如何都不能發(fā)布。也就是說,像檢查界面元素的顏色是否正確這類測(cè)試不應(yīng)該包含在這個(gè)測(cè)試集合當(dāng)中。 · 盡可能做到環(huán)境中立。這個(gè)環(huán)境沒必要和生產(chǎn)環(huán)境一模一樣,可以相對(duì)簡(jiǎn)單廉價(jià)一些。 相對(duì)而言,提交階段之后的測(cè)試一般有如下這些特點(diǎn)。 · 它們通常運(yùn)行更慢一些,所以適合于并行執(zhí)行。 · 即使某些測(cè)試有可能失敗,但在某種場(chǎng)合下,我們還是會(huì)發(fā)布應(yīng)用程序。比如某個(gè)即將發(fā)布的版本有一個(gè)不穩(wěn)定的修復(fù),會(huì)導(dǎo)致其性能低于預(yù)先定義的標(biāo)準(zhǔn),但有時(shí)我們還是會(huì)決定發(fā)布這個(gè)版本。 · 它們的運(yùn)行環(huán)境應(yīng)該盡可能與生產(chǎn)環(huán)境相同。除了測(cè)試功能以外,它同時(shí)還會(huì)對(duì)部署過程以及對(duì)生產(chǎn)環(huán)境的任何修改進(jìn)行測(cè)試。 先經(jīng)過一輪測(cè)試(在便宜的硬件上運(yùn)行最快的那些測(cè)試)之后,再經(jīng)過這種測(cè)試過程,會(huì)讓我們對(duì)軟件更有信心。如果這些測(cè)試失敗了,這個(gè)構(gòu)建版本就不會(huì)再進(jìn)入后續(xù)階段,這樣就可以更好地利用資源。第5章中會(huì)詳細(xì)介紹流水線技術(shù),而第7、8、9章中會(huì)分別講述提交測(cè)試階段、自動(dòng)化驗(yàn)收測(cè)試,以及非功能需求的測(cè)試。 這種方法的基礎(chǔ)之一就是快速的反饋。為了確保對(duì)變更的快速反饋,我們就要注意開發(fā)軟件的流程,特別是如何使用版本控制系統(tǒng)和如何組織代碼。開發(fā)人員應(yīng)該頻繁提交代碼到版本控制系統(tǒng)中,像管理大規(guī)模團(tuán)隊(duì)或分布式團(tuán)隊(duì)那樣,將代碼分成多個(gè)組件。在大多數(shù)情況下,應(yīng)該避免使用分支。我們將在第13章討論增量式交付以及組件的使用,在第14章中討論分支與合并。 ……
你還可能感興趣
我要評(píng)論
|