Go Middleware Chain Ordering¶
概念概覽
Bug 描述¶
核心知識¶
Bug 描述¶
game-server 的 middleware 執行順序錯誤:
問題根因:ResponseMeta middleware 在執行時讀取 X-Trace-Id,但此時 Tracing middleware 尚未執行,span context 還沒建立,所以 X-Trace-Id 抓到的是空值。
修正原則¶
Go HTTP/gRPC middleware chain 的設計規則:
- Context 生產者先於消費者:任何需要讀取 trace_id / span context 的 middleware,都必須排在 Tracing middleware 之後
- Recovery 永遠最外層:確保 panic 不會讓 middleware chain 直接崩潰
- Logging 通常最後執行(在 chain 最外或特定位置),這樣才能記錄到完整的 response 狀態
// 推薦順序示例
engine.Use(
middleware.Recovery(),
middleware.Tracing(), // 先建立 span context
middleware.ResponseMeta(), // 再讀取 trace_id 注入 response header
middleware.Logging(), // 最後記錄完整資訊
)
經驗教訓¶
-
Middleware 順序 bug 不會有 compile error 或明顯 runtime panic,只會在特定欄位出現空值,需要靠 trace 分析才能發現
-
新增 middleware 時要明確問:這個 middleware 有沒有依賴其他 middleware 產生的 context 值?
常見陷阱¶
- Tracing middleware 排在 ResponseMeta 之後,導致 response header 的 X-Trace-Id 永遠是空的,debug 時誤以為 tracing 沒有啟用
最佳實踐¶
-
middleware chain 要有文件或 comment 說明各層職責與依賴關係
-
Context 生產者(如 Tracing)必須早於消費者(如 ResponseMeta、Logging with trace_id)
相關概念¶
- API Refactoring PR Splitting Strategy
- Circuit Breaker Outcome Semantics
- Go Test Coverage -coverpkg Flag
- Observability Maturity Framework
- OpenTelemetry Trace Pipeline
來源 Sessions¶
| 日期 | Session | 貢獻摘要 |
|---|---|---|
| 2026-03-24 | 6295486a-8e60-49c7-a5da-f375c806641a | 發現並記錄 Go game-server middleware 順序 bug:Tracing 必須在 ResponseMeta 之前,否則 X-Trace-Id header 無法正確注入 |