尬住了,Go HTTP/3 又又被擱置了!
2024 年,Go 核心團隊成員 @neild 提交了一個新提案 #70914[1],打算在 x/net/http3 中添加 HTTP/3 的實驗性實現。
圖片
本以為這次也算是正式啟動了。能有些苗頭。結果萬萬沒想到,這個提案能又被半路擱置了!
圖片
要知道,這已經不是 Go HTTP/3 第一次 "跳票" 了。
背景:多年的苦等
說起來挺無奈的,Go 社區對 HTTP/3 的呼聲由來已久。早在 2019 年 5 月,社區就開了 Issue #32204[2] 來追蹤 HTTP/3 在標準庫中的實現進度。那時候 HTTP/3 還只是 IETF 的草案,大家也能理解官方的謹慎態度。
圖片
但是現在都 2025 年了!HTTP/3 早在 2022 年 6 月就被 IETF 正式發布為提議標準(RFC 9114)了,主流瀏覽器的支持率已經超過 95%,全球前 1000 萬網站中也有 34%支持了 HTTP/3。
圖片
簡單來說,HTTP/3 已經不是什么"新鮮玩意兒"了,它是實打實的生產級協議。可 Go 官方在標準庫層面,依然沒有動靜。
提案內容:看似穩妥的方案
我們來看看 @neild 這次提出的方案到底是什么。
這個提案的思路其實挺保守的,和之前被接受的 QUIC 提案 #58547[3] 基本一致:
- 先在 x/net/internal/http3 中實驗性開發
- 等 API 穩定后,再移到 x/net/http3 供外部測試
- 最后提交正式的 API 審查提案
這個策略看起來很穩妥對吧?先內部折騰,等成熟了再放出來。照理說應該問題不大。
但是很無奈的是,就是這么個穩妥的方案,也被擱置了!也是絕了。
社區討論:無奈與不解
在 Issue #32204 的討論中,我們能看到社區對這個問題的長期關注。
主要包含以下幾種態度/想法:
1、時間線: 2020 年,Brad Fitzpatrick 就在評論中提到過,Go 團隊在觀望 HTTP/3 的成熟度。現在 5 年過去了,HTTP/3 早就從草案變成了正式標準,主流語言和框架也都有了成熟實現。
2、生態問題: 目前想在 Go 中使用 HTTP/3,只能依賴第三方庫 quic-go[4]。這個庫做得確實不錯,實現了完整的 QUIC 和 HTTP/3 支持:
package main
import (
"github.com/quic-go/quic-go/http3"
"log"
"net/http"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello, HTTP/3!"))
})
// 啟動 HTTP/3 服務器
log.Fatal(http3.ListenAndServeQUIC(
"0.0.0.0:8443",
"/path/to/cert.pem",
"/path/to/key.pem",
mux,
))
}但問題在于:
- 第三方庫的維護周期和 Go 官方不一致
- 沒有標準庫的背書,企業級項目用起來總是有顧慮
- API 設計上無法和 net/http 無縫集成
3、多語言對比:隔壁 Rust、C++、Java、C# 等語言,人家早就把 HTTP/3 支持做進標準庫或官方庫了。Go 作為云原生時代的代表語言,在網絡協議支持上反而顯得保守,這確實讓人有點心里不平衡。
為什么又又被擱置?
那問題來了,為什么一個看起來如此合理的提案,會被擱置呢?
根據 Go 團隊的處理風格,我推測可能有這么幾個原因:
1. API 設計的復雜性
HTTP/3 基于 QUIC 協議,和傳統的 TCP 有本質區別。要讓它和現有的 net/http 優雅地集成,不是簡單加幾個接口就能搞定的。
舉個例子,HTTP/3 的連接是基于 UDP 的,這意味著:
- TLS 握手方式不同(使用 QUIC 的 TLS 1.3)
- 連接遷移特性需要特殊處理
- 流控機制完全不同
這些都需要在 API 設計上仔細考慮。
2. 向后兼容的壓力
Go 一直以向后兼容聞名,這是好事,但也帶來了設計上的約束。HTTP/3 的 API 怎么設計,既要考慮現有 net/http 用戶的習慣,又要支持 HTTP/3 的新特性,這是個難題。
看看在 Go1.24 加入的 HTTP 版本選擇 API te'xing #67814[5] 就知道了:
type Protocol uint64
const (
HTTP1 Protocol = (1 << iota)
HTTP2
// HTTP3 還沒有...
)
// Server 可以選擇支持的協議
s := &http.Server{}
s.Protocols = HTTP1 | HTTP2
// Transport 也可以選擇
tr := &http.Transport{}
tr.Protocols = HTTP1 | HTTP2這個 API 預留了擴展空間,但 HTTP3 的位置還是空著的。為什么?因為官方還沒想好怎么搞!
3. 資源分配問題
Go 核心團隊人手有限,他們現在的重點在:
- 把 x/net/http2 移到標準庫 #67810[6]。預計在 Go1.26 版本支持。
- 支持明文 HTTP/2 #67816[7]。這個特性在 Go1.24 版本支持了。
- 完善 HTTP/2 的一系列雜七雜八的問題。
說白了,HTTP/2 都還沒徹底搞定,甚至都還沒有進入標準庫(尷尬了),可能他們認為哪有精力去搞 HTTP/3?
4. 實用主義的考量
有個不得不承認的事實:雖然 HTTP/3 很先進,但在實際生產環境中,HTTP/2 已經夠用了。大多數場景下,HTTP/3 帶來的性能提升并不是質的飛躍。
所以從實用主義角度看,Go 團隊可能覺得 HTTP/3 不是當務之急。資源就沒有分配在這里。
總結
Go HTTP/3 的推進,可以說是 "起了個大早,趕了個晚集"。2019 年就有人提議,2025 年提案又被擱置,這個過程確實有點魔幻。
但換個角度想,這也是 Go 一貫的風格:穩字當頭,又或是 ”less is more“。至于什么時候能在標準庫中用上 HTTP/3,就看 Go 核心團隊的魄力和資源分配了。
在那之前,可以先繼續使用 quic-go。
參考資料
[1] #70914: https://github.com/golang/go/issues/70914
[2] Issue #32204: https://github.com/golang/go/issues/32204
[3] #58547: https://github.com/golang/go/issues/58547
[4] quic-go: https://github.com/quic-go/quic-go
[5] #67814: https://github.com/golang/go/issues/67814
[6] #67810: https://github.com/golang/go/issues/67810
[7] #67816: https://github.com/golang/go/issues/67816































