為什麼造一個 kitchen-sink 框架
為什麼造一個 kitchen-sink 框架
現代 Go 社群偏好小而組合的庫,這在微服務裡是對的。但情境換成平台團隊,目標就從「輕量」變成「強制一致性」。gortex 復刻的正是後者的思維。
建議先讀 A 軌 Go 基礎五篇。
YAGNI vs Platform Engineering
Go 社群的主流是把標準、小巧的庫組起來,像 Go 1.22+ 的原生 ServeMux、或 chi。對單一微服務來說,這完全符合 YAGNI:不需要的東西就別先蓋。gortex 同意這個判斷,在那個情境下。
但把鏡頭拉到平台工程(大型基礎設施團隊),目標就不同:不再是每個服務各自輕量,而是跨幾十個服務強制一致、高可觀測。kitchen-sink 框架不是在回答微服務那題,是在回答這一題;同一個設計,放在微服務是過度設計,放在平台治理才是對的場合。
一致性、可觀測性、依賴收斂
gortex 把複雜度刻意集中到框架層,換三件事(架構哲學文件講得很清楚):
-
強制一致性:自訂
Context、強制綁定的Config、統一的Logger,讓跨部門、跨服務的程式碼在處理請求、寫 log、讀設定時長一個樣,維運跨專案除錯的認知成本就低。Config 支援 YAML /.env/ 環境變數混搭覆蓋,正是為了 K8s:本地讀設定檔、上線同一個 image 改由 K8s 注入環境變數,兩邊共用同一套解析。 -
內建可觀測性:分散式 tracing(Jaeger / OpenTelemetry)、httpclient 連線池指標、內建
/_routes與/_monitor端點,全部框架底層吸收。業務開發者不用每開一個新專案就重接一次 Prometheus 或 tracing middleware。 -
依賴收斂:路由、參數綁定、中介層都收在框架內。遇到資安漏洞或要全域改行為(改 CORS 預設、調全域 timeout),只要升框架版本,不用去每個 repo 逐一追它用了哪套第三方庫。
app, _ := app.NewApp(app.WithHandlers(&HandlersManager{}))
// 路由、Context、Logger、tracing、/_monitor 都在這一層之下,業務碼不重接
權衡與技術債
把複雜度留在框架層,對業務端友善,但框架自己要扛高維護責任:
- 與標準庫解耦:自訂
Context換來一致性,代價是社群那些針對原生http.Handler寫的 middleware 不能直接套,得自己做轉接層。 - 維護成本:自維 segment-trie 路由器與 HTTP client 連線池,等於要自己處理極端邊界與效能瓶頸,像 goroutine leak、惡意連線、慢消費者。這些後面逐篇拆:路由比對是 B3、Hub 的優雅關機是 B6、安全預設是 B8。
天下沒有白吃的抽象。整合帶來的好處,是用框架層的維護負擔換來的。
定位:研究與紀錄
直說:gortex 不是要跟 Gin、Echo 或標準庫競爭的開源框架。它是一個 reference implementation,主要由 AI 協助、在本地復刻過去那種「通用基礎設施框架」的架構哲學,研究與紀錄用途,不為 production。它要展示的是一件事:當系統開發的重點從「單一微服務的輕量化」轉向「跨服務的基礎設施統一與治理」,框架層會被迫做出哪些設計決策與取捨。
重點整理
- 小庫組合在微服務是對的(YAGNI);kitchen-sink 是回答另一題:跨服務的一致性與治理。
- 三支柱:強制一致性(Context / Config / Logger)、內建可觀測性(tracing / metrics /
_monitor)、依賴收斂(改一次框架,不用追每個 repo)。 - 代價誠實列出來:與標準庫解耦要 adapter,自維 router 與連線池要扛邊界與效能。
- 定位是 reference implementation,研究與紀錄,不是 production 框架。
- 接下來 B2–B9 逐一拆這些決策怎麼落地,從 B3〈Segment-trie 路由器〉(
gortex-segment-trie-router)開始。
原始碼:yshengliao/gortex。
大綱 Sheng,內文 Claude 協助 · 環境 Go 1.24(gortex go.mod)· 本系列為事後回填整理 · 列入 20260613 blog 翻新計劃,新漆未乾。