2026 年企業核心系統微服務化拉開序幕:Strangler Fig 絞殺者模式實作

concept%20visualization%20for%202026%20%E5%B9%B4%E...
發表時間:2026 年 09 月 16 日 | 更新日期:2026 年 09 月 16 日 | 編輯:雅寶社區編輯團隊
2026 年企業核心系統微服務化拉開序幕:Strangler Fig 絞殺者模式實作|// 舊實作:包裝既有的預存程序呼叫 - 雅寶社區 · 頂客論壇

@Com

// 新實作:呼叫獨立部署的定價服務

@Com

} c

以下是一套經過多次實戰修正的六階段路線圖。原則是:每一階段結束時,系統都必須處於可上線、可回滾的狀態。

4.1 第 0 階段:辨識絞殺縫隙(Seam Identification)

縫隙(Seam)是系統中「可以插入切換點而不需修改內部結構」的位置。找出好的縫隙,是整個專案最重要的一次決策。評估一個候選縫隙的標準有四項:

  • 業務邊界清晰度:這個能力是否有明確的輸入輸出、是否與其他能力高度耦合。
  • 變更頻率:業務上是否經常需要修改?越常改的越值得先拆。

    資料獨立性:它主要操作的資料表,是否與其他能力有大量共享寫入。

    風險容忍度:出錯時的業務影響是「客人多等兩秒」還是「帳務錯亂」。

    實務建議:第一個絞殺目標應該選「高變更頻率、低資料耦合、中低業務風險」的能力。例如「會員等級查詢」、「商品目錄」、「通知偏好設定」。第一個目標的意義不在於它本身有多大價值,而在於它必須成功,用來建立組織信心與驗證整條工具鏈。把它當成一次完整的實彈演習。

    4.2 第 1 階段:建立門面與旁路

    此時不做任何功能遷移,只做兩件事:

  • 在單體前面部署門面,設定 100% 回退到單體,確認延遲增加在可接受範圍(通常目標是 P99 增加不超過 5ms)。
  • 建立觀測基礎:統一的 correlation-id 傳遞、門面層的存取日誌、以及路由決策的事件記錄。

    這一階段常被視為「沒有產出」而遭刪減,但它其實是在為後續所有階段購買保險。門面一旦上線並穩定運行一個月,後續的每一次切換都只是一行設定變更。

    4.3 第 2 階段:讀取路徑絞殺(Read Strangler)

    新服務先接管查詢流量,但寫入仍由單體負責。資料透過 CDC 單向同步到新服務的讀取模型。

    這個階段的價值在於:

    驗證資料同步的正確性與延遲特性(同步延遲是否在業務可接受範圍內,例如 500ms 內)。

    驗證新服務在真實流量下的效能與穩定性。

    建立團隊對新部署流程與工具鏈的肌肉記憶。

    切換策略建議採用分層放量:先內部使用者、再 1% 真實流量、再 10%、再 50%、再 100%。每一層至少要觀察一個完整的業務週期(例如包含一個週末與一個月初結帳日)。

    4.4 第 3 階段:寫入路徑絞殺(Write Strangler)

    這是真正的分水嶺,因為它涉及資料主權的移轉。建議採用命令攔截 + 反向同步的過渡架構:

    門面把寫入請求導向新服務。

    新服務在自己的資料庫完成寫入,並發布領域事件。

    一個適配器訂閱事件,把變更以舊系統能理解的形式寫回單體資料庫。

    單體仍能讀到最新資料,因此所有尚未絞殺的功能不受影響。

    這個架構讓你可以逐功能切換寫入,而不必一次移轉整張資料表。但要注意:反向同步必須對「單體自己也會修改同一筆資料」的情況有防禦機制,否則兩邊互相覆寫會產生極難追查的資料損壞。常見做法是對資料列加上版本號或 last_modified_by 標記,並在衝突時採「新服務優先」或「人工裁決佇列」策略。

    4.5 第 4 階段:資料主權正式移轉

    當某個能力的所有讀寫路徑都已由新服務承接,且反向同步已穩定運行足夠長的觀察期,就可以進行正式移轉:

    停止反向同步。

    在單體中把該能力的相關程式碼改為「呼叫新服務」或直接移除。

    針對單體中殘存的直接資料庫存取(例如報表、批次作業),建立唯讀檢視或資料倉儲同步。

    這裡最容易被忽略的是非同步的資料消費者:批次對帳程式、BI 報表、資料倉儲 ETL、稽核歸檔。它們往往直接連線單體資料庫,不會出現在 API 呼叫圖上。務必在移轉前做一次完整的資料血緣盤點。

    4.6 第 5 階段:掏空與退役

    重複上述流程,直到單體只剩下一層薄殼。此時才決定它的最終命運:完全下線、或保留為一個極小的核心服務。無論哪一種,都要記得把絞殺過程中累積的臨時性構件清理乾淨:影子比對程式碼、雙寫適配器、特性開關、已無用的唯讀檢視。這些臨時構件如果不清,會變成下一代的技術債。

    五、常見陷阱與反模式

    5.1 陷阱一:門面變成新的單體

    症狀:門面開始出現 if (customer.type == "VIP" && order.amount > 10000) 這類條件判斷。原因通常是某個邊界情境用路由規則難以表達,工程師就「暫時」把邏輯放進門面。

    防禦方式:把「門面不得包含業務邏輯」寫進架構決策紀錄(ADR),並在程式碼審查中強制執行。若真的需要複雜的切換邏輯,應該把它實作成一個獨立的「路由決策服務」,而不是塞進代理層。

    5.2 陷阱二:雙寫導致資料漂移

    症狀:新舊兩邊的資料在幾週後開始出現無法解釋的差異,且數量逐漸累積。

    根本原因:應用層雙寫沒有原子性保證,其中一邊失敗時若沒有補償,就會漂移。防禦方式是採用 Transaction Outbox 模式:把要發布的事件與本地交易寫入同一張 outbox 表,再由獨立的發布器讀取並送出。這保證了「本地交易成功」與「事件最終被發布」的一致性。

    -- Outbox 表結構

    CREATE TABLE outbox_event (

    id BIGSERIAL PRIMARY KEY,

    aggregate_type VARCHAR(64) NOT NULL,

    aggregate_id VARCHAR(64) NOT NULL,

    event_type VARCHAR(128) NOT NULL,

    payload JSONB NOT NULL,

    occurred_at TIMESTAMPTZ NOT NULL DEFAULT now(),

    published_at TIMESTAMPTZ,

    retry_count INT NOT NULL DEFAULT 0

    );

    CREATE INDEX idx_outbox_unpublished

    ON outbox_event (id)

    WHERE published_at IS NULL;

    5.3 陷阱三:以技術模組而非業務能力切分

    症狀:拆出來的是「使用者服務」、「訂單服務」、「產品服務」,每個服務都直接存取同一批共用資料表,服務之間還有大量同步呼叫。

    這就是典型的「分散式單體」。它比原本的單體更糟,因為你同時承擔了單體的耦合與分散式系統的複雜度。

    正確做法是回到領域驅動設計,以限界上下文(Bounded Context)為切分單位,並且確保每個上下文擁有自己的資料儲存。如果兩個能力共享同一張表,那它們很可能本來就屬於同一個上下文,不應該在此時被拆開。

    5.4 陷阱四:絞殺順序由技術難度決定,而非業務價值

    症狀:團隊從「最容易拆的」開始拆,兩年後發現拆掉的全是邊緣功能,核心的營收流程仍是鐵板一塊,而管理層已經對專案失去耐心。

    防禦方式:建立一個「價值 × 可行性」的二維矩陣,並且每個季度至少要完成一次「高價值」象限的絞殺。這需要架構團隊與業務端共同排定順序,而不是由技術團隊單方面決定。

    5.5 陷阱五:特性開關債

    絞殺過程會累積大量特性開關。如果沒有清理機制,兩年後你會面對數百個開關,沒有人敢關掉任何一個,於是所有程式碼路徑都必須被測試與維護。

    建議做法:每個開關建立時就指定預期的移除日期與負責人,並在 CI 中對超過期限的開關發出警告。開關的狀態也應該納入可觀測性,讓你知道目前有多少流量走在「非預期路徑」上。

    六、2026 年的工具鏈與 AI 輔助實作

    6.1 AI 輔助的三個實用場景

    在絞殺專案中,AI 工具已經可以在三個環節產生實質效益:

  • 行為規格萃取:閱讀遺留程式碼,產出以 Gherkin 描述的行為規格草案,由人類工程師審核後轉為自動化測試。這把「理解舊系統」從數十人月壓縮到數週。
  • 測試資料生成:根據資料庫 schema 與業務規則,生成符合邊界條件的測試資料集,用於影子比對。
  • 差異根因分析:當影子比對產生大量差異時,AI 可以聚類差異模式,指出最可能的邏輯分歧點,大幅縮短除錯時間。
  • 但要強調:AI 產出的行為規格必須被驗證。錯的規格比沒有規格更危險,因為它會讓你在錯誤的基礎上建立信心。實務原則是「AI 提案、人類裁決、自動化驗證」。

    6.2 平台工程必須提供的能力清單

    若你正在規劃 2026 年的絞殺專案,請確認內部開發者平台已提供以下能力,否則專案進度會嚴重受制於基礎設施:

    能力若缺乏時的後果

    服務範本(含可觀測性骨架)每個團隊自己配日誌與追蹤,格式不一,無法跨服務比對

    流量治理(金絲雀、權重路由)無法做分層放量,只能一次全切

    Schema Registry事件格式變更導致消費者中斷

    統一的身分與政策服務間呼叫各自實作授權,稽核無法通過

    環境即程式碼無法快速建立影子比對所需的隔離環境

    成本可視化並存期的雙倍成本無人掌握,預算失控

    七、治理與度量:如何證明絞殺正在成功

    7.1 四個必須持續追蹤的指標

  • 絞殺覆蓋率:由新服務承接的業務能力佔比(以業務能力數或營收流程覆蓋率計,而非程式碼行數)。
  • 差異率(Divergence Rate):影子比對中不一致的比例,按業務語意分組。目標是在正式切換前降至可解釋的接近零。
  • 回滾頻率與時間:每次切換的回滾比例,以及從發現問題到完成回滾所需的時間。目標是回滾在五分鐘內完成。
  • 並存成本:同時維護兩套系統的額外基礎設施與人力成本,這是說服管理層持續投資的關鍵數字。
  • 7.2 組織層面的配套

    技術架構的改變若沒有組織配套,註定失敗。三個必要條件是:

  • 單體與新服務不得由同一組人同時負責。否則該團隊會優先處理單體的緊急需求,絞殺永遠排在後面。
  • 建立平台團隊,負責門面、CDC 管線、Schema Registry 與服務範本。這些是橫向能力,不應由各業務團隊重複實作。
  • 把「絞殺進度」納入常態性的管理檢視,與其他產品目標同級,而不是當成一個「有空再做」的技術專案。
  • 八、結語:絞殺是一場馬拉松,不是一次衝刺

    Strangler Fig 模式之所以在 2026 年重回架構舞台的中心,不是因為它是什麼嶄新的技術,而是因為它終於在成本、工具與治理三個面向上同時具備了可執行性。它承認了一個現實:企業核心系統不可能被一次性取代,它只能被持續地、有紀律地掏空與重塑。

    如果你正在規劃 2026 年的現代化專案,請記住三個最重要的原則。第一,第一個絞殺目標必須小、必須成功、必須完整走完全流程,它的價值在於驗證工具鏈與建立組織信心,不在於它本身的業務貢獻。第二,門面必須保持笨、資料必須單向流、交易邊界必須重新設計——這三件事做錯任何一件,專案都會退化成更糟的分散式單體。第三,絞殺的順序應該由業務價值驅動,而不是由技術難度驅動;否則你會發現自己花了兩年,卻只拆掉了無關緊要的邊緣功能。

    最後,請接受一件事:絞殺過程中,新舊兩套系統並存是常態,不是失敗的徵兆。真正的失敗,是試圖跳過並存期、直接進行一次完美切換。榕樹不會在一夜之間長成,它只是在每一個交易日裡,安靜地多包覆一點宿主的枝幹。企業核心系統的微服務化,也是如此。

    本文由「雅寶社區 · 頂客論壇」技術編輯團隊整理,歡迎在討論區分享你的絞殺實作經驗與踩坑紀錄。

    🏠 返回首頁