最近聽了
ECUG
大會上孫敬雲老師的分享感覺受益匪淺,畢竟大學課本上隻講到
瀑布模型
就沒有下文了,工作以後一直貫徹的都是
Scrum
路線,一直也沒有時間好好的去學習整理這部分的知識,直到近幾天聽到了孫老師的分享,是以就在這裡記錄下孫老師的分享也總結我自己的思路。以下内容部分摘自于孫老師的分析PPT
1 軟體工程之路
1.1 軟體工程的演進
貌似大學的那門軟體工程隻給我們講到了1980年,之後的需要我們走出校門,在社會中進行學習。
先來看下面這張圖,是1980年至今的軟體工程演化路線,像瀑布模型大家應該是耳熟能詳。
進入1990年,Scrum這種,近幾年應該也是略有耳聞,可是像
極限程式設計
這種可能就很少聽說了吧。
再向後看,進入2000年,
持續內建
也就是
CI/CD
中的CI和
靈活開發
近幾年炒的火熱,網際網路公司争先恐後,
kanban
(今天公司産品說,我才知道kanban是日本人發明的)也有點大勢已去,不過市場上應該還有不少公司在使用kanban。
走到了2010年,我們所看到的應該就是幾個随處可見的概念了,
持續傳遞
,
DevOps
,
Scrumban
(我們近幾年說的真正意義上的Scrum)
1.2 瀑布模型
在這裡不詳細叙述,隻叙述幾個痛點。
- 産生客戶價值周期長
- 部門、角色之間存在壁壘
- 無法及時響應需求變化
- 價值流動不可見
1.3 靈活開發
靈活軟體開發(英語:Agile software development),又稱靈活開發,是一種能應對快速變化需求的軟體開發能力。它們的具體名稱、理念、過程、術語都不盡相同,相對于“非靈活”,更強調程式員團隊與業務專家之間的緊密協作、面對面的溝通(認為比書面的文檔更有效)、頻繁傳遞新的軟體版本、緊湊而自我組織型的團隊、能夠很好地适應需求變化的代碼編寫和團隊組織方法,也更注重軟體開發過程中人的作用。
說人話,就是更注重溝通,快速産出新版本,并且更适應需求變更的的适合小團體開發的方法。
下圖左方,是需求池的概念(比如jira中的backlog),比如7%的需求是現實中大量客戶的需求,則我們将這7%的需求作為優先級最高的需求。
下圖右方,是疊代和回報的概念。
靈活開發中有靈活宣言,可以更好地闡述靈活開發的概念。
- 個體和互動高于流程和工具(靈活開發的站會落實了這一點)
- 工作的軟體高于詳盡的文檔(jira、miro等更好地代替厚重的需求文檔)
- 客戶合作高于合同談判(公司内各部門甩鍋情況,難道不應該用合作為公司創造價值嗎)
- 響應變化高于遵循計劃(快速響應時長需求,而不是錯過市場變化)
1.3.1 Scrum實踐
下圖右上方是Scrum中的角色定義。
- Product Owner(産品負責人,主要負責産品設計,需求篩選等)
- Scrum Master(靈活主管,主要負責項目疊代跟進等)
- Scrum Team(靈活團隊,主要負責需求的研發測試部署等,包括Dev、Test、Ops等)
下圖左方是
使用者故事
(
user story
),其實就是我們傳統意義上的需求,隻不過以一種需求方的更委婉拟人的語氣來講述該使用者人群的需求。
例如:我是一個買家,我希望我的購物車能通過價格排序,這樣我就能根據我卡中的錢進行合理的消費。
下圖中部,則是Scrum的核心流程。有很多公司光注重了其中的流程(比如站會),卻沒有得到其中的精髓。Scrum中把一個疊代叫做一個
沖刺
(
Sprint
),這也是很多地方把計劃會議叫做沖刺會的由來,一般一個Sprint為1~4周。核心流程包括4個會議,如下所示:
- 計劃會議(Product Owener、Scrum Master、Scrum Team)
- 從Backlog中按照優先級選擇這個Sprint要做的User Story
- 向團隊解釋澄清User Story的需求,并決定是否将User Story拆解為更細粒度的
Sub Task
- 團隊估計User Story的
(用以評估story的大小,有一種好玩的方式叫做Story Point
)Scrum Poker
- 團隊決定是否将User Story拆分Sub Task來進行跟蹤
- 決定這個Sprint的目标和傳遞的User Story
- 每日站會(Product Owener(可選)、Scrum Master、Scrum Team)
- 站會維持在15分鐘以内,分早晚
- 團隊成員講述圍繞3點:我做了什麼,我将要做什麼,我遇到什麼困難
- 每人陸續進行講述,為了快速響應,維持最新消息,包括需求調整等
- 以及進行高效溝通,傳遞資訊,拒絕資訊發散
- 确定相關問題後,團體相關人員小範圍讨論
- 評審會議(Product Owener、Scrum Master、Scrum Team)
- 類似于傳統意義上的驗收階段
- 介紹Sprint結果,按User Story順序示範新功能
- 回答相關人員對展示的疑問,并記錄其所期望的更改,收集回報
- 如果遇到一些還沒解決的障礙,則将障礙加入障礙Backlog
- 以User Story作為是否成功傳遞的标準來評價任務完成情況
- 回顧會議(Scrum Master、Scrum Team)
- 回顧這個Sprint,收集Sprint的相關資料
- 産生見解,多問為什麼,找到各個方面的優缺點,進行複盤分析
- 進行頭腦風暴分析解決方案,投票選出下期的改進項
- 探索提高效率和品質的方式
1.3.2 極限程式設計(XP)實戰
極限程式設計
是靈活開發中最具成效的幾種方法之一,如同其他靈活方法,它和傳統方法的本質不同在于它更強調可适應性能性以及面臨的困難。
它的基礎和價值觀是:
- 交流(加強交流,解決資訊不同步導緻的問題)
- 樸素(秉持最小可用,勤于疊代,不做拍腦袋的無用功擴充)
- 回報(多接受回報,以進行快速調整修改)
- 勇氣(在該重構時重構,當狀态不對時,放棄思考,調整狀态後重新思考)
它認為任何一個軟體項目都可以從四個方面入手進行改善:加強交流;從簡單做起;尋求回報;勇于實事求是。
下圖是極限程式設計的13個最佳實踐。
1.3.3 思考自己的團隊是不是靈活
問問自己下面的幾個問題:
- 成員是否氫氣的知道團隊的目标?
- 成員是否可以預測結果并且充滿信心?
- 成員是否主動做事并且為此負責?
- 成員是否願意持續改進團隊?
如果你對上述幾個問題的回答時肯定的,那麼恭喜你,你們的團隊是關注發展的靈活團隊,如果你對上述問題有部分或全部否定,那麼你可能需要調整你的團隊,你們隻不過是在關注靈活的形式,而沒有精髓。
1.4 DevOps模型
DevOps
是一種開發、測試和運維之間文化溝通,通過自動化的方式來進行軟體傳遞和架構變更的流程,使建構、測試、釋出軟體能更快捷、頻繁、可靠。它的出現是因為軟體逐漸的認識到,開發、測試和運維的緊密合作可以更好的傳遞軟體産品和服務。
下圖是DevOps的标準化流程,通過建立一個完備的團隊來建立一條IT服務供應鍊,通過自動化實作高效率傳遞,不固定需求管理、工具鍊等,隻專注于持續的穩定的價值傳遞
2 三部工作法
2.1 第一工作法(工作流)
這一步工作法是關于從開發到運再到客戶的
自左向右
的
工作流
2.1.1 定義工作流
下圖展示了自循環工作流的流程,其中前4項屬于Dev範疇,後4項屬于Ops範疇:
- plan(計劃)
- code(編碼)
- build(建構)
- test(測試)
- release(釋出)
- deploy(部署)
- operate(操作)
- monitor(監控)
2.1.2 工作流實踐
下圖左方是我們針對上面的工作流的一種實踐,是一種工作日志的方式,這種工作方式同樣适用于靈活開發(jira中的工作日志),其實DevOps的本質就是靈活開發。
- 過程名稱
- 輸入
- 輸出
- 工具
- DoD(Definition of Done,完成的定義,可以了解為完成的标準)
- 平均前置任務等待數(完成目前任務,依賴等待了多少任務)
- 手工比例(手工操作的步驟占據了總量多少)
- %C/A(返工名額,完成時間/總花費時間,總花費時間=完成時間 修複時間)
- 處理時間PT(真正處理該任務所花費的時間)
- 流動時間FT(從接收到需求到需求完成所花費的時間)
通過上方工作日志所記錄的資料,我們可以對我們的工作進行階段性的分析,比如:
-
可以用來判斷我們的任務配置設定是否合理平均前置任務等待數
-
可以用來提示我們是否需要使用自動化來優化流程手工比例
-
可以用來判斷一個人的工作品質是否需要優化%C/A
- 等等
2.1.3 版本和分支政策
2.1.3.1 普通版本管理
- 新需求拉一條新的分支進行開發,命名
xxx feature branch
- 新bug拉一條新的分支進行修複,命名
xxx fix branch
- master分支保持永遠可建構成功狀态
- 每當新需求或新bug完成合并到主分支,觸發主分支的pipeline建構流程
2.1.3.2 GitFLow實踐
這種方案是基于
GitFLow
的标準來進行版本控制的。
該方案采用
develop
、
feature
、
hotfix
、
release
、
prod
等分支進行實踐,比較适合版本并存的團隊
- develop:主開發分支,包含所有釋出到下一個release的代碼
- feature:新功能開發分支,最後會合并回develop分支
- hotfix:prod發現bug時,用來熱修複分支,最後會合并回develop分支
- release:釋出版本時,基于develop建立的分支
- prod: 用于釋出到生産環境的代碼的分支,隻能合并不能修改。
這種方式很靈活,代碼隔離也很好,隻是過于繁瑣。
2.1.3.3 tag版本實踐
該方案是基于版本打tag的方式來進行版本控制的。
該方案采用
master
、
feature
、
fix
等分支進行實踐,比較适合小版本滾動更新團隊
- master:主分支,該分支不允許修改,隻允許合并,該分支永遠保持可建構狀态,釋出時通過tag來進行版本釋出
- feature:新功能開發分支,最後會合并回master分支
- fix:線上發生bug後,用于修複的分支最終會合并到master分支
這種方式很簡單,但是對多環境的支援不是很好。
我們推薦使用GitFlow Tag的方式來進行版本控制。以觸發多環境下的pipeline自動化流程。
2.1.4 規劃流水線
這裡主要是我們的CI/CD的流水線的結構,可已使用
Jenkins
的pipeline也可以使用
Gitlab
的pipeline。
這裡連結下之前寫的Jenkinsfile教程(Jenkins Pipeline 教程)
自動:
- 代碼檢測(推薦使用SonarQube,教程)
- 單元測試(很重要,java可使用junit,其他的未調研)
- 制品(過去的jar包,如今的docker image)
- 內建測試(很重要,屬于自動化測試中的一個重要環節)
- 性能測試(大部分場景下可能不會每次都做)
- 安全測試(跟性能測試差不多)
- 部署預釋出(這裡泛指線上以下的所有環境)
手動:
- 驗收測試
- 部署線上
2.1.5 Scrum XP DevOps流程
看過了上面的部分,你一定嗤之以鼻,因為下面的圖其實就是上面的Scrum圖 Pipeline的圖。其實下面你的這張圖才能真正意義上的指導我們如何在工作中實踐Scrum DevOps。我将下面的圖分層了4塊,讓我們一起看看下面的圖吧
Scrum XP流程
第一部分的需求池的這個概念我們在上方的Scrum中已經看到了,在這裡不做詳細解釋,如果記不太清了,可以回到上方#1.3.1 進行複習。
第二部分的Scrum流程需要我們再來回顧一下,一個疊代中的4個會議還記得嗎,不記得就回去看看吧,通過小疊代來進行可持續的速度小型釋出,其中要落實XP的13個實踐,包括集體所有權、簡單設計、重構等等。
CI/CD
通過代碼版本控制來觸發我們的的CI和CD的建構。
通過釋出編碼标準,測試驅動開發,代碼riew等來提升我們的代碼品質以進行優質的代碼持續內建。
在持續內建之後,迎面而來的是建構、測試、部署,這幾個步驟的才是真真正的表現我們的團隊的持續傳遞的品質。
在3和4兩個步驟,我們會看到下方有包含對号和錯号的表格,這個我們會在接下來的地方講到,這個是個CI/CD回報表,用來表示我們某個階段的CI/CD的縮略情況,可以通過這個回報來進行相關的分析。
2.2 第二工作法(回報流)
2.2.1 持續回報
下方的圖是CI/CD的持續回報圖,可能做過Jenkins的Pipeline的小夥伴已經能看出它了。
頂部的“表頭”其實就是我們的Pipeline的流程,而每一行是我們的曆史建構記錄,通過這張圖我們可以清洗的看到我們在某一階段的pipeline的執行情況,就可以看到我們在哪一個節點發生錯誤的情況比較高。
在這個流程中最重要的就是測試部分,如果我們的團隊對包括單元測試在内的測試環節如果不是很重視,那這個回報将對我們的團隊毫無意義。
在DevOps中,我們推崇測試驅動開發,通過先寫單元測試,內建測試等用例來驅動我們的開發進行編碼。
2.2.2 檢視在制品
這裡的制品的含義就是我們所建構的,比如java的jar,golang的native,docker的docker image等。
通過DevOps的回報,我們可以檢視制品所在的story的目前階段
2.3 第三工作法(學習)
2.3.1 不斷嘗試和重複學習
讓我們再來看下面這張圖,對比上面的那種圖,在我們的編碼、測試、部署三個階段多了個小錘子的标志。
這裡的編碼、測試、部署,分别代表着開發、測試、運維,三個崗位需要不斷的嘗試、配合和重複學習來讓這條IT服務供應鍊更快速更穩定更自動化,讓資訊回報更精準、更全面的覆寫到整個服務生命周期。
2.3.2 測試四象限
首先畫一個由x軸支援評價和y軸業務技術導向組成的四象限,我們将我們DevOps中的所有種類的測試流程放入其中,來将每一個測試落實在一個二維區間内,再在每一種測試上辨別一個工作投入程度,組成下面的圖。
我們之前提過,在XP極限開發中,我們推崇測試驅動開發,因為測試驅動開發可以讓我們在開發之前更加深入的了解業務,并且基于接口定義程式,更好的組織我們的軟體架構。
是以下圖是我們的測試流程應在我們的工作中所占有的工作比例,如果所有的工作經曆為100%的話,那麼6顆星則為60%,每顆星占據10%。
良好的開發習慣,和标準的測試流程可以讓我們的代碼品質更上一層樓。
2.3.3 運維四象限
上面我們說了測試的四象限,這裡我們說說運維的四象限,我們以緊急性為x軸,重要性為y軸,這個四象限其實是很多工種的人都會使用到的,會将我們每天的任務放到裡面,用來确定任務的優先級,我們知道基于這種四象限,我們的優先級會有下方四種:
- 緊急且重要
- 緊急不重要
- 重要不緊急
- 不重要不緊急
我們将運維的工作放在上面,如果大部分的工作都落實在緊急且重要的第一象限上的話,那麼說明我們的DevOps流程是有問題的,比如我們的運維的大部分精力都在每天的線上緊急修複之類的任務,就說明我們的開發和測試的品質是有問題的。
運維的工作不應該重點在右方,而應該重心左移,偏向于重要不緊急,多做一些規劃性的工作,比如從傳統部署方式轉向k8s容器編排等工作。
3 工程化指南
3.1 實踐整合
在上面我們将上面說講述的知識合并起來,組成我們真正在工作中實踐所要用到的東西。Scrum XP DevOps
3.2 建立工程師文化模型
小團隊内部要做到:
- 可視化面闆和主動領取任務(資訊扁平化,加速效率,共同目标幫助隊友完成任務)
- 成為使用者故事的負責人(每個人都要有主人翁意識,認為自己是UserStory的主人)
- 20%的非功能性需求(給開發一點非業務的技術需求,提升多巴胺,産生樂趣)
- 合入主幹的代碼需要稽核(合代碼需要組内review,降低代碼出問題的機率)
- 周期性的技術分享(每個人都要分享,對自己所學到的東西進行沉澱,同時也吸取組内其他人的分享)
公司級别:
- 舉辦黑客馬拉松(選擇一個主題,讓公司的開發進行參與,進行開發,讨論,提升技術激情)
- 舉辦技術沙龍
3.3 目錄結構
定義每種語言的标準的目錄結構,比如下方的目錄結構就是Node.js的标準目錄結構,我将一些語言級通用的結構用紅框畫了出來。
- src
- test
- .env
- Compilefile
- Dockerfile
- Jenkisnfile
3.4 版本控制規劃
下圖使用的是基于Tag的版本控制,我這裡看推薦使用GitFLow Tag的方式來進行基于Tag多多環境的版本控制的方式進行建構使用。
3.5 快速失敗的流水線
下圖中的快速失敗的概念是指當pipeline中某一節點未達到通過的要求,則不再運作之後得節點,以目前節點的失敗為整個pipeline的失敗。
像jenkins原生就相容快速失敗。下圖是jenkins最新的Blue Ocean界面,很友好的。
3.6 可視化回報平台
在第二工作法中,我們學習到了回報工作流,如果使用jenkins建構pipeline的時候,我們就可以通過jenkins原生支援的可視化結果來了解到我們近期的CI/CD情況。
3.7 持續改進
在我們的産品設計中,有一個
MVP
的概念,它的意思是
最小可行産品
,這個概念來自于《精益創業:新創企業的成長思維》這本書中,書中提倡首先定義一個面向市場的最小可用的極簡原型産品,然後再不斷的試驗和學習中,以最小的成本和最有效的方式來驗證産品是否符合使用者需求,靈活調整方向,以達到“快速失敗,廉價失敗”的方式來驗證産品是否符合市場需求。這是一種不斷學習,挖掘使用者需求,疊代優化産品的方式。
我們對待我們的團隊,其實也要像對待我們的産品一樣,不停地學習,不停地嘗試,不停地優化,這樣讓我們的團隊快速成長,要允許我們的團隊犯錯(但是不能重複掉進相同或相似的坑中)。
3.8 更多的品質保證
3.8.1 CI/CCD
通過良好的測試 自動化流水線來提高我們的代碼的品質
在部署前:
- 內建測試
- 性能測試
- 安全性測試
部署後測試:
- 自動化測試
- 驗收測試
3.8.2 環境與配置管理
通過配置中心來差別應用在各個環境中的配置,以防止出現踩到帶着開發測試的配置上線的這種老舊坑。
3.8.3 制品庫管理
制品庫推薦也同樣隔離開,預發和生産使用同一個制品庫,開發和測試使用同一個制品庫,在兩個制品庫之間,需要人為來稽核和同步。
3.8.4 流程控制
這裡的流程控制主要指的是CI/CD的流程控制。因為我們都知道jenkins單節點在同一時間自由一個pipeline能建構,也就是說單節點jenkins不能多條pipeline并發建構。是以我們需要搭建分布式的jenkins叢集,來對pipeline的建構進行排程。
另一種更好的方式就是通過gitlab或其他支援并發pipeline建構的工具進行建構。
下方的pipeline中在測試環節分成了三個分支,這個特性我們再使用jenkins的pipeline時是有完美支援的,名字叫并行流,是根據條件來判斷三個分支是否進行的。
3.8.5 資料收集和監控
我們的服務上線後,我們需要使用兩種方式來確定我們線上使用的服務能夠健康的提供服務。
- 日志
- 監控
通過采集我們的線上的服務的日志,來對線上日志進行分析,達到實時監控服務健康情況的需求。這裡推薦使用市場較為開放通用的開源方案ELK
我們同時還要對我們的中間件,流量,實體硬體等進行相關監控,以确定基礎環境的實時監控情況,這裡我推薦使用Prometheus Granfa進行監控。
3.8.6 容災
當我們的應用日益複雜且使用者量逐漸提高後,我們需要對我們的服務進行容災配置以及周期醒的混沌工程演練。我們的服務應該像下圖一樣逐漸進階為可用性更高的部署方式。
3.8.7 緊急事件處理
我們永遠都不能問心無愧的拍着胸口說我們的服務非常的問題,可用性能達到100%。因為100%是我們的服務的可用性極限,就算我們的服務可用性做到6個9,8個9,但是永遠也達不到100%,永遠隻能無限的趨近于100%。因為我們永遠都沒辦法避免黑天鵝事件。但是我們能做的是出現黑天鵝事件後,我們要快速響應,将我們的損失降到最低。下面就說說當出現線上故障的時候,我們應該怎麼做才能更好的減少我們的損失。
事故發生前(凡事有預案):
- 提前準備可能出現的事故
- 全員參與容災演練
- 多做混沌工程,提高服務的可用性和健壯性
事故發生時(先通報,後處理):
- Ops和Dev互相通報
- Ops和Dev各自向上級彙報
- 主管決定是否繼續向上級彙報
事故進行中(先止損,後查因):
- 是否有處理預案
- 有預案,Ops主管10分鐘内做復原決定
- 無預案,Ops主管和Dev主管決定復原和補救方案
事故處理後(反思,定級):
- Ops通報事故處理結果
- 24小時内主要責任部門牽頭矩形Case Study
- 對事故進行定級
本文來自納蘭小築,本文不予回複,評論請追溯原文
檢視原文