本頁提供撰寫正確、效能良好且隔離性佳的 Service Extensions 外掛程式的訣竅。正確性至關重要,因為外掛程式會在受限的引擎沙箱中執行,且 API 介面有限。外掛程式會在使用者要求期間執行,且資源用量較少,因此效能至關重要。專案層級提供隔離功能。
開始使用
從範例開始
建議您先瀏覽我們的外掛程式碼範例。這些是常見的外掛程式模式範例,例如路徑或查詢剖析、標頭重寫、自訂記錄和自訂驗證。
使用支援的 API
外掛程式必須根據 Proxy-Wasm 二進位檔介面 (ABI) 編譯。Service Extensions 支援 Proxy-Wasm ABI 的子集,包括 HTTP 標頭和主體突變、本機回應、自訂記錄和外掛程式設定。Proxy-Wasm 也支援一小部分的 WASI 預先發布版 1,包括用於記錄的 stdout 和 stderr,以及 clock_time_get 和 random_get。
Service Extensions 不支援計時器、自訂指標、共用資料、共用佇列或輸出網路呼叫。服務擴充功能也不支援嘗試暫停要求處理作業的外掛程式回呼傳回值,並會忽略這些值。
執行功能測試和基準測試
為評估正確性和效能,我們提供本機外掛程式測試工具,可執行、測試及評估外掛程式。您可以在 Docker 容器中叫用這項工具,並傳遞外掛程式二進位檔,以及輸入和預期的文字原型。請參閱本機測試人員說明文件和測試輸入範例。
正確性
不要依賴時鐘
基於安全考量,系統會在建立外掛程式或要求時設定時鐘時間,並在外掛程式呼叫期間保持凍結。這表示 WebAssembly 外掛程式不得休眠,因為時間不會前進,休眠會逾時。這也表示外掛程式無法測量自己的執行時間,但這項資訊會顯示在 Cloud Monitoring 中。
將標頭名稱視為不區分大小寫
根據 HTTP 語意,HTTP 標頭欄位名稱不區分大小寫。外掛程式撰寫的標頭大小寫可以在傳送至用戶端或後端前變更。
效能
避免外掛程式當機
外掛程式當機時,觸發要求會收到錯誤訊息。如果這種情況經常發生,外掛程式重新啟動的頻率就會受到限制,導致錯誤大量湧現,影響多位使用者。
為避免外掛程式當機,請嘗試下列做法:
- 請避免使用任何類型的斷言。請改為設定錯誤記錄或向使用者提供本機回應。
- 在 Rust 中,請避免使用可能導致恐慌的方法,例如
unwrap。此外,您可以使用panic::set_hook設定外掛程式來處理當機問題。 - 使用 Google 提供的外掛程式測試工具測試外掛程式,確保外掛程式能處理格式錯誤或空白的輸入內容,不會因此當機。
編譯以提升執行速度
使用建構選項 -O3 (適用於 C++) 或 opt-level=3 (適用於 Rust),編譯 WebAssembly 程式碼,以達到最佳執行速度。
預先編譯規則運算式
避免在每個要求的路徑 (在 HTTP 處理常式中) 執行需要大量運算的作業。 請改為在外掛程式設定時執行任何與要求無關的工作,並將任何預先計算的狀態傳遞至每個 HTTP 要求環境 (也稱為串流環境)。
特別是,請在設定外掛程式時預先編譯任何規則運算式。我們的正則運算式程式碼範例說明如何達成這個目標。
避免將資料複製到 HTTP 環境
在根環境和 HTTP 環境之間共用資料時,請避免耗費資源的副本或複製呼叫。請改為分享指標或參照。在 C++ 中,這可透過 std::shared_ptr 或原始指標和參照完成,因為根層級的內容會比任何 HTTP 內容都長。在 Rust 中,可以使用 std::rc::Rc 共用值。在 Go 中,您可以儲存值的指標來共用值,而垃圾收集器會移除這些指標。
安全性
依專案區隔工作負載
在 Google 的基礎架構上,屬於同一 Google Cloud 專案的外掛程式可以在同一個安全沙箱中執行。也就是說,WebAssembly 執行階段是同一專案中外掛程式之間唯一的安全屏障。
針對需要安全區隔的工作負載,使用個別專案。 Google Cloud 這項做法也能確保資源和權限分開處理。
限制 Media CDN 上的密鑰
根據設計,Media CDN 運作時使用的硬體機群,並非由 Google 實體控管。為 Media CDN 編寫安全性相關外掛程式時,請使用專屬主機名稱或子網域,並使用經常輪替的簽署金鑰設定外掛程式。