遷移
兩條路並存 → 讀方逐一搬過去 → 收回授權
沒有東西是一步遷完的,也沒有東西是一次全遷的。每一份資料各自切換過去,整個環境在最後一份切完時才算完成。
五個步驟
| 步驟 | 完成判準 | |
|---|---|---|
| 01 | 擁有者發布契約並開始服務 | API 有回應,直連那條路完全不動 |
| 02 | 讀方逐一搬過去 | 每個讀方的呼叫都走契約 |
| 03 | 觀察到直連流量歸零 | 資料庫側看不到來自該憑證的查詢 |
| 04 | 收回授權 | 該憑證不再存在 |
| 05 | 核發不出新的授權 | 憑證由密鑰引擎核發,且只發給擁有者 |
第 03 步是量出來的,不是宣稱的。「我們認為都搬完了」與「日誌顯示兩週沒有任何查詢」是兩種不同的主張,只有後者撐得起第 04 步。
為什麼判準是收回授權
一個跑在仍然開著的直連旁邊的 API,是多了一個元件,沒有少掉任何耦合。第 02 頁上的每一項代價都還在付:schema 仍然被那些還在直連的讀方釘住、稽核軌跡仍然只記得到連線、讀方仍然不明。
更麻煩的是,這種遷到一半的狀態很穩定。它看起來像進度、demo 起來好看,而且沒有任何力量推它往前。一場用「上線幾個 API」衡量的遷移,會抵達 API 百分之百、效益百分之零。
所以里程碑的完成判準是收回授權,而且路線圖上明講。
順序:影響最小的先做
波次依「切壞了會影響多少」排序,最小的先。這與 IaC 重建(項目 02)和 Kubernetes 遷移(項目 26)已經在遵守的規矩相同:先在可復原的對象上驗證做法,再處理其餘一切所依賴的資料。
適合當第一份的資料,特徵是讀方少、擁有者明確、而且沒有跨到另一份資料的不變量。
什麼時候不該用 API
不是所有存取都變成同步呼叫。假裝可以,就是這件事在第一個像樣的需求出現後被放棄的原因。
| 這種讀取 | 去哪裡 | 為什麼 |
|---|---|---|
| 大量或歷史型 —— 報表、回填、跨百萬列的 join | 項目 27 — Trino 資料倉儲 | OLTP 資料庫不該服務它,擺在它前面的 API 也不該。用分頁 HTTP 撈一百萬列,只是一次更慢更貴、還多出一堆失敗模式的全表掃描。 |
| 可容忍延遲 —— 快取、投影、另一個服務的本地副本 | 項目 28 — 事件匯流排 | 擁有者發布變更,消費者自己維護副本。沒有同步依賴,擁有者也不必扛這份讀取負載。 |
| 需要當下的值,現在就要 | 契約 | 這才是 API 存在的目的。 |
在設計契約的當下就把這條線劃出來,是里程碑 30.2 的一條 task,理由就在這裡:不劃這條線,API-first 會把批次查詢變成 HTTP,並連帶把資料庫打掛 —— 而事後得出的結論會是「API-first 行不通」。
防止長回來
最後一步是讓已完成的工作維持下去的那一步。資料庫憑證只由動態密鑰引擎核發(路線圖項目 12),而且只發給該份資料的擁有者服務。沒有單一核發路徑,直連會安靜地長回來,盤點就得重做一次。
在這裡開例外流程,就是讓整個環境回到原點的那套機制。