Google PCD: API 設計、整合與事件驅動開發 — 學習指南
屬於 Google Professional Cloud Developer — 學習指南. 使用經過驗證的解答練習: Google 考試中心, 或參加限時模擬考試: ExamRoll.io.
總覽
在 Google Cloud 上的現代應用程式整合,融合了設計精良的同步 API 與具備韌性的非同步及事件驅動模式。其目標是提供清晰的契約、強大的身分識別、一致的錯誤處理以及操作控制,即使在發生故障、擴展或變更的情況下,也能保持低延遲和高可用性。本節涵蓋協定與 API 的選擇、閘道與驗證、訊息傳遞與事件路由、背景作業、編排、服務間的身分識別與信任、可靠性模式、安全的 webhook 以及安全的 schema 演進。
API 設計與管理
選擇正確的協定:
- REST:對人類友善,可透過 HTTP 快取,非常適合公開及合作夥伴的 API。採用資源導向設計、標準方法,並僅在有價值時使用 ETags 和 HATEOAS。權衡:契約不如 protobuf 精確;可能發生資料過度/不足擷取的問題。
- gRPC:使用 Protobuf 契約、雙向串流、高效的二進位傳輸;非常適合低延遲的內部服務間呼叫。權衡:瀏覽器支援需要 gRPC-Web;對公開客戶端而言,可觀測性與相容性可能更難達成。
- GraphQL:彈性的查詢方式,可減少取得複合視圖時的來回請求。權衡:複雜的解析器、N+1 風險、快取挑戰以及存取控制的細微差異。
版本控制與分頁:
- 偏好採用附加的、向後相容的變更。使用基於 URI 的主版本號 (例如 /v1),並透過欄位和功能旗標進行次要修訂。棄用時應提供明確的時間表。
- 使用穩定的游標或 nextPageToken 進行分頁,以避免在資料變動下出現頁面不一致的情況;對於大型資料集,應避免使用 offset。
驗證與錯誤:
- REST 使用 OpenAPI 定義請求/回應的 schema,gRPC 則使用 protobuf 的驗證規則。
- 採用一致的錯誤模型:對應到標準的 HTTP 狀態碼;gRPC 則使用 google.rpc.Status (包含 code、message、details)。應包含機器可解析的錯誤原因和一個關聯 ID。避免洩漏內部實作細節。
API 管理的選擇:
- API Gateway:一個輕量級的託管閘道,適用於 OpenAPI/gRPC 後端 (Cloud Run、Cloud Functions、GKE、Compute Engine)。支援驗證、API 金鑰、JWT 驗證、配額。適合無伺服器和直接了當的控制平面。
- Cloud Endpoints (ESPv2):與您的服務一同部署;支援 OpenAPI 或 gRPC 轉碼、驗證、配額和指標。適合偏好將代理與工作負載部署在同一位置的情境。
- Apigee:全生命週期的 API 管理平台,提供進階策略 (如尖峰流量抑制、配額、中介、轉換、OAuth 供應商、營利、開發者入口網站)。最適合複雜的合作夥伴生態系與南北向流量控制。
驗證與配額:
- 對終端使用者:使用 OAuth 2.0 或 Firebase Authentication;對服務:使用 Google 簽署的 ID token (OIDC) 或 OAuth 服務帳號 token (2-legged)。
- 在靠近客戶端的位置 (Apigee) 實施配額與尖峰流量抑制,並針對每個消費者 (透過 API 金鑰或用戶端憑證) 進行限制,以保護後端服務。
使用 Cloud Run 後端和 OIDC 的 API Gateway 最小 OpenAPI 範例:
openapi: 3.0.0
info: {title: orders, version: 1.0.0}
paths:
/v1/orders:
get:
security: [{firebase: []}]
x-google-backend: {address: https://orders-xyz-uc.a.run.app}
responses: {"200": {description: OK}}
components:
securitySchemes:
firebase:
type: http
scheme: bearer
bearerFormat: JWT
x-google-issuer: https://securetoken.google.com/PROJECT_ID
x-google-audiences: PROJECT_ID
非同步訊息傳遞與事件處理
Pub/Sub 基礎:
- 主題 (topic) 和訂閱 (subscription) 將發布者與消費者解耦。交付模式為至少一次 (at-least-once);可能會發生重複和順序錯亂的情況。
- 當處理時間較長時,使用確認 (acknowledgment) 並延長 ack 期限;應用客戶端流量控制以避免記憶體壓力。
- 排序:啟用訊息排序功能並提供排序鍵 (ordering key),以保證每個鍵值的訊息能依序交付;盡可能為每個鍵值維持單一的活躍發布者。
- 死信:設定死信主題 (dead-letter topic) 來存放毒訊息 (poison message),以防止無限重試;並對其進行監控和分類處理。
建立主題、訂閱和 DLQ:
gcloud pubsub topics create orders
gcloud pubsub topics create orders-dlq
gcloud pubsub subscriptions create orders-sub \
--topic=orders \
--dead-letter-topic=orders-dlq \
--max-delivery-attempts=5 \
--ack-deadline=30
消費者端的考量:實作冪等處理器和去重複機制 (例如,透過 messageId 或應用程式層級的冪等鍵);對於暫時性錯誤,使用退避 (backoff) 機制進行重試;將無法復原的訊息移至 DLQ 並發出警報。
Eventarc 與 CloudEvents:
- Eventarc 將來自 Google Cloud 服務、自訂來源和稽核日誌 (Audit Logs) 的事件路由到 Cloud Run、Cloud Functions 或 GKE。事件使用 CloudEvents 封套 (包含 id、source、type、subject、time)。
- 在觸發器端依屬性 (如 type、subject、location) 進行篩選,以減少雜訊和成本。使用專屬的服務帳號以符合最小權限原則。
為 Cloud Storage 物件完成事件建立 Eventarc 觸發器:
gcloud eventarc triggers create index-new-objects \
--destination-run-service=media-indexer \
--destination-run-region=us-central1 \
--event-filters="type=google.cloud.storage.object.v1.finalized" \
--event-filters="bucket=my-assets-bucket" \
--service-account=eventarc-router@PROJECT_ID.iam.gserviceaccount.com
權衡:
- Pub/Sub 針對拉取 (pull) 模式進行了優化,並在高吞吐量下具有高韌性;Eventarc 則簡化了來自您無法控制的生產者的事件路由,並使用標準化元資料將事件推送 (push) 到您的服務。
- 若要求嚴格排序或有嚴格的成本上限,可考慮在發布者端進行分割 (partitioning) 和速率限制;若要求極低延遲的扇出 (fanout),則需謹慎調整訂閱者的並行度。
編排、背景作業與長時間執行的程序
Cloud Tasks:
- 用於可靠背景 HTTP 呼叫的推送佇列 (push-queue)。設定每個佇列的分派速率和並行度以保護後端。設定包含指數退避 (exponential backoff) 和最大嘗試次數的重試策略。
- 透過確定性的任務名稱或 Idempotency-Key 標頭來確保冪等性,並在伺服器端進行去重複。快速回應 (2xx),並在需要時非同步地執行繁重的工作。
建立具有速率限制和重試機制的佇列:
gcloud tasks queues create payments-queue \
--max-dispatches-per-second=50 \
--max-concurrent-dispatches=200 \
--max-attempts=10 \
--min-backoff=5s \
--max-backoff=300s
Workflows:
- 跨 HTTP 和 Google Cloud 連接器來編排多步驟的業務流程。為部分失敗的情況建立補償性動作模型 (saga 模式);避免使用分散式交易。
- 使用步驟層級的逾時和重試策略;在重試之間持久化狀態,以便在中斷後能恢復執行。輪詢長時間執行的操作,並在期限到達時取消。
補償流程示意:
main:
params: [orderId]
steps:
- charge:
call: http.post
args: {url: ${paymentsUrl}/charge, auth: {type: OIDC}, body: {orderId: ${orderId}}}
result: chargeRes
- reserveInventory:
try:
steps:
- reserve:
call: http.post
args: {url: ${inventoryUrl}/reserve, auth: {type: OIDC}, body: {orderId: ${orderId}}}
except:
as: e
steps:
- refund:
call: http.post
args: {url: ${paymentsUrl}/refund, auth: {type: OIDC}, body: {paymentId: ${chargeRes.body.id}}}
- raise: ${e}
操作指引:
- 對於需要精確速率控制、發送到單一服務的「發後不理」(fire-and-forget) 式背景 HTTP 呼叫,優先選用 Cloud Tasks。對於扇出 (fanout) 和多個消費者的情境,使用 Pub/Sub。當您必須協調多個帶有分支邏輯和補償機制的呼叫時,使用 Workflows。
身分認證、可靠性與整合
服務對服務的身分認證與權杖傳遞:
- Cloud Run/Functions/Compute Engine/GKE 的工作負載應使用具備最低權限的服務帳戶。在 GKE 上,使用 Workload Identity 以避免節點層級的憑證。
- 對於 Cloud Run 對 Cloud Run 的呼叫,應使用 ID 權杖,其 audience 需與目標 URL 相符。僅在下游服務必須代表呼叫者執行操作時,才傳遞身分;否則應使用被呼叫者的服務帳戶。
在 Cloud Run 中取得 ID 權杖:
AUD="https://inventory-xyz-uc.a.run.app"
TOKEN=$(curl -s -H "Metadata-Flavor: Google" \
"http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience=${AUD}")
curl -H "Authorization: Bearer ${TOKEN}" "${AUD}/v1/check"
同步依賴與彈性:
- 將用戶端逾時設定得比上游逾時更短;為每一跳(hop)設定預算。僅對冪等(idempotent)操作進行重試,並採用截斷指數退避(truncated exponential backoff)與抖動(jitter)。透過限制總重試時間來避免重試風暴。
- 使用斷路器(circuit breaker)在上游服務不健康時快速失敗;在 GKE/Apigee/Envoy 中,您可以設定最大待處理請求數、失敗時的驅逐(ejection)以及健康探測(health probe)。提供合理的備援機制或優雅地降級。
- 將暫時性錯誤(429、408、500–503)對應到可重試的行為;將 4xx(408/429 除外)視為不可重試。
Webhook 與第三方整合:
- 使用帶有共享密鑰的 HMAC 簽章標頭或已簽署的 JWT 來驗證傳入的請求;若要更高的保證,請使用 mTLS。將密鑰儲存在 Secret Manager 中並定期輪替。
- 快速回應確認;將繁重的處理程序加入 Cloud Tasks 佇列或發布到 Pub/Sub 以進行解耦。對傳入的 IP 或金鑰進行速率限制,以保護後端。
- 對外發送的 Webhook:包含一個 Idempotency-Key 以允許安全的重試,並驗證遠端的 TLS 憑證和主機名稱。
結構演進與相容性:
- REST/JSON:新增欄位是安全的;絕不應重用或更改現有欄位的類型/意義。將欄位標記為已棄用,並在一段時間內繼續提供服務。
- Protobuf/gRPC:絕不重用欄位編號;使用保留的標籤;偏好使用可選欄位;預設值和存在語意對相容性至關重要。
- 事件:包含一個 dataVersion 並保持 CloudEvents 屬性的穩定;為擴充功能預留空間。對於 Pub/Sub,考慮使用 Pub/Sub Schema (Avro/Protobuf) 在發布時進行驗證。
- 測試:使用消費者驅動的合約測試、模擬器(Pub/Sub、Datastore/Firestore)或隔離的專案,以及金絲雀版本。在 CI 中使用臨時環境和實際的配額來執行整合測試,以揭露潛在的故障。
整個技術堆疊的安全性與配額:
- 在邊緣(API Gateway/Apigee/Endpoints)和服務層級強制執行驗證。套用每個消費者的配額和突波抑制(spike arrest)。監控 401/403 的突增和 429 的速率,以調整用戶端的退避策略和配額。
- 跨元件記錄請求 ID 並傳遞追蹤標頭(Traceparent 或 X-Cloud-Trace-Context),以實現端到端的可觀測性。
實務問題情境
AcmeRetail 正在 Google Cloud 上建立一個「點擊取貨」(click-to-collect)服務。一個 React 網頁應用程式呼叫一個公開的 API 來下訂單;後端服務必須預留庫存、收取款項並通知店家。團隊需要低延遲的 API、可靠的背景處理、事件驅動的更新,以及在部分失敗時的安全回滾機制。
方法:
- 透過 API Gateway 將一個公開的 REST API 暴露在一個 Cloud Run 訂單服務之前。
- 理由:對瀏覽器來說,使用 JSON 的 REST 很簡單;API Gateway 會驗證來自 Firebase Auth 的 JWT、對每個用戶端強制執行 API 金鑰和配額,並在邊緣終止連線。Cloud Run 會隨著流量高峰自動擴展。
- 對於內部熱門路徑(訂單到庫存、定價),使用 gRPC 實現服務對服務的呼叫。
- 理由:gRPC 減少了序列化開銷並提供嚴格的合約。在服務之間使用 Workload Identity (GKE) 或服務帳戶 (Cloud Run) 以及 OIDC。對於冪等讀取,逾時設定為 300 毫秒,並帶有兩次重試和抖動。
- 使用 Workflows 來協調訂單的 saga 模式:收取款項、預留庫存、建立取貨任務;並在失敗時進行補償。
- 理由:集中式協調管理長時間執行的步驟和補償。如果預留失敗,Workflows 會觸發退款並向用戶端返回 409。
- 將領域事件發布到 Pub/Sub 的 orders 和 inventory 主題,供下游消費者(分析、店家通知)使用。
- 理由:不需緊密耦合即可實現扇出(Fanout)。訂閱者以 orderId 為鍵實現冪等性。訂閱設有死信主題(dead-letter topics),其 max-delivery-attempts=10,並在 DLQ 增長時觸發警報。
- 當 Cloud Storage 和 Firestore 發生相關變更時,透過 Eventarc 觸發店家通知,傳送到一個 Cloud Run 通知服務。
- 理由:Eventarc 使用屬性篩選器僅路由必要的事件;CloudEvents 確保元資料的一致性。通知器使用 Cloud Tasks 將訊息發布到第三方 SMS/電子郵件供應商,以控制速率和重試。
- 使用一個專用的 Cloud Run 端點處理支付供應商的 webhook,該端點由 API Gateway 保護,並驗證 HMAC 簽章,同時使用 Cloud Tasks 進行處理。
- 理由:快速的 200 確認回應可減少供應商的重試;Tasks 確保使用退避策略進行重試。密鑰儲存在 Secret Manager 中;請求主體會根據 OpenAPI 結構進行驗證。
- 強制執行可靠性模式:在 Apigee 或 Envoy 上為對支付供應商的對外呼叫設置斷路器;將用戶端逾時設定在供應商的 SLA 以下;對 429/5xx 錯誤使用截斷指數退避進行重試。
- 理由:防止連鎖故障和重試風暴,尊重第三方限制,並將暫時的超載轉化為優雅降級。
- 採用結構演進控制:內部 gRPC 使用帶有保留欄位的 Protobuf;REST 回應使用附加性的 JSON 變更;Pub/Sub 在發布時使用 Protobuf 結構驗證。
- 理由:維持消費者的相容性。合約和整合測試在每次合併時於 Cloud Build 中運行;金絲雀部署可安全地驗證真實流量。
- 觀測與操作:在 API Gateway 和服務之間傳遞追蹤標頭;匯出 Cloud Logging 指標以監控錯誤率和 DLQ 大小;針對 SLO 耗用和 429/5xx 異常情況發出警報。
- 理由:快速偵測回歸、配額問題或供應商事件;SRE 可以快速調整配額和退避策略。
← 運算、容器與 Serverless 執行階段平台 · 所有領域 · 應用程式資料、狀態與儲存模式 →
練習這些題目 → · 在 ExamRoll.io 上限時練習 →
Pass the whole exam — not just this question
You found this answer. Get every verified question and explanation in one place, and save hours of prep. Free to start.
通過考試 →