之前在文章《什麼是MLOps?》介紹過 MLOps 與 DevOps 的差異,但是並沒有從頭解釋 DevOps 的精神與原則是從哪裡來的。最近終於讀完這本《鳳凰項目》,發現這本書在 IT 領域的地位,就相當於工業工程領域的《目標》一般,是一本教科書級的小說,且裡面引用了相當多的工業工程理論來解決軟體工程問題。
身為工業工程畢業後轉職做 IT 產業的打工人,因此對這本書大量引用《目標》的內容覺得格外親切,特別推薦從工工往資工換跑道的學弟妹來看這本書(或這篇文章)。如果是工業工程專業或者是有學習過生產管理學分的讀者,想往 IT/CS 領域轉職的話也十分推薦看這本書。
本篇文章會引用書中的論點,並且用工業工程的術語解釋軟體工程中碰到的管理問題與解決方法,並且不涉及 IT/CS 專業的領域知識。
生產管理 v.s. 軟體開發的共同問題
《鳳凰項目》書中有一個關鍵的角色艾瑞克,可以同等於《目標》裡面的鐘納。在《目標》裡面,鐘納身為一個物理學家卻能直視生產管理的核心問題;在《鳳凰項目》裡面,艾瑞克用車間工廠的管理理論來類比軟體工程裡面的效率問題。
軟體工程的問題是看不到摸不著的,而生產管理的問題確實十分具現化,並且問題的核心點驚人的相似。所以下面我也會用生產管理來類比軟體工程中碰到的種種問題,讓軟體工程的問題更加清晰可見。
流水線生產 v.s. 瀑布式開發
工業革命後,人們發現了分工+重複勞動可以增加生產效率,因此大量的工廠使用了流水線的生產方式:一個工人只負責一件工作,然後利用輸送帶把原物料送過每一個站點,最後變成完成品。
瀑布式軟體開發 (Waterfall Development) 與流水線生產的原理是類似的。我們把巨大的軟體切割為 5 個步驟:需求分析、設計、實作、測試、維護。當整個開發工作流從上走到底時,整個大型軟體就完成了。
流水線生產與瀑布式開發雖然是製造業與 IT 產業早起規模化的成功方法,但是在產業與時並進的過程中也逐漸發現發現了很多問題,並且這些問題在這兩個行業中同時存在且驚人的相似。
問題1:大量的庫存與半成品
流水線最大的問題就是庫存與半成品 (WIP, Work in Progress)。為了讓流水生產線達到最高效率,就必須在輸送帶上佈滿大量的 WIP,確保每一個工人都不會閒下來,達到每個工人的最大效率。但是這種做法讓必須在生產線上堆滿了大量的 WIP,而且這些 WIP沒有辦法立刻走出工廠變成現金流,造成了巨大的浪費成本。
瀑布式軟體開發存在著相同問題。大型軟體的中間產出並沒有辦法獨立作為一個軟體賣給客戶,也不能產生任何價值。開發人員花費了時間寫好的 Code,只能囤積在 Git/SVN 裡面等著最終軟體完成。這些 Code 都是軟體開發的 WIP。
問題2:Lead Time 過長
生產管理中有一個專業術語叫做 Lead Time,就是工廠內把原物料變成成品的所需時間。因為流水線的 Lead Time 非常長,所以為了即時響應客戶的訂單,工廠必須預先在生產線上投入,以預測來滿足客戶的需求。這會造成各種的「浪費」,包括生產線上「半成品浪費」,沒有客戶下單的「庫存浪費」,等待前一批物料加工完的「等待浪費」…這些浪費大大的增加了生產線的隱形成本。
同樣的,在瀑布式開發裡面,大型軟體的開發週期——也就是 Lead Time——是非常長的。在這個冗長的 Lead Time 裡面,Git/SVN 裡面堆滿了大量的 Code,且客戶在沒看到最終的軟體之前也不會買單。這些都一一對應了生產開發的各種浪費。
問題3:搬運的浪費
在生產線中,搬運是最不可避的浪費之一,因為搬運完全無法創造價值,也無法完全消除。因此我們試著用設施規劃等專業能力,來儘量讓每個工作站之間達到最小距離,避免 WIP 消耗時間在無意義的搬運上。
軟體開發裡面,雖然並不存在「物理」的搬運,但卻存在「組織」之間的搬運。例如:小組 A 開發完某個功能要給小組 B 繼續開發剩餘的功能,這期間需要用郵件、電話、文件等方式,透過溝通協作完成這個功能的轉移。這就是在軟體開發中的「搬運浪費」。
問題4:不良品
在流水線加工中,任何工作站的良率過低都會造成生產線的效率平衡被打破。在最嚴重的情況,工廠甚至必須停掉整個生產線來排除問題。如果不這麼做,等到最後品質檢驗才發現不通過,整批原物料將會直接報銷,造成更大的浪費。
在瀑布式軟體開發裡面,如果某個功能出現了問題,很可能必須倒推所有上游重新修改,甚至會回退到前一個瀑布流。這對瀑布式軟體開發的殺傷極大,因為所有開發流程都必須要倒退,甚至有可能要改變設計規格。
工業工程的改善方法
以上我們已經描述了生產管理與軟體工程中面對的共同問題。經過多年的研究,工業工程領域推出了很多的經典理論與方法來解決工廠裡面碰到的問題。下面簡述幾個比較經典的理論與方法。
限制理論 Theory of Constraint
限制理論的核心觀點在於:整個生產線的生產效率是由瓶頸工作站的生產效率決定的,對瓶頸之外的任何工作站改善效率都只是假象。因此,改善生產效率的第一步就是識別瓶頸工作站。找到瓶頸工作站之後,利用各種手段改善工作站的生產效率,例如:最小批次、改善機台效率、改善工作方法、工作外包…等等。當工作站不再是瓶頸之後,再去尋找下一個瓶頸,並且持續改善。
軟體開發中也會碰到相同的問題。在《鳳凰項目》裡面,公司的開發瓶頸人員是布倫特,所有的任務幾乎都會走到布倫特手上,因此拉低了整體的團隊效率。書中主角做的工作無外乎就是消除瓶頸:限制提交工作給布倫特、培養新人分擔布倫特的工作、避免布倫特做重工…等等。這些解決手段與生產管理裡面消除瓶頸的方法都很類似,就是想盡辦法消除對瓶頸的依賴。
精實生產 Lean Production
精實生產是從豐田式生產中延伸出來的生產方法,其中最核心的精神是 JIT (Just in Time) 生產。JIT 生產的核心理念是實現「0 庫存」,用最快的 Lead Time 來滿足客戶的需求,藉此來降低浪費。為了實現 JIT 的 0 庫存生產,精實生產必須工廠自發性的嘗試變革生產流程,來改善流水線生產的不足。
在精實生產中,組織會推行一個精實生產小組,並設立實驗試點。在實驗試點裡面,小組成員會試著尋找更高效的方法來取代現有方法。比方說尋找更高效的機器用法、更好的工作流程等等。記得以前上課的時候有一個印象深刻的例子:豐田內部設計的精實生產工作站讓一個工作人員能夠負責整個汽車座椅的組裝,並且發現這種作法的 Lead Time 比流水線的生產還要高。
精實生產中的另一個原則是持續改善。精實生產是個永不止境的改善過程,發現問題、分析問題、解決問題,並且不斷循環。因此,精實生產中也分出了許多管理方式與學科,例如 6 Sigma,來幫助快速的辨識並改善問題。
軟體開發的改善手段
軟體開發引入了限制理論、JIT 生產等等概念,推翻了瀑布式開發創立了新的開發典範——敏捷開發。敏捷開發也進一步延伸了許多的開發方式與工具,其中最終集大成者就是 DevOps。
敏捷開發 Agile Development
敏捷開發取代了瀑布式開發成為了現在的主流開發方法——如同精實生產取代了流水線生產一樣。敏捷開發的核心理念與精實生產完全相同,試著用最快的方式將產品送到顧客的眼前。其中最核心的方法論可能是 Scrum & Sprint。
Scrum 是橄欖球中的一個進攻回合,團隊成員試著要在 3 次進攻內推進到足夠的距離。在敏捷開發裡面,Scrum 會要求團隊在一個不超過四週的短週期裡面進行衝刺 (Sprint),在短時間將產品送到客戶手上,並且根據客戶的反饋在進行修改,規劃下一次的 Scrum。
Scrum 的開發方式與 JIT 生產方式是高度相似的,儘量把所有的工作都轉化為客戶的價值。透過短期的 Scrum,我們可以快速的辨識什麼是客戶感興趣的,什麼是客戶覺得不需要的,以此來規劃我們的軟體開發流程。
持續集成 Continuous Integration
如同精實生產中需要消除不良品並且持續進行改善實驗一般,在軟體開發中,我們同樣會想著在不出 bug 的情況修改舊的程式或功能,甚至是確保新功能的程式執行正確。這個時候可以使用測試驅動開發 (Test Driven Development, TDD),預先寫好單元測試程式,再開始撰寫功能程式,確保程式執行符合規格。
進一步的,如果我們使用自動化的方式,當 Code 被提交到 Git/SVN 的時候就能夠執行這些測試,就可以在第一時間知道 bug 並且避免發佈到線上系統。這個自動化的 bug 檢測與合併 Code 的工作設計就是持續集成 Continuous Integration,簡稱 CI。
三步法 Three Ways
最終,我們要回歸到精實生產的持續改善原則。在 DevOps 中把持續改善原則描述為三步法 Three Ways。
第一步的目的是將軟體開發 (Dev) 的工作快速完成並且往軟體運維 (Ops) 方向去流動。用工業工程的術語來說,這一步就是在減少 Lead Time,試著辨識開發中的瓶頸並且運用一切手段去消除瓶頸並提升效率。
第二步的目的是將軟體運維 (Ops) 的結果流回軟體開發 (Dev)。在生產管理中,工廠需要對產品負責,並且將客戶反饋的問題與投訴返回給製造部門。在軟體開發中,同樣也需要直面客戶問題,同時需要觀察程式 crash 率、記憶體佔用率、CPU佔用率等效能指標,並將這些問題返回給 Dev 做下一輪的開發規劃。
第三步是持續的優化與學習,這完全對應了精實生產的持續改善原則。這其中需要進行實驗性的探索,試著改善目前的最佳效率。DevOps 而如何在探索的期間維持軟體品質,並且利用 Scrum & Sprint、CI/CD 等開發流程與工具來輔助第三步的持續更新。
DevOps
最終,將上述的所有概念濃縮成一個圖,就會變成之前的文章中提到的這個 DevOps 概念圖:
左半邊的黑色對應的是 Three Ways 的第 1 步:從 Dev 往 Ops 的流動;右半邊的綠色對應的是 Three Ways 的第 2 步:從 Ops 往 Dev 的回流。而整個圖形構成了一個無限的符號,表示的是 Three Ways 的第 3 步:持續優化。
DevOps 背後的精神
DevOps 已經發展十年左右。現在講起 DevOps,很多人都可以講出裡面的方法論與工具,但是卻對背後的精神一無所知,甚至完全無視。
其實無論在任何國家、任何公司、任何產品,任何一個 IT 開發流程都一定存在著問題:百變的客戶需求、一直出現的 bug、不合理的時間壓力,會耗去你所有的精力。DevOps 裡面的確是許多現成的方法論,例如工作看板、CI/CD,可以解決眼前的部分問題;但新問題總是一個接一個,永遠不會有解決完的一天。
如果你把 DevOps 的流程圖看成兩個圓圈,你會覺得這兩個圓圈就是解決問題的工具與手段。但直到你將之視為無限符號,才會理解到 DevOps 本來就是持續改善的過程,而工具終究只是工具,不斷的嘗試與突破才是 DevOps 的背後精神。