天天看點

記一次扯到蛋的教訓

上周五的時候我對某個項目做了一個更改,将裡面的建構腳本由maven換成了gradle。原因之一是因為maven的配置太繁瑣,由于其引入了lifecycle的機制,導緻其不夠靈活,而gradle作為用groovy寫的DSL,代碼清爽、簡單、靈活。原因之二是我們所有的項目建構都換成了gradle,為了保持技術棧單一,此項目做遷移也是大勢所趨。(其實最重要的原因是我想練練手,雖然對maven已經箱單熟悉了,但是gradle的練習不多。)

完成遷移以後,我在本地試了一下,編譯的war包可以成功運作。并且我也修改了建構管道,使其能夠支援新的gradle腳本将war包部署到伺服器上。

然後我就給項目成員發了封郵件,告知了這件事情。

周一來上班的時候,收到了項目組的回信,大家都對我的勞動表示感謝。其中有一個組員建議我将這個項目的名稱更換一下。因為該項目之前叫做ais-stub,他的主要功能是模拟ais服務,但是後來我們也加入了對其他web service的模拟,應該改為service-stub更具有意義。

我覺的這個改動應該比較簡單,無非就是修改一下該項目的名稱,并且更改建構出來的war包名稱,修改建構管道的配置。然後我就動手改了。待我改了war包名稱後,想起來這樣會引起url中的contextPath也發生變化,而功能測試引用了這個url,那麼我就修改了功能測試中的url。然後我又發現我需要修改其他項目中的配置,将使用了該url的地方替換為新的url。待我将我的修改送出後,發現部署失敗了。原來是由于war包名稱改變,部署腳本在擷取war包時找不到新war包,我不得不修改部署腳本。但是修改過程中我發現有一段部署腳本由于權限原因我無法修改,隻能請求對該腳本有修改權限的人替我修改,這又浪費了不少時間。全部修改完後我想起項目wiki上的介紹也要跟着改,把所有使用到該項目名稱的地方都需要改成新名稱……

就這樣一步步的做下去,本來覺得2小時就能完成的任務我足足幹了4個多小時。最後全部改完後,我試着跑一下看看能運作不。結果傻眼了,将該項目部署到伺服器上後,其他項目請求該服務失敗,具體原因未知。由于我已經做了太多的改變,很難定位到問題所在。我剛開始懷疑部署有問題,想檢視伺服器上的建構版本,發現查詢不到。找了半天原因後發現原來星期五我做建構腳本遷移時遺漏了一個插件,導緻沒有将建構版本記錄到war包中。我隻能先放棄檢視伺服器上的war包建構版本,而在本地将該項目的伺服器起起來,使用其他項目進行通路,結果又一切正常。那證明可能還是伺服器上的部署有問題。我檢視了建構出來的war包,發現裡面的properties檔案不是期望的那個,這時我想起周五修改建構管道時,随手删除了一個自認為多餘的task,可能正是這個原因導緻最後導入war包的properties不對。我隻好又修改建構腳本,確定其能包含正确的war包……

很快時間已經到了6點多了,該下班了,但是我仍然深陷這個泥潭,沒有找到問題原因,反而時不時要解決一些其他雜七雜八的東西。看來今天是完成不了了,因為修改的東西太多了,每個修改都沒有進行驗證,是以問題排查很難,并且還經常發現新的問題。

最後,我隻好打住。決定明天早上一來把今天所有的修改都撤銷掉,等于說今天的活都白幹了。今天下班了,感覺很不好。作為一個豐富的程式員,給羊剪羊毛(出自《卓有成效的程式員》,指剪不斷理還亂,本來要解決這個問題,但解決過程中面對的都是與根本問題不相幹的其他問題)這件事情怎麼會發生在我的身上那?

我覺得最大的問題有兩個:

沒有對改名這個任務列詳細的task。剛開始太輕敵,以為改名很簡單,沒有仔細想。結果自己把自己帶到了溝裡,步子邁的太大了,把蛋給扯到了。列出詳細的task好處是你能預估出完成的時間,并且了解可能會出現哪些風險。每個task都循序漸進、可以驗證,并且保證随時可以回退。由于沒有列task,直接導緻我明天撤銷修改時還要努力回想到底今天做了哪些修改。

我沒有及時進行驗證。TDD的思想就是先測試-》測試失敗->再寫實作->測試成功。這樣周而複始來驅動出你的代碼。由于所有代碼都有測試覆寫,你有充分的信心保證你的實作是正确的。而雖然我對項目的修改無法及時通過自動化測試進行驗證,但起碼也應當在做了一個小改動時及時的手工進行驗證。比如在将建構腳本替換成gradle之後,不僅要在本地測試一下是否正确,還應當測試部署到伺服器上的war包是否正确。這樣至少能及時發現建構版本資訊缺失及properties檔案不對的問題。

以前老教導别人做事的時候要列task,要及時驗證和回報,沒想自己今天在這上面宰了一跟頭,還是太輕敵啊。不過吃一塹長一智,希望以後少犯這種低級錯誤。

繼續閱讀