Go語言寫的tsnet庫運行了四年,Tailscale團隊突然用Rust重寫核心。這不是技術炫技,而是一個被用戶逼出來的決定——當Python和Elixir開發者想把Tailscale塞進自己的程序時,他們發現唯一的橋梁是"在進程里塞一個Go運行時"。
為什么Go的解法走到頭了
![]()
Tailscale的核心產品邏輯很干凈:讓程序像連局域網一樣安全通信,但不需要真的坐在同一個機房。實現方式是給操作系統掛一個虛擬網卡,讓上層應用無感知。
這個設計在桌面和服務器上跑得通。但團隊自己踩坑時發現,OS層動手腳在很多場景是死路:精簡內核的嵌入式設備、禁止修改網絡棧的容器環境、或者只是不想折騰系統權限的SaaS多租戶架構。
tsnet應運而生——"把Tailscale編譯進你的程序",不碰操作系統,純用戶態運行。Go開發者用得很爽:setec密鑰管理、tsidp身份代理、tclip粘貼板、golink短鏈,全是內部工具。
社區也跟上來了。tnsrv反向代理、chat-tails消息服務,生態慢慢長出來。
但非Go開發者被擋在門外。Tailscale試過補救:libtailscale,一個C庫包裝。實現方式很粗暴——首次調用時在你的進程里啟動完整Go運行時,再用C膠水粘一層接口。
兩個運行時搶進程生命周期,結果可想而知。Python的GIL和Go的調度器打架,Elixir的BEAM虛擬機被Go運行時強行插入,穩定性災難。
「第一次調用就 spinning up an entire Go runtime inside your process」,原文這句描述本身就是問題診斷。不是API設計差,是架構層面的不可能三角:既要tsnet的功能,又要跨語言,還要進程內和平共處。
Rust的解法:把運行時削薄到零
tailscale-rs的立項邏輯很直接:如果Go的運行時是障礙,那就換一個沒有運行時負擔的語言。Rust的零成本抽象和無垃圾回收特性,讓它成為系統級庫的新默認選擇。
具體實現上,tailscale-rs是一個原生Rust庫,同時輸出C兼容接口。Python、Elixir、C的綁定都基于這層C接口,但底層不再有Go運行時攪局。
關鍵差異在于進程內的資源所有權。Rust的所有權模型編譯期就解決了內存安全,不需要運行時垃圾回收。這意味著嵌入tailscale-rs的程序,網絡棧完全受控于宿主語言的生命周期管理。
Python的asyncio事件循環、Elixir的OTP監督樹、C的手動內存管理——各自保持原有的運行假設,不被外來運行時入侵。
目前代碼以實驗性預覽形式發布,GitHub倉庫明確標注「do not use it in production yet」。但方向已經清晰:tsnet的功能集,以庫的形態向全語言開放。
正方:這是基礎設施庫的正確形態
支持者認為,網絡基礎設施的終極形態就是語言無關的庫。Tailscale的WireGuard實現、NAT穿透、密鑰管理,這些能力應該像zlib或OpenSSL一樣,任何語言都能鏈接。
Rust在這個位置有先例優勢。Mozilla用Rust重寫Firefox的CSS引擎,AWS用Rust寫Lambda的MicroVM(Firecracker),Cloudflare的代理棧也在Rust化。系統級庫選Rust,已經成為2020年代的基礎設施共識。
對Tailscale自身而言,這步棋也有商業計算。tsnet生態原本局限在Go社區,現在可以觸達Python的數據科學棧、Elixir的實時通信場景、C/C++的嵌入式和游戲開發。每個語言社區都是一個潛在的產品擴展面。
技術債角度,維護一套Rust核心比維護「Go運行時+C膠水+多語言綁定」的三層架構更可持續。libtailscale的兼容性問題本質是架構缺陷,不是修bug能解決的。
反方:生態分裂與機會成本
質疑聲音同樣具體。首先,tsnet在Go生態已經運行四年,內部工具和社區項目深度依賴。tailscale-rs從預覽到生產就緒需要時間,期間兩套實現并行維護,團隊資源被稀釋。
更深層的問題是功能對齊。tsnet的API設計經過大量實戰打磨,tailscale-rs能否完全復刻語義?Go的goroutine和channel模型與Rust的async/await差異顯著,某些tsnet的慣用模式在Rust里可能需要重新設計。
綁定層的質量也是未知數。Python的PyO3、Elixir的Rustler都是成熟的FFI工具,但每個綁定都需要持續維護。C接口的ABI穩定性、跨平臺編譯、調試體驗——這些細節會消耗大量工程時間。
一個尖銳的對比:如果目標是跨語言,為什么不直接完善libtailscale的Go運行時隔離?比如用獨立進程+IPC通信,而非進程內嵌。這條路徑沒有被完全探索就被放棄,是否存在技術決策的過早優化?
我的判斷:運行時戰爭的基礎設施終局
這場爭論的本質是「運行時邊界」在基礎設施庫中的位置。Go的成功很大程度上依賴其運行時——調度器、垃圾回收、網絡輪詢——但這也成為跨語言嵌入的障礙。
Tailscale的選擇揭示了一個趨勢:下一代系統級庫正在從「帶運行時的SDK」轉向「零運行時的引擎」。Rust不是唯一選項,但它是2026年這個時間點上,平衡性能、安全和多語言綁定的最優解。
對開發者的實際影響:如果你在用Python寫IoT網關,用Elixir建實時協作工具,或者用C++開發游戲服務器,現在可以把Tailscale的組網能力編譯進二進制,而不必在部署時折騰系統網卡或容器特權。
這改變了什么?邊緣計算場景的部署模型。以前「Tailscale客戶端+你的應用」是兩套東西,現在可以是一個靜態鏈接的可執行文件。在受限環境——比如客戶的VPC、工廠的內網、飛機的娛樂系統——這種差異決定了方案是否可行。
Tailscale團隊把預覽版放出來,明確要社區反饋。這不是產品發布,是技術路線的公開驗證。Go的tsnet不會消失,但Rust版本的演進速度將決定Tailscale能否突破語言天花板,成為真正的基礎設施默認選項。
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.