有一套web系統,會部署到不同的服務器上分別運行,這套系統類似於市面上的OA系統一樣, OA開發商會給不同的企業客戶部署一套獨立的互不關聯的系統,我維護的這套系統也差不多,分別被部署在互不關聯的服務器上,當然,這些系統的代碼是同一套,功能也都是相同的。
前兩天,有客戶反饋,他們系統的某個功能無法正常使用。我開始排查問題,發現部署在其它服務器的系統這個功能都是正常的,唯獨這個客戶的系統存在問題。而據我所知,這套系統功能上對於所有客戶都是一視同仁的,是不存對於不同客戶有不同功能的情況,因為部署在所有服務器上的代碼是同一份。
剛開始以為問題是代碼不同步導致的, 后來反復確認出問題的那套系統的代碼的確是最新。可為什么大家的代碼都是一樣的偏偏就它有問題呢? 而出現的這個問題是純業務邏輯上的問題,跟服務器環境是不相關的。
反復查看代碼, 反復檢查配置文件,反復在開發環境中調試,始終找不出個所以然來, 百思不得其解。
最終我不得不祭出只有在嘗試了所有方法后依然無法奏效萬不得已才會去使用的殺手鐧:線上調試。
我登上服務器,編輯代碼文件,在我認為容易定位到問題所在的代碼位置加上打印數據的語句, 然后運行出問題的功能,觀察出問題的數據。在這里我要感謝運維,感謝PHP,沒有他們的幫助,我還要繞個大圈圈才能干這事。
然后以我觀察到的數據為線索, 一步步的向上追蹤問題代碼, 最終發現, 在某一個很深的角落里, 靜靜的躺着這樣一段代碼
if($_SERVER["SERVER_NAME"] == "192.168.110.233" || $_SERVER["SERVER_NAME"] == www.xxx.com"){ //問題系統消失的功能的代碼 }
看到這段代碼我心里萬馬奔騰, 氣不打一處來, 並且狠狠的罵了一句:CMNLGB。 緊接着,一股深深的無力感涌上心頭。
使我受盡折磨,並且付出一下午美好時光的BUG居然是由這么一個在正常的代碼中絕不因該出現的腦殘的條件判斷引起了。 不值得啊。
我很想懟寫着段代碼的程序員,但是這個任務我完不成了, 因為她離職了,我就是從她手里接手這套系統的。
於是我去除代碼中的這個條件判斷,同步代碼,出問題的系統能正常運行了。
冷靜下來以后, 我思考這個問題。 毫無疑問,對於這個問題,寫出這段代碼的程序員當時面對的需求應該是讓某個功能只在部分服務器上部署的系統中體現, 於是這個腦殘的條件判斷應運而生。
如果是我實現這個功能,我可能會在配置文件里加一個具有描述性名稱的flag,然后在代碼中讀取這個flag進行條件判斷。
然而,這樣做能從根本上解決問題嗎? 顯然不能。 假如我面對的是這個改進版本的條件判斷,頂多能讓我有幾率加速定位到問題所在,也就是我查看配置文件並且眼尖看到了這個配置項目就能明白事情的真相。如果我不去看配置文件,或者沒有看到這個配置項,那么到達目標的路徑依舊不會有變化,而且這是大概率事件,因為這次出現的問題的特殊性,很難讓人將它和配置文件中的配置項聯系到一起。
那如何做才能從根本上避免這個問題?
為項目維護一份文檔? 不太現實,代碼都來不及寫, 哪有時間寫文檔。
離職交接時把注意事項說清楚? 不太現實, 離職交接都是交接一些宏觀的內容,代碼上的細節不可能在這個范圍之內。
規范化項目管理, 功能迭代流程,更新系統功能需要審核? 不太現實,部門中這樣的項目大大小小幾十個,這樣做成本太高了。
不給做這樣的需求? 更加不現實,人家需求方分分鍾投訴到大領導那, 讓我們吃不了兜着走。
那究竟怎樣做才能避免這類問題,才能讓我愉快的寫代碼, 求各位大神支招, 在下感激不盡。