银行祖传系统重构实例:创立12年,只支持Python 2,跑着500多个应用程序
作者 | THEHFTGUY、萬佳
提到遺留系統,你會想到什么?
-
還在使用 Java 5 的路過
-
JDK 1.6 的我不說啥了
-
很多坑
-
難維護
-
從零開始(重寫)
-
盼著 IE 什么時候不再能使用
-
......
1 遺留系統
對遺留系統,程序員們并不陌生。據維基百科介紹,遺留系統是一種舊的方法、舊的技術、舊的計算機系統或應用程序。張逸認為,遺留系統首先是一個還在運行和使用,但已步入軟件生命周期衰老期的軟件系統。它符合所謂的“奶牛規則”:奶牛逐漸衰老,最終無奶可擠,然而與此同時,飼養成本卻在上升。這意味著遺留系統會逐漸隨著時間的推移,維護成本會不斷地增加。
在《從 300 萬行到 50 萬行代碼,遺留系統的微服務改造》一文中,技術瑣話闡述了遺留系統的一些共同特征。
-
龐大的單體應用:遺留系統大多是多年積累下來的“巨無霸”系統,以單體應用形式呈現。
-
難于修改:多年的代碼累積過程中疏于重構,導致代碼的可讀性和可擴展性較差。
-
維護成本很高:在龐大的代碼中尋找 bug 的根本原因可能會比較困難。此外,運維也是難題,比如在本章開頭提到的 Perl 系統,沒有 APM 工具支持它的監控。
-
學習成本高昂:由于設計陳舊或技術過時,可能了解遺留系統技術和業務的人已經很難找到。
-
缺乏質量保障:由于過去缺少投入,許多功能基本上沒有自動化測試來保障質量。
事實上,在傳統企業甚至互聯網企業往往存在大量的遺留系統。這些遺留系統大多都能正常工作,有的可能還運行著關鍵業務或者持有核心數據。但是,大部分遺留系統通常經常存在技術陳舊、代碼復雜、難以修改等特點。
我們看到,有的遺留系統給企業帶來不可挽回的損失:
系統出現故障,當年負責編寫這個程序的開發者卻在 15 年前去世,現在已經無人能看懂他的代碼,結果一個 bug 導致千萬損失。——《程序開發者去世,代碼沒人懂,一個 bug 導致千萬損失》
還有的遺留系統在企業技術變革中慢慢淡出:
筆者曾經維護過一個 Perl 實現的網站,在 2015 年被解耦前,它已經工作了十幾年,為公司占領市場立下了汗馬功勞。奈何技術陳舊,維護困難,最后在微服務化過程中慢慢淡出。——《從 300 萬行到 50 萬行代碼,遺留系統的微服務改造》
當然,也有遺留系統至今活得很好,默默貢獻自己的力量。
2 印象深刻的遺留系統
我在一家銀行工作時,遇到了一套令人印象深刻的遺留系統。
它最初創建于 2008 年(北京奧運會那一年),花費數周時間進行開發。整套系統具有完整的 CI、CD、單元測試、代碼審查、自動部署等功能。自創建以來,大部分時間,它的核心基本保持不變,但是外圍有許多改進(代碼審查、日志記錄、性能、身份驗證等)。
從某種方面說,它相當于是公司內部的 AWS lambda 等效系統。
你可以編寫一個 Python 腳本(Python 是該系統唯一支持的語言),大約 5 分鐘內就能審核完畢并投入生產,準備供世界使用。
這個系統并不是官方層面的“戰略”解決方案,它不為人知,也沒有做過廣告宣傳。但是,它被頻繁用于多個業務部門,并且不時有新的發展。因為它太好用了,所以大家都沒法拋棄它。
我們部門有個暑期實習生,他利用這個系統,只花了 3-4 周就基本完成了他們的小項目(實習期應該有 2-3 個月)。而同時,其他實習生群體還沒有弄清楚如何在“戰略”框架內交付應用程序。
我最后一次統計時,那里運行著 500 多個應用程序。值得注意的是,生產日志顯示,其中 80% 處于活躍狀態。
3 外科手術式維護
不過,在不斷變化的軟件世界中,所有美好的事物都必須迎來終結。到頭來, 這套系統還是要重新設計或被拋棄,原因如下:
-
Python 2.7 即將壽終正寢
-
身份驗證庫已經棄用
-
中間件有很長時間沒有重新編譯或升級了
-
有一些潛在的 UI 改進需要完成
為了擁抱變化,這個系統開始升級。而在升級到第一批生產腳本時,我們就遇到問題。
有兩個用戶每隔 1 小時就報告一次問題,我們研究問題后發現其僅限于 IE 瀏覽器。在 IE 瀏覽器中,某些功能無法正常運行。
實際上,這家銀行很早前就棄用了 IE,轉而支持 Chrome 瀏覽器。全公司 25 萬的員工被要求禁止使用 IE 瀏覽器。如果嘗試在 IE 中打開某些站點會報錯,會提示你改用 Chrome。這對用戶導航有副作用,因為所有內容都是相互連接的(想象一下 report.example.com 鏈接到 otherreport.example.com 并調用 internalapi.example.com,可是某些 URL 是被阻止的)。
好消息是,最近的升級并沒有倒退回去,而是簡單解決了這個問題。IE 被屏蔽,并向 5000 位開發人員發出了通知:不再支持 IE 瀏覽器。問題解決了。
供參考:最好硬屏蔽 IE 以改善用戶體驗,IE 用戶習慣了在其他瀏覽器中重試。也許最近幾年開發的內部應用中有三分之一無法在 Chrome 之外運行,不是頁面空白,要么就是到處都有損壞的小部件。
于是,升級按計劃進行。在最后,我們遇到一個小麻煩:一個獨立的腳本停止工作了 。
該腳本最初創建于十多年前,也就是這個框架剛創建后的幾個月內。這是最早發布的應用程序之一,也許從歷史上來看是第 8 個(現在有 500 多個)。
它實際上不是代碼,而是某種模板。眾所皆知, 該框架帶有自己的模板語言和例程 (二十一世紀的開發人員應注意:請使用 jinja 進行模板化)。已經沒有東西還在用這個模板功能了。團隊進行了一些調整,然后系統又恢復了正常工作。
最終,升級完成。
新版同時支持 Python 2.7 和 Python 3.7,支持 OpenID Connect 和 Kerberos,在各處添加了一些消息和錯誤以簡化使用,還更新了開發文檔等等……
經過 12 年的可靠和忠誠的服務,這款舊系統并沒有被棄用。恰恰相反。它還在兢兢業業做事,并且肯定還會再活起碼 12 年,比現在所有的 JavaScript 和戰略框架壽命都更長。
唯一的缺點是 lambda 請求的啟動時間較長(基線為 5 秒)。它適合處理偶爾訪問的報告和 API,不適合用于高性能 API 或緩存,后面的情況下最好使用其他技術,推薦 tornado 用作 Web 服務器 Web 框架。
4 看遺留系統的“正確姿勢”
在《關于遺留系統,看看 Google 怎么辦》一文中,Cheng 哥總結了幾點,個人覺得挺好,分享給讀者。
?保守態度,不輕易改變
老的系統,面對的場景沒有發生太大變化,原來什么模式就是什么模式,不要為了改變而改變,比如運營商的 CT 系統、銀行的核心交易系統等關乎國計民生。
同時,因業務特性的原因,本身不會有很頻繁、很大的變更,這種時候,現有手段,慢一點、穩妥一點,哪怕流程繁瑣一點都沒問題。如果改,就可能會帶來極大的風險,也不會帶來太大收益,不改,也能維護下去,孰優孰劣,自然就清楚了。
現在,運維有一種提法,叫做雙態運維,就是針對系統特點,分為穩態和敏態,不同場景采用不同的模式。
?重構過渡
如果業務場景變化了,要求系統必須能跟上節奏,這種情況下,建議通過重構,且逐步遷移的方式過渡。也就是,根據新的場景,設計適應的技術架構,能夠滿足效率、穩定和成本的要求,然后老系統上的業務和流量逐步遷移過去。
如果是直接在承載業務運行的老系統上改,成本和風險會非常高,實際情況下是不可行的。
?從現在開始,重視標準統一
前面提到傳統行業的軟件體系,大多是多廠商建設,標準不統一。但不管是做 DevOps,還是 SRE,甚至最基礎的自動化,標準都是前提中的前提。所以,如果當前正在規劃新的技術體系,或者有針對某些遺留系統重構的機會,從一開始規劃好各種標準體系,就非常重要,建設前沒有標準,事后再去統一標準,基本就沒有機會了。
互聯網的技術體系,從最早期的單體架構,沒有標準,到系統拆分的服務化演進,形成統一標準,再到基于統一標準的運維自動化、持續交付以及穩定性建設,最終形成大中臺的體系,也是遵從著這樣一個過程和規律走下來。
只不過,互聯網公司在早期沒有太大的業務和技術的包袱,所以可以小步(甚至大步)快跑,大膽試錯,快速迭代,整個過程的進展會更快一些,但是規律是一樣的。不過,當規模到了一定體量,所面對的問題,跟傳統行業也是一樣的,一樣會有遺留系統。既不可能隨意放棄(還在承載業務),也不可能說重構就重構,成本和代價是必須要考慮的。
對遺留系統,你有什么看法?歡迎留言告訴我們。
總結
以上是生活随笔為你收集整理的银行祖传系统重构实例:创立12年,只支持Python 2,跑着500多个应用程序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 蚂蚁科技 Service Mesh 落地
- 下一篇: Spring 自定义注解玩法大全,从入门