
用 Go 構建分散式系統與微服務
簡單、快速,為併發而生
為什麼 Go 主導了雲基礎設施
Go 是為大型網路系統而生的:編譯快、語言精簡、標準庫的 I/O 能力紮實。正因如此,Docker、Kubernetes、Terraform、etcd,以及一大批基礎設施工具,都以單個靜態二進位制檔案的形式釋出。
論單個 CPU 週期的速度,它並不是最快的語言;但對於把時間花在 RPC、序列化和扇出(fan-out)上的服務來說,它往往能讓團隊最快把東西推上生產環境——這恰好就是大多數非撮合核心的交易所後端。
GaiaEx 這類技術棧,在吞吐量和簡潔性比從熱迴圈裡摳出最後幾納秒更重要的地方,就用 Go。
Goroutine 與 Channel:讓併發變簡單
Goroutine 是廉價的使用者態任務;channel 在它們之間傳遞訊息。帶有 CSP 風味的箴言是:優先用訊息傳遞,而不是共享記憶體——這仍然靠紀律,而非魔法。
func processOrders(orders <-chan Order) {
for order := range orders {
go handleOrder(order)
}
}
Channel 承載帶型別的值;select 對多個等待進行多路複用。配合 go test -race 使用——會發生資料競爭的金融程式碼不是「最終一致」,而是錯的。
併發很容易寫出來;正確性仍然要靠測試和評審來掙得。
用 Go 構建 HTTP 服務與 gRPC
對很多 API 來說,net/http 就夠用了;路由庫再加上路由分發和中介軟體。在資料中心內部,gRPC + protobuf 更勝一籌:負載更小、可生成程式碼、支援流式傳輸——當內部呼叫量遠超對外 JSON 流量時尤其好用。
func main() {
mux := http.NewServeMux()
mux.HandleFunc("GET /api/v1/ticker/{symbol}", handleTicker)
mux.HandleFunc("POST /api/v1/orders", handleNewOrder)
server := &http.Server{Addr: ":8443", Handler: mux, ReadTimeout: 5 * time.Second}
log.Fatal(server.ListenAndServeTLS("cert.pem", "key.pem"))
}
Go 的介面是隱式實現的——在測試裡 mock 儲存層時,不必引入笨重的框架。
Go 在區塊鏈節點與交易所後端中的應用
Geth、Cosmos/Tendermint 系列技術棧、Fabric、Cockroach——在區塊鏈和資料庫領域,Go 無處不在。交易所的膠水層——閘道器、風控預檢查、websocket 扇出——天然適合用 Go。
跑在個位數微秒級的撮合引擎,往往仍是 C++/Rust 的地盤;而圍繞它們的一切,都任 Go 發揮。
GaiaEx 在 API 邊緣和實時行情上用 Go;在 Hyperliquid L1 上的執行則是另一層——要清楚自己負責的是哪一份延遲預算。
錯誤處理、測試與 Go Modules
顯式返回 error 囉嗦但誠實——對於資金流轉,吞掉錯誤是不可饒恕的。用 %w 包裝錯誤,讓呼叫方能對失敗進行分類。
go test、基準測試和 pprof 都是一等公民。表驅動測試(table-driven tests)讓用例一目瞭然。
Modules 透過 go.mod/go.sum 鎖定版本——當生產環境不是你的筆記本時,可復現的構建很重要。
什麼時候該選 Go——什麼時候不該
適合:網路服務、CLI、operator、CPU 負載中等而 I/O 繁重的場景。
不適合:追求最低延遲的撮合、不能容忍 GC 暫停的硬實時保證、繁重的數值型機器學習——要挑對趁手的工具。
當「能交付、好運維」和理論峰值 QPS 同樣重要時,Go 就會勝出——而這正是交易周邊的大多數基礎設施。