聊聊遺留系統改造的“道”與“術”

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"作者 | 蔡芳芳"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"採訪嘉賓 | 梅雪松"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" "}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"讓我們面對現實吧,我們今天所做的一切就是在編寫明天的遺留系統。—— Martin Fowler"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"什麼是遺留系統(Legacy System)?根據"},{"type":"link","attrs":{"href":"https:\/\/en.wikipedia.org\/wiki\/Legacy_system","title":null,"type":null},"content":[{"type":"text","text":"維基百科的定義"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":",遺留系統是一種舊的方法、舊的技術、舊的計算機系統或應用程序,“屬於或與以前的、過時的計算機系統有關” ,但仍在使用中。通常,將系統稱爲“遺留系統”意味着它可能已經過時或需要更換。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"遺留系統改造是程序員的宿命,因爲軟件永遠沒有完成的時候。公司的業務始終在變化,軟件架構和代碼也只能隨之不斷變化,在數字化時代,這種變化更快了。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"據"},{"type":"link","attrs":{"href":"https:\/\/spectrum.ieee.org\/computing\/it\/inside-hidden-world-legacy-it-systems","title":null,"type":null},"content":[{"type":"text","text":"IEEE報道"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":",自2010年以來,全世界的公司和政府在IT產品和服務上的支出估計爲35萬億美元。其中,約四分之三用於運營和維護現有的IT系統。至少有2.5萬億美元用於嘗試替換舊的IT系統,其中約有7200億美元被浪費在失敗的替換工作上。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"遺留系統改造和替換是一個高風險操作,開發人員應該如何對遺留系統改造做風險評估?需要遵循哪些改造原則?重構還是重寫,應該怎麼選擇?在近日舉行的2021 ThoughtWorks技術雷達峯會上,ThoughtWorks首席諮詢師梅雪松圍繞上述話題做了演講分享,並在演講後接受了InfoQ記者的採訪,與我們聊聊他在經歷衆多改造項目後總結出的遺留系統改造的“道”與“術”。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#555555","name":"user"}}],"text":"微服務不是遺留系統改造的首要選擇"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"雖然當前微服務幾乎已經成了軟件架構的事實標準,很多開發團隊在重新開發系統的時候會把微服務作爲默認架構直接使用。但對於很多遺留系統來說,微服務可以作爲一個選項,但並不是團隊優先要解決的問題。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"微服務的好處在於能夠讓不同的模塊獨立上線和運行,如果享受不到這個好處又付出了微服務改造所需要的成本,就划不來了。對於那些IT資產比較重的行業(如金融、保險等),他們的核心繫統本身就很難快起來,通常是一批需求一起上線,模塊是否能獨立上線、獨立演進並不太重要,微服務反而還會帶來極高的運維複雜度。對於這類核心系統來說,優先級更高的是業務代碼解耦,很多系統往往就是因爲代碼耦合度太高才變得複雜。梅雪松表示,解耦一直是遺留系統改造的重點,10年前是如此,現在是如此,再過10年可能還是如此。雖然“高內聚、低耦合”是大家一直在追求的目標,但實際很難達到。系統開發的第一步必然是先完成業務需求,業務也有deadline,於是就成了死循環,業務一直在催,IT只能趕緊幹,結果就留下了很多技術債而且沒有時間修復,甚至沒有意識到要去修復,最終這個系統就變成了遺留系統。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"如何啓動遺留系統改造?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"遺留系統改造是一個長期過程,通常會持續很長時間。因此啓動改造之前,需要考慮其他相關干係人的訴求,明確改造目標。如果不能得到其他部門的支持,改造工作可能會遇到比較大的挑戰。梅雪松建議可以從四個方向尋找目標:"}]},{"type":"numberedlist","attrs":{"start":null,"normalizeStart":1},"content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"業務敏捷,能不能讓響應力變得更快?"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"運營效率,如何通過系統改造,提升業務運營的效率?"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":3,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"客戶洞見,如何讓系統更好地發現客戶洞見,進而更好地理解客戶需求和演進產品?"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":4,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"系統本身的韌性和彈性,這是在雲時代比較典型的訴求。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"有了明確的改造目標後,還需要制定度量指標,在每個維度上搜集度量數據並可視化出來。這樣做的好處,一是能夠讓團隊瞭解改造進展和成果,確保改造朝着正確的方向走;二是能夠將數據透明給相關的干係人,如業務、運營、市場等部門,以獲得他們的支持。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"遺留系統現代化改造的三個原則"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"如前文所述,遺留系統改造是一項高風險工作,失敗率高達三分之一。那是什麼原因讓遺留系統改造獲得了成功?又有哪些因素導致遺留系統改造最終失敗?借鑑Neal Ford《演進式架構》一書的內容,梅雪松總結了遺留系統現代化改造的三個原則,這些原則在遺留系統改造中可以作爲指導思想使用。"}]},{"type":"image","attrs":{"src":"https:\/\/static001.infoq.cn\/resource\/image\/ae\/d4\/aeb6c5b28210d26e7b544384b699abd4.png","alt":null,"title":"","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"第一個原則是要把演進能力作爲一種架構特徵。架構有很多特徵,比如安全性、可靠性、應用性等等。既然業務一直在變化,代碼需要一直演進,那就應該把演進的能力作爲一種架構特徵,在設計架構時需要考慮到這一點。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"第二個原則是以適應度函數來牽引架構的演進。軟件開發是一個社會化的過程,所以架構的演進以及維護需要團隊來做,但團隊很難自發去做這項工作,需要有一個東西來牽引着他們,並評估每一次的演進到底變得更好還是變得更壞了,這就是適應度函數。比如如果以架構分層爲設計原則之一,就可以定義一個分層的適應度函數,然後把它變成一個測試放到CI上持續運行。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"第三個原則是以增量變更作爲架構演進的單元,這是在實操層面最重要的一個原則。很多失敗的遺留系統改造案例幾乎都有一個同樣的特點,就是步子邁得太大了,有的直接就重新開發,甚至連數據庫都變了,這種情況的風險顯然是非常大的。如果在改造一個遺留系統的時候,不能分階段地上線、遷移、切換,而是等到最後一刻才最終上線切換的話,風險可能就爆表了。如果能以增量變更的方式來做改造,每個增量都能夠回滾,這種改造基本上風險是可控的。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"重構不如小範圍重寫"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"遺留系統改造有五種常見策略,分別是封裝(Encapsulate)、平臺切換(Replatform)、遷移(Rehost)、重構(Refactoring\/Re-architecing)、重新開發(Rebulid\/Replace)。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"image","attrs":{"src":"https:\/\/static001.infoq.cn\/resource\/image\/7a\/34\/7aa9c5c9dfc2fe34577aa11dd3f48334.png","alt":null,"title":"","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"選擇策略的時候,需要考慮對應的風險、收益和成本。如上圖所示,封裝的風險是最小的,收益也比較小,但是成本也很低。重構和重新開發的收益都比較大,但是成本也比較高,其中重新開發的風險是最高的。梅雪松強調,這些策略作用的顆粒度並不是整個系統,而可能是在很小的模塊上,並且這些策略可以組合使用而非單獨只選擇某一個策略。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"那對於遺留系統改造來說,重構和重新開發哪一個是更好的選擇?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"梅雪松表示,隨着經歷的客戶改造案例越來越多,他的想法也在發生變化。最早的時候,他認爲只要具備足夠強的能力,重構比重寫更安全,但後來他發現,很多老舊的業務系統代碼質量非常糟糕,幾乎可以說是“一次性”代碼,並沒有什麼重構的價值,不如直接重寫。在他看來,理解業務後再重寫,其實是比較安全的,複雜的是本身不瞭解業務、代碼又寫得很亂,這時候通過代碼對照去了解業務反而難上加難。當然,保證重寫安全性的前提是,不能整個系統大範圍地重寫,而是要一小塊一小塊去重寫。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"但重構並非沒有價值。梅雪松認爲,在應對很多老代碼的時候重構價值不大,但重構這個能力對於工程師來說依然非常重要。即便是開發新需求,也是一個不斷重構的過程。寫代碼就像寫文章一樣,一開始寫出來的一定不會是好代碼,只有一遍一遍地修改和重構之後才能寫出高質量的代碼。因此重構並非只是架構師或高級別技術大牛才需要關注的事情,而是所有開發人員都應該具備的最基本技能。"}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章