MapleCheng

在浩瀚的網路世界中無限潛水欸少年郎!

0%

相容層不是解法,它只是過渡期

最近整理一個內部自動化流程時,又碰到一個很熟悉的場景:系統表面上已經搬到新架構,實際上卻還偷偷依賴舊路徑、舊憑證位置,甚至靠一條臨時的符號連結撐著。

這種狀況最麻煩的地方,不是它立刻壞掉,而是它看起來還能跑。看起來能跑,往往就是技術債最會偽裝的時候。

我一直覺得「相容層」是工程裡很必要、也很危險的東西。必要,是因為現實世界不可能所有東西都一次切乾淨。系統在跑,使用者在用,排程在半夜觸發,外部服務還會照舊打進來。你不可能每次改架構都要求大家停工一天,然後祈禱所有依賴都已經被找到。

所以我們會做相容層:舊 API 先保留一段時間,舊路徑先做轉接,舊資料格式先支援讀取,舊設定先用 fallback 找得到。這些做法在切換期間非常實用,也常常是讓遷移能平穩落地的關鍵。

但危險也在這裡。相容層太好用了,好到團隊很容易忘記它本來只是過渡期。

能跑,不代表已經完成

我看過很多遷移最後卡住,不是卡在新系統做不出來,而是卡在「舊東西到底還有沒有被用」。

例如某個腳本已經移到新目錄,但排程還指向舊目錄;某組憑證已經整理到標準位置,但程式裡還有一個 fallback 會去舊資料夾找;某個臨時符號連結原本只是為了讓測試先過,結果過了兩週、兩個月,大家都忘了它的存在。直到某天清理舊環境、換機器、改權限,才發現所謂的新流程其實還牽著一條舊尾巴。

這時候最常聽到的一句話是:「可是之前都可以啊。」

沒錯,之前都可以。因為相容層替我們吃掉了錯誤訊號。它讓壞掉的依賴沒有立刻爆炸,也讓團隊誤以為遷移已經完成。從使用者角度看,服務有回應;從工程角度看,卻是新舊架構混在一起,只是暫時沒出事。

我現在會把這種狀態稱為「未完成的完成」。

臨時方案要有拆除日期

相容層不是不能做,但我會要求它至少具備三件事。

第一,要有名字。不要只是在某個角落加一段 fallback,然後 commit message 寫得很含糊。要明確說:這是一個相容層,目的是讓哪些舊依賴在切換期間還能運作。

第二,要有觀測。相容層被觸發時,應該留下 log、計數或警告。否則你永遠不知道它還有沒有被用。最糟的相容層,是默默成功的相容層;它越安靜,越容易變成永久架構。

第三,要有拆除日期。這不一定是精確到哪一天,但至少要有退出條件:哪些排程改完、哪些路徑驗證完、哪些使用者切過去、哪些檔案不存在時仍能正常啟動。沒有退出條件的臨時方案,其實就是正式方案,只是大家不好意思承認。

這點在自動化流程特別重要。因為自動化通常不是每天有人盯著跑,它會在固定時間、固定事件、固定條件下自己動作。如果相容層沒有觀測,團隊可能要等到半夜某個排程失敗,或某個外部寫入沒有發生,才知道舊依賴其實還活著。

清掉舊東西,是驗證的一部分

很多人把清理 legacy 當成收尾工作,我倒覺得它應該算驗證的一部分。

如果一個系統宣稱已經遷移到新架構,那移除舊路徑、舊符號連結、舊憑證位置後,系統仍然能正常啟動,才算真的通過測試。否則我們測到的只是「新架構加舊環境」可以跑,不是新架構自己可以跑。

這兩件事差很多。

「新架構加舊環境」能跑,代表你還沒有證明新架構獨立成立。它可能仍依賴某個舊資料夾、舊使用者權限、舊 shell profile、舊 token 檔案,或某個只有原本那台機器才存在的奇怪設定。

真正的遷移驗證,應該包含一個很不浪漫但很有效的步驟:把舊東西拿掉,然後重跑。

這也是為什麼我越來越喜歡把「移除 legacy」寫進 checklist,而不是留在大家有空再做。因為大家通常不會有空。只要系統能跑,清理工作就會被更急的事情吃掉;等到它真的造成問題時,當初知道脈絡的人可能已經忘了細節。

不要讓方便變成架構

符號連結、fallback、舊 API、相容 adapter,這些東西本身都不是壞人。壞的是我們讓它們從方便變成架構,卻沒有承認。

工程上很多風險不是來自一次很大的錯誤,而是來自一連串合理的小方便。今天先 link 一下,明天先 fallback 一下,下週先保留舊設定,過一陣子再整理。每一步單獨看都合理,但串起來就會變成一個沒有人完整理解的系統。

從技術主管的角度,我不會禁止團隊做臨時方案。相反地,好的臨時方案常常代表團隊懂得控制風險,知道怎麼讓改動平滑落地。但我會很在意臨時方案有沒有被管理:它為什麼存在、誰知道它存在、什麼時候可以拆、拆掉後怎麼驗證。

如果回答不出來,那它就不是臨時方案,而是技術債開始長根。

遷移完成,是舊依賴真的死掉

我現在判斷一個遷移是不是完成,不只看新流程有沒有跑起來,也看舊依賴是不是能被安全刪掉。

舊路徑刪掉後不會壞,舊憑證移除後不會被讀,舊排程關掉後沒有事件漏處理,舊入口停用後沒有流量還打過來。這些都確認過,我才比較願意說:好,這次是真的搬完了。

否則它只是新系統披著舊系統的外套。

相容層真正的價值,不是讓我們永遠不用面對切換成本,而是讓我們能有秩序地走過切換期。它應該是一座橋,不是一條永久道路。橋搭好了,人走過去了,就該回頭確認沒有人還站在橋中央,然後把該拆的拆掉。

工程成熟度有時候不是看你能不能把新東西做出來,而是看你有沒有勇氣把舊東西關掉。

因為只有舊依賴真的死掉,新架構才算真正活著。