題幹與適用場景
平台需要讓第三方外掛處理檔案轉換、欄位驗證和租戶自訂規則。外掛來自不同語言,不能直接信任,也不能因單一外掛失控拖垮宿主程序。請設計基於 Wasm Component Model 的執行時,涵蓋介面定義、載入、隔離、資源預算、相容升級和故障復原。
Component Model 用元件、介面和 world 描述匯入匯出,WIT 作為介面定義語言,Canonical ABI 負責跨語言的高階型別表示。題目考察候選人能否把標準能力轉成可營運的多租戶外掛平台。
面試官考察點
重點包括介面與資料型別治理、最小能力、實例隔離、CPU 與記憶體預算、逾時與取消、元件簽章與來源、版本相容、結果可重現性、日誌與指標,以及灰度與回滾。
回答前需要釐清的問題
- 外掛是在同步請求內執行,還是非同步任務;單次延遲與吞吐預算是多少?
- 外掛需要檔案、網路、金鑰或時鐘等哪些能力,租戶之間如何隔離?
- 介面是否允許 resource、stream 和 future,還是只允許有界值型別?
- 外掛升級要保持舊租戶可重現嗎,相容窗口多長?
- 違規或逾時外掛應立即終止、隔離後重試,還是回退到宿主實作?
30 秒回答框架
「先用 WIT 定義窄介面和版本化 world,只暴露業務所需能力。控制面驗證來源、簽章和依賴,資料面在獨立 Wasm 實例中執行,設定 CPU、記憶體、輸出大小和 deadline。按介面版本做相容檢查和灰度,所有呼叫記錄版本、租戶、預算消耗和結果摘要。逾時或違規只熔斷該外掛,回退到安全預設實作。」
分步驟深入解答
第一步:設計 WIT 介面與資料邊界
介面優先使用有界的 record、variant、list 和 result,明確錯誤列舉、最大長度和編碼。避免把宿主內部物件或隱含全域狀態暴露給外掛;每個 world 只包含該類外掛需要的匯入與匯出。
world transform-v2 {
export transform: func(input: record { bytes: list<u8>, mime: string }) -> result<list<u8>, transform-error>
}介面倉庫記錄套件名稱、版本、相容規則和產生繫結的工具鏈版本。對串流資料另設介面並規定背壓,不把無限輸入偽裝成普通 list。
第二步:建立能力與租戶隔離
宿主為每次呼叫建立獨立實例,預設不提供網路、檔案系統、環境變數、隨機數或金鑰能力;確需存取時透過明確 host function 授權,並綁定租戶、外掛和請求身分。
能力令牌應短時、可稽核且不可跨租戶重放。把宿主 API 設計成最小權限介面,禁止外掛直接取得宿主程序指標或未過濾的系統控制代碼。
第三步:設定資源預算與終止機制
為實例設定 CPU 指令或時間預算、線性記憶體上限、表格/堆疊限制、輸出大小和並發配額。宿主以 deadline 傳播取消,超過預算立即終止實例並記錄原因;重試前先判斷外掛是否具冪等性。
長任務採用非同步佇列和租約,避免把無限等待放在使用者請求中。資源計費和限流按租戶與外掛雙維度統計,防止單一租戶占滿共用執行池。
第四步:處理元件版本與 ABI 相容
發布前解析 WIT world 和依賴,檢查匯入匯出是否符合相容規則。Canonical ABI 解決跨語言值的表示,但不自動解決業務語意相容;例如列舉新增、錯誤含義改變和單位變化仍需契約測試。
保留舊 world 的執行器和繫結,允許外掛宣告支援的介面版本。升級採用雙讀或影子執行比較結果,確認誤差與資源變化後再切換預設版本。
第五步:驗證供應鏈與載入路徑
建置產物產生不可變摘要,簽章涵蓋元件、WIT world、依賴鎖定檔和建置中繼資料。控制面只允許可信簽發者和通過掃描的依賴;載入時再次校驗摘要、簽章、目標執行時版本和撤銷狀態。
外掛註冊、審批、撤銷和回滾都寫入稽核日誌。禁止執行時下載未登記元件,快取按摘要尋址,避免標籤移動導致實際程式碼變化。
第六步:觀測、灰度與故障復原
每次呼叫記錄外掛摘要、介面版本、租戶、延遲、資源消耗、結果狀態和錯誤類別;日誌欄位不得包含使用者原文或金鑰。指標按外掛與租戶聚合,追蹤逾時、記憶體耗盡和拒絕率。
新版本先在合成流量或少量租戶灰度,比較結果差異和尾延遲。發生異常時停止該版本、撤銷註冊並切回上一摘要;宿主提供安全預設結果,避免外掛故障傳播到主業務。
高品質示範回答
我會用版本化 WIT world 定義窄介面和有界型別,只授予外掛必要的 host capability。每次請求執行獨立實例,限制 CPU、記憶體、輸出與 deadline,控制面校驗簽章、摘要、依賴與撤銷狀態。升級先做契約檢查、影子執行和小流量灰度,觀測按外掛、租戶與版本拆分;逾時或違規只終止該實例並回退到安全預設實作。
常見錯誤
- 把宿主物件直接暴露給外掛 → 越權和跨租戶洩露 → 使用最小化 host function。
- 只限制記憶體不限制時間 → 無限迴圈仍占滿執行池 → 同時設定 CPU、deadline 與並發配額。
- 認為 Canonical ABI 等於業務相容 → 單位和錯誤語意仍可能破壞呼叫方 → 保留契約測試和 world 版本。
- 按標籤快取元件 → 標籤移動後執行未知程式碼 → 按不可變摘要和簽章尋址。
- 失敗後重試所有外掛 → 非冪等副作用被重複執行 → 宣告冪等性並按錯誤類別決策。
追問及應對
追問一:為什麼不用程序或容器隔離?
取決於威脅模型與預算。Wasm 實例啟動快、介面可控,但不能取代執行時修補、宿主加固與縱深防禦;高風險外掛仍可放入更強隔離層。
追問二:如何支援串流大型檔案?
定義具背壓的 stream 介面,限制並發、區塊大小與累計輸出,使用非同步任務處理長尾,並把取消與租約狀態納入稽核。
追問三:如何判斷兩個版本結果一致?
用固定輸入集做影子執行,比較規範化結果、錯誤類別、延遲和資源消耗;允許已宣告的浮點或排序差異,並對不可接受差異設定發布門禁。
追問四:外掛需要網路存取怎麼辦?
透過按租戶與網域授權的代理能力存取,強制逾時、回應大小和稽核;預設拒絕任意位址,並在撤銷時立即使能力令牌失效。