上一篇先整理了 Gateway 的責任,這一篇想把設定裡常見的三個名字分清楚:Route、Predicate、Filter。先知道誰負責哪一步,再看 YAML,會比較容易理解。
如果少了說明,設定越加越多,後面就會越來越不敢動。所以我希望路由設定除了能跑,也能讓接手的人看懂:這條規則為什麼在這裡,修改之後會影響哪個服務。
下面用一段路由設定範例,對照這三個部分的位置:
spring:
cloud:
gateway:
routes:
- id: material-service
uri: ${MATERIAL_SERVICE_URL:http://material-service:9095}
predicates:
- Path=/api/materials/**
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: ${RATE_MATERIAL_REPLENISH:80}
redis-rate-limiter.burstCapacity: ${RATE_MATERIAL_BURST:160}
redis-rate-limiter.requestedTokens: 1
key-resolver: "#{@clientKeyResolver}"
deny-empty-key: false
我會這樣讀這段設定:先用 id 找到路由對應的服務,負責人則回 Day 07 的 context card 查,再看 predicates 決定哪些請求會進來,最後看 filters 會做哪些處理。限流值由環境變數帶入,不同環境可以調整,預設值則留在版本紀錄裡;計數放在 Redis,多個 Gateway instance 才會共用同一份額度。
還有一行值得停下來看:deny-empty-key: false 表示算不出限流 key 的請求會放行。這裡的 key 來自呼叫端識別值,而 Day 09 說過 Gateway 會先驗 Token 基本有效性,沒有身分的請求在前一關就回 401,所以就算 key 算不出來也放行,不會出現「沒登入的人可以無限打」的漏洞。至於不用登入的路徑,抓不到 Token 就改用來源 IP 計數,所以 key 永遠算得出來,這個開關實際上不會用到,真正不能拆的是 IP 這層備援。如果限流跑在驗證之前,這一行就要改成 true。
每條路由,我都會對回 Day 07 的 context card,確認服務與負責人,並把公開路徑和內部路徑分開管理。Filter 處理共用政策,敏感 Header 由 Gateway 控制;至於 timeout、retry 與 circuit breaker,再依 API 的特性安排。

圖 Day 10-1:Spring Cloud Gateway 路由。
未知路徑也要測一次,確認帶有效 Token 時回的是預期的 404;因為 Security 先於路由執行,沒帶 Token 打未知路徑會先回 401,這是刻意不讓外部探到有哪些路由。如果有 fallback 路由,要再看看它會接住哪些請求,避免一條寫錯的路徑被轉送到不相關的後端。
若對外路徑直接等於內部服務結構,之後任何內部重構都會變成對外的破壞性變更。所以公開路徑與內部路徑要分開,讓對外契約可以獨立演進。
測試至少涵蓋正確路徑的路由、未知路徑 404、未驗證 401、無權限 403、限流 429,以及 Header 偽造、後端逾時與 correlation ID 傳遞。每項都要確認下游實際收到的內容與對外回應。
我自己會特別看下游實際收到了什麼。狀態碼正確,還不一定代表 Header 都處理好了;偽造的值有沒有被移除,correlation ID 有沒有帶到,都要一起驗證。
限流測試要先把「用誰的身分測試」固定下來。限流是按呼叫端計數的,今天用 A 的 Token 測、明天用 B 的,兩次結果就不能比。整輪測試都用同一個 Token,重跑幾次才對得起來。
| 取捨 | 這樣選的理由 | 何時要重新評估 |
|---|---|---|
| 限流參數以環境變數覆寫 | 各環境門檻值不同,但預設值仍可追溯 | 環境間差異大到預設值失去參考價值時 |
| 不對非冪等請求設定自動 retry | 重試可能建立重複交易 | 下游已具備冪等保證時(見 Day 19) |
| 路由設定納入版本控管 | 變更可審查、可回溯 | 需要在執行期動態調整路由時 |
| Predicate 不符合就回 404(帶有效 Token 時) | 路徑寫錯時當場看到錯誤,不會悄悄被轉到別的服務 | 有明確的降級或維護頁需求時 |
有幾個設定,我會多停下來確認。寫入型 POST 如果沒有冪等保護,重試可能多建一筆交易;StripPrefix 與 RewritePath 則要對照公開契約,看看轉送後的路徑是不是原本想要的。
| 指標 | 計算方式 | 想回答的問題 |
|---|---|---|
| 各 route 流量分佈 | 依 route id 統計請求數 | 哪些路由實際被使用? |
| 各 route 錯誤率 | 該 route 的 4xx/5xx 比率 | 問題集中在哪一條路由? |
| 各 route P95 延遲 | 依 route id 統計延遲 | 哪一條路由是效能瓶頸? |
| 設定變更紀錄 | 路由設定的 commit 與部署對應 | 行為改變能否對應到某次變更? |
個別路由變慢或出錯,很容易被整體數字蓋過去,所以量測要依 route id 分開看。之後要能對照是哪次調整前後出現變化,設定異動也記下部署時間。
把路由、條件與前後處理分清楚,設定就比較容易看懂,也比較知道要測什麼。下一篇,再繼續整理呼叫者的身分,以及 Keycloak、OAuth 2.0、OIDC 與 JWT 各自的角色。