承接遺留系統(tǒng)運維工作的經(jīng)驗
眾所周知,改造遺留系統(tǒng)并非易事,如果該系統(tǒng)沒有良好的架構(gòu)和編碼,那么在這基礎(chǔ)上做功能升級改造,往往比做全新系統(tǒng)更加費時費力。我的團隊最近承接了一個這樣的平臺升級改造項目,該平臺前后已經(jīng)歷四五家供應商歷時七八年的不斷修改,可維護性極差。在進行升級改造的同時,我們更“有幸”直接承擔了該系統(tǒng)的各項線上運維工作,真真切切體驗了陷入“軟件泥潭”的感受。
一、那些令我們難忘的經(jīng)歷
在項目一開始,便得知該系統(tǒng)前團隊合同已到期會直接撤出,于是我們快速進行了交接,對系統(tǒng)做升級改造之前,先展開運維工作。以下為我們經(jīng)歷的幾個片段,該系統(tǒng)的威力略見一斑。
1)“定時炸彈”
系統(tǒng)里有這樣一個功能,可以定時修改首頁某區(qū)域的內(nèi)容。有這么一次,運營人員通過后臺上傳要修改的內(nèi)容后,發(fā)現(xiàn)上傳錯了,但系統(tǒng)卻沒有提供刪除和更新已上傳內(nèi)容的功能,好在可以修改定時時間,于是運營人聰明地把定時時間設(shè)置為一年后生效,從而避免了系統(tǒng)首頁被改為錯誤信息。一年后本團隊接手了,首頁莫名被修改,原本設(shè)置該定時任務的人員早已離職,留下我方研發(fā)加運維人員努力排查問題至深夜。
2)“扯謊”的流水線
在交接運維工作時被告知客戶需要頻繁做各種活動,每次活動都是要做代碼修改和重新上線的。本團隊一度慶幸該系統(tǒng)盡管老舊,但還是可以通過Jenkins進行上線工作的。
但接手后發(fā)現(xiàn)我們“天真”了,該系統(tǒng)由4個子系統(tǒng)約二十多個單獨部署的服務組成,使用的語言和框架各不相同。當?shù)谝淮斡昧魉€進行上線工作時,我們以為點了按鈕就大功告成了,結(jié)果發(fā)現(xiàn)最后只有少部分服務部署提示成功,而更過分的是,這些提示成功的部署實際有可能是失敗了,而一些提示失敗的實際上卻是部署成功了。當我們聯(lián)系前運維團隊時,被告知由于年久失修,這些流水線有的能用,有的不能用,有時好用,有時不好用,上線時候讓開發(fā)備著。為了不影響第二天白天的正常使用,我方研發(fā)加運維人員上線到天明。
3)尷尬的日志和難纏的注釋
該系統(tǒng)常常出現(xiàn)一些不大不小的錯誤,不致命但是會被客戶業(yè)務部門投訴。例如線索模塊負責處理線索數(shù)據(jù)并向下游傳送,每周總會莫名其妙丟失幾條數(shù)據(jù),于是我們展開了問題排查工作。首先就是去查看日志,當找到處理線索的日志后,我們震驚了,只見日志里滿屏顯示著大寫的“END”,既沒有時間信息也沒有相關(guān)處理的信息,只是每條數(shù)據(jù)成功處理完print “END”,找不到任何有用信息。
當我們?nèi)シ创a時,名不達意自是意料之中,好在有注釋。不過注釋是亂碼,這自然難不住我們,修改編碼嘛。修改后又驚奇的發(fā)現(xiàn),一部分注釋變成中文可讀了,而另一部分卻變成了另一種亂碼,不管怎么改,總是只有一部分注釋變?yōu)檎?,其他仍為亂碼。沒想到之前的幾波研發(fā)團隊寫注釋竟然還使用各自不同的編碼。
二、原因初探
那么這套系統(tǒng)怎么會發(fā)展到如下境地呢,冰凍三尺,非一日之寒。從我們最近的觀察,可能有以下幾點值得注意:
1)缺乏長遠的規(guī)劃,各種“債”不斷堆積
企業(yè)的復雜性,使交付團隊處在一個艱難的環(huán)境,面對業(yè)務側(cè)頻繁的、緊急的業(yè)務需求,交付團隊經(jīng)??考夹g(shù)人員強行對應,導致了各種臨時方案不斷堆積,各種“債”也隨之積攢,系統(tǒng)變得越來越難以維護。
另一個現(xiàn)象是,由于系統(tǒng)各種依賴關(guān)系太復雜,每一家新供應商基本都不愿去修改或優(yōu)化之前的代碼,做功能時候都只增不減。以至于系統(tǒng)管理后臺出現(xiàn)出現(xiàn)多個同名的模塊的詭異現(xiàn)象,其功能又全然不同,完全分不清楚哪個是在用的。久而久之,該系統(tǒng)的運營工作難度也越來越大,換了運營人員肯定玩不轉(zhuǎn)。
2)功能不夠運維湊
由于系統(tǒng)功能不夠閉環(huán),外加開發(fā)階段過后只剩下運維人員支撐,導致了很多緊要需求通過運維人員改庫來實現(xiàn)。當通過改庫和臨時修改代碼來應對需求變成了日常例行操作,整個系統(tǒng)也變得更加脆弱了。
三、應對策略與建議
最好的策略自然是不要過早承接遺留系統(tǒng)的運維工作,至少要等升級改造工作開展到一定階段,新系統(tǒng)上線后再去承接。但現(xiàn)實往往骨感,如果不得已需要立刻交接,那么建議至少做好以下幾點:
1)拉長交接期,在交接期做足功課
將交接列表做得詳細一些,并做好交接期間的日程安排,確保雙方團隊有充足的溝通,從業(yè)務和技術(shù)層面都有詳細的講解。交接列表參考示例見文末附錄,如果項目使用到了一些看板或相關(guān)需求開發(fā)管理工具也注意一并交接。
對于交接列表中的文檔,很可能對方缺失嚴重,那么一方面是需要讓對方盡力補齊相關(guān)文檔,另一方面則要針對列表中的各項專題開展交接溝通會,盡量獲取到更多的知識,在交接過程中注意做好總結(jié)。
2)確保開發(fā)人員的可調(diào)試環(huán)境能正常運行
這點很重要,盡管在交接階段已經(jīng)拿到了大量文檔,但文檔的內(nèi)容和當前代碼真的一致嗎,緊急出現(xiàn)的BUG如何快速排查和修復?這些終究需要可運行可調(diào)試的代碼來給出答案。以本項目為例,交接期僅有Tech Lead和一個運維同事開展與前團隊所有的技術(shù)和運維交接工作,面對多種語言多種框架實現(xiàn)的各類代碼有些力不從心,好在果斷要求對方協(xié)助,在我們的研發(fā)機器上實現(xiàn)各類代碼的運行和調(diào)試。交接完就立刻趕上雙十一活動上線,結(jié)果到了凌晨搶購時間點,產(chǎn)品購買頁面的購買按鈕仍是置灰狀態(tài)無法點擊,于是現(xiàn)場調(diào)試,發(fā)現(xiàn)了系統(tǒng)處理時間的BUG并及時修復,才使業(yè)務未受到明顯影響。
3)完善監(jiān)控和日志功能,變被動為主動
這點不用過多解釋,通過對監(jiān)控的完善和日志的完善,使團隊能夠及早發(fā)現(xiàn)系統(tǒng)的各種問題,在出現(xiàn)異常時能夠追查原因,不至于手足無措。
4)與前團隊維護好關(guān)系
雖然這不是一個技術(shù)舉措,但有時候卻非常有效,畢竟前團隊經(jīng)過摸爬滾打,已經(jīng)熟悉了這個系統(tǒng)的秉性。當遇到一些緊急問題時候,他們的一句建議可能省去一天的錯誤排查。
四、后記
盡管這樣一個“軟件泥潭”讓團隊的行動很艱難,但我們對各種企業(yè)級問題的處理和解決增長了經(jīng)驗,我想團隊中每個人都會從中有所收獲。在系統(tǒng)運維工作順利展開后,團隊終于開啟了遺留系統(tǒng)改造之旅。
附錄1: 交接列表示例(設(shè)計與開發(fā))
類別 | 內(nèi)容 |
項目管理 | 項目日程 |
會議記錄 | |
體制圖 | |
項目要件 | 業(yè)務功能清單 |
業(yè)務流程圖 | |
需求變更記錄 | |
操作說明書/用戶手冊 | |
常見問題一覽 | |
界面設(shè)計 | UE設(shè)計稿 |
高保真畫面設(shè)計稿 | |
需求變更一覽 | |
系統(tǒng)設(shè)計 | 系統(tǒng)架構(gòu)設(shè)計圖 |
部署架構(gòu)圖 | |
DB關(guān)聯(lián)圖(ER圖)和DB詳細設(shè)計 | |
系統(tǒng)間集成關(guān)系圖 | |
對接系統(tǒng)一覽表和對接系統(tǒng)接口清單 | |
開發(fā)制作 | 源代碼 |
代碼運行說明 | |
測試 | 系統(tǒng)測試用例與系統(tǒng)測試報告書 |
性能測試用例與性能測試報告書 | |
用戶測試用例 | |
用戶測試簽字 |
附錄2: 交接列表示例(運維相關(guān))
類別 | 內(nèi)容 |
上線相關(guān) | 上線判定表 |
上線操作記錄 | |
歷次上線版本說明 | |
臨時對應體制 | |
基礎(chǔ)設(shè)施 | 硬件資源一覽 |
軟件資源一覽 | |
服務器/系統(tǒng)賬號權(quán)限 | |
系統(tǒng)工具 - 付費/免費軟件 | |
運維體制 | 運維工作一覽表 |
近半年運維工作應對流程 | |
運維體制 | |
故障對應流程 | |
SLA(服務水平協(xié)議) | |
DEVOPS(開發(fā)運維一體化) | CI/CD工具與使用 |
監(jiān)控工具 | |
備份管理 | |
代碼庫與分支管理 | |
數(shù)據(jù)庫相關(guān)配置與策略 |