1. 程式人生 > >鍊金術(8): 開發和釋出的並行

鍊金術(8): 開發和釋出的並行

在一個技術群裡,遇到一個網友提了一個問題,這種場景我曾經遇到過,提供一種解法,這需要去構建,但是如果需要的是【立即有效】的解法,可能不存在。這個方式,最小的情況下3人的迷你小team就可以實施,所以可以說是一個面向小企業的團隊的介紹。麻雀雖小,五臟俱全,要用好的排程、原則、自動化工具帶來效率和自由。

一個網友的問題:

為了趕時間,dev和pub並行,我一天發五六版,不是在發版就是在發版的路上,就是發版太頻繁 導致我沒時間開發。
問題其實在於業務方,業務為了給領導看,我軟體沒做好,他們就用,我現在一邊開發一邊維護一個線上版本,他們還在往裡錄入資料,導致的結果就是,問題要馬上解決,解決後要發版本然後我還在開發。

怎麼辦?

首先,原始碼的分支,和部署的環境需要隔離。

  1. 原始碼要有不同分支,釋出的分支上,只修復BUG。開發的分支是新功能。
  2. 部署的環境要有三套,一套是開發的,一套是測試的,一套是正式的。
  3. 請使用好的git版本線檢視工具,例如sublimemerge

你在Git的開發分支上開發新功能,部署的時候只能部署到開發環境。
你在Git的釋出分支上修復BUG,部署的時候先部署到測試環境測試,測試驗證通過了再發布到正式環境。

其次,工具鏈要做成自動化:

  1. 配置不同環境的部署資訊,例如用JSON配置好某個環境的所有依賴的配置資訊+賬號密碼,這個配置檔案不提交到git倉庫。
  2. 編寫部署的指令碼,一鍵部署某個Git分支的當前程式碼到某個部署環境上去。
  3. 如果進一步,可以將自動化部署配置到內部的持續整合(CI)工具上,但是,這要仔細考慮密碼的儲存問題。確保安全。此處可以進一步考慮。

接著,問題應該有issue管理軟體整理

  1. 應該用一個issue管理軟體管理客戶提交的問題。例如,redmine、jira、teambition等。
  2. 在issue管理軟體上建立不同的分支標記,例如1.1.1表示釋出的了版本,1.1.2表示正在開發新功能的內部版本。
  3. 客戶反饋的問題,應該新增到1.1.1版本的issue列表下。內部新開發功能的問題應該放在1.1.2版本上。

然後,人員上調整下。

  1. 配置一個專門的人負責和對方對接,開發不要直接和對方對接,讓那個人彙總客戶的問題,再提交到issue管理器軟體裡的1.1.1上。
  2. 開發如果對某些issue有問題,應該直接給這個專門負責對接的人反饋,由他/她統一跟對方協商。
  3. 開發人員處於「開發密集型」,無法同時應付和對方的對接和反饋問題上,這樣是沒法開發的。

還有,如何修復issue

  1. 測試需要在內部的測試環境上按照對方提交的操作步驟重現(reproduct)問題。因此,對接人需要與對方確認清楚問題出現的必要環境,是否是必現的,還是偶發的。
  2. 因此,需要內部搭建和對方儘量一致的測試環境,測試環境應該與開發環境能並行工作,避免開發人員佔用資源時,測試無法進行測試。
  3. issue重現後,開發介入診斷問題,分析問題,找到原因,在issue管理軟體裡應該寫下原因,如果原因不明,就不是【修復】,而只是【猜測】。
  4. 修復後,應該更改issue的狀態,測試介入迴歸測試。
  5. 測試通過後,與對方溝通,確認釋出到測試環境。對方在測試環境下驗證通過確認後,可以釋出到正式環境。
  6. issue列表多的時候,要標記不同的【優先順序】,如果一個問題處理在一半中,如果估計時間不是阻塞的,要處理完再處理其他問題,如果是阻塞的,就要在Git上建立一個分支去處理它,這樣如果不能立刻修復,可以暫時切出去修復其他更容易修復的問題。
  7. 如果issue很多,開發人員應該不只一個,在能力允許的範圍內,儘可能的把issue分發給對應的人修復,讓開發並行起來。

最後,控制週期

  1. 很多issue提交後,對接人員整理的issue列表,要根據2周為單位能處理多少issue,根據優先順序分類,整理出2周為週期的里程碑節點,確認2周內主要解決這些issue,其他的必須延後。
  2. 這個分類和劃分可能一開始不準確,但是要堅持這麼做,多個里程碑後就會獲得足夠的經驗來支撐作出更合理的控制。
  3. 儘量控制開發週期,不能用掉所有時間,例如在2/4-3/4時間內完成開發,預留內部測試的時間。

如果,專案的某些部分有嚴重的技術債務。技術債務一般是指:

  1. 設計上的某些錯誤,導致問題不斷;
  2. 或者構架上的不合理,導致某些功能的增加非常費勁,成了瓶頸;
  3. 或者程式碼實現質量上出現嚴重的義大利麵條,不論是BUG的追蹤分析還是功能的增加都異常困難,或者會拆東牆補西牆
  4. 那麼此時應該申請一個2-3周的【重構里程碑】,償還技術債務。
  5. 償還技術債務不是客戶提的需求,但是在必要的時候,它就是必要的,軟體最終要有質量才能提供穩定的現有功能,以及可維護的狀態。

考慮小工具。

  1. 專案中,應該提供一組便利的工具,這些工具,每個用來獨立的診斷一個特定的問題是否能正常工作。這在排除問題的過程中有用,並且能節省你的時間。
  2. 這些工具應該能方便的執行,例如做成windows下的bat執行,*nix上的sh指令碼執行。
  3. 提供切換到【除錯模式】和【非除錯模式】的便捷工具、選單等。在【除錯模式】裡,應該可以方便的檢視日誌。如果是UI程式,除錯模式下,應該可以在UI上展示一些關鍵的診斷資訊。注意這裡說的不是在IDE裡的【除錯】,而是釋出後執行時可切換。

編寫良好的日誌。

  1. 程式程式碼的日誌應該根據不同模組,提編寫同Tag標記的日誌行。例如[module1][module2]…,這樣便於你在檢視日誌時通過Tag來搜尋。
  2. 如果某個模組A【向下】呼叫了模組B,那麼A的日誌裡應該包含[tagb][taga],這樣B模組可以看到自己內部的日誌以及自己被A呼叫的日誌。A模組可以看到自己的日誌,以及自己呼叫B的日誌。如果A同時呼叫了C,[tagc][taga]將只會看到A和C之間有關係的日誌。諸如此類。
  3. 嚴格區分日誌級別,一般來說,WARN、INFO、ERROR、三種是重要的區分。更簡化的,INFO和ERROR兩種區分就能覆蓋大部分問題。
  4. 程式的內部充滿了不同的控制邏輯,一般來說if-else及其巢狀,應該在所有重要的分支裡都加好日誌。漏掉的那個沒寫日誌的分支很可能實際出現問題,但是你的日誌丟失了,無法確認問題。
  5. 如果是一個迴圈,或者一個反覆執行的定時器,此類日誌要小心控制。同樣的日誌太多可能影響效能,也可能不利於診斷。
  6. 日誌庫應該支援日誌寫檔案,以及日誌檔案個數的控制,超出配置的大小後,要迴圈覆蓋。
  7. 應該提供【上傳日誌】的能力,當現場出現問題時,能上傳日誌到日誌伺服器。應該提供開發工具【下載日誌】,下載日誌去分析問題。
  8. 請使用合適的工具分析日誌。例如,合理使用*nix下的cat/grep等命令過濾日誌。如果是使用編輯器,一種方式是用cat把所有日誌寫入到一個日誌檔案,用sublime text開啟,裝一個它的擴充套件,使得你可以方便的在[ctrl+k][ctrl+s]後,輸入關鍵字,sublime text將自動將過濾的日誌在一個新的臨時檔案標籤頁裡開啟,這很方便做各種過濾和分析。可以說是grep的便利ui版。

專案是可以迭代的,這是基於:

  1. 如果我們知道一些已知【事實資料】,在這些【事實資料】支撐下,我們能做出假設,編寫程式。
  2. 如果程式不能良好執行,那麼它可能是我們對【事實資料】的分析不周密,漏掉了分支,這種是可以修復的。修復之後,這個程式處於【比之前更正確】的狀態,有序的做這個過程,可以讓程式對已知的【事實資料】的分支覆蓋率達到足夠的程度,例如98%。
  3. 如果出現新的【事實資料】,那麼原來的覆蓋率就降低了,新資料會對原來的假設有交叉,交叉的那些地方要重新考慮。這需要一個過程去再次達到平衡。
  4. 在這個過程中,程式執行所依賴環境的事實資料,以及基於此所作出的分支,達到了一定程度後,測試覆蓋率足夠後,例如98%,程式就應該處於98%情況下可以確定能正確執行。如果出現了意外的不在考慮內的新事實資料,程式有很小的概率會不正確工作。
  5. 在這種對資料足夠的理解、分支的足夠的分析、測試的足夠覆蓋率下。程式可以被【有信心】的釋出。

這個過程,本身就是一個程式,如果要讓整個過程有效率、有序收斂,越是issue來的猛烈,越要遵守原則,守住底線。

—end—