今天,字節跳動正式宣布開源 CloudWeGo。這是一套以 Go 語言為核心、專注于微服務通信與治理的中間件集合,具有高性能、可擴展、高可靠的特點。
項目地址:https://github.com/cloudwego
作為項目維護方,字節跳動基礎架構團隊已推進項目以 CloudWeGo 開源庫為主進行迭代,未來,團隊將堅持內外維護一套代碼,統一迭代演進,并逐步分享更多內部微服務最佳實踐。
CloudWeGo 概述
多年來,在億級流量背后,字節跳動基礎架構團隊開發的技術底座支撐著龐大的微服務生態系統,從 2018 年至今,團隊維護的在線微服務數量增長了近 600%,超過 5 萬。面對這樣的規模和增速,提高性能、可擴展性和穩定性成了構建 CloudWeGo 的核心。
CloudWeGo 第一批開源了四個項目,以 RPC 框架 Kitex 和網絡庫 Netpoll 為主,關于它們的技術實踐,可以參考此前發布的兩篇文章:《字節跳動 Go RPC 框架 KiteX 性能優化實踐》《字節跳動在 Go 網絡庫上的實踐》。
Kitex
Kitex 是一個 Golang 微服務 RPC 框架,具有高性能、強可擴展的特點。
字節跳動使用 Golang 作為主要業務開發語言。早在 2016 年,基礎架構團隊就已經開始基于 Golang 開發內部框架 Kite,并在 2019 年圍繞性能和可擴展啟動重構,使其能更好地滿足業務發展和技術體系演進需求。
2020 年 10 月,Kitex 正式上線。雖然是一個全新的框架,但經過一年的線上應用,目前字節跳動內部已有超過 50% 的 Golang 微服務遷移到了 Kitex。
下面是 Kitex 的一些特性:
- 高性能:Kitex 默認集成自研網絡庫 Netpoll 作為網絡傳輸模塊,性能相較使用 go net 有顯著優勢;除了網絡庫帶來的性能收益,Kitex 對 Thrift 編解碼也做了優化,這在之前的性能優化實踐文章中有介紹。關于性能數據,可參考 https://github.com/cloudwego/kitex-benchmark。
- 擴展性:Kitex 設計上做了模塊劃分,提供了較多的擴展接口以及默認的擴展實現,使用者也可以根據需要自行定制擴展。Kitex 未耦合 Netpoll,開發者可選擇其他網絡庫擴展使用。
- 消息協議:RPC 消息協議默認支持 Thrift、Kitex Protobuf、gRPC。Thrift 支持 Buffered 和 Framed 二進制協議;Kitex Protobuf 是 Kitex 自定義的 Protobuf 消息協議,協議格式類似 Thrift;gRPC 是對 gRPC 消息協議的支持,可以與 gRPC 互通。除此之外,使用者也可以擴展自己的消息協議。
- 傳輸協議:傳輸協議封裝消息協議進行 RPC 互通,傳輸協議可以額外透傳元信息,用于服務治理,Kitex 支持的傳輸協議有 TTHeader、HTTP2。TTHeader 可以和 Thrift、Kitex Protobuf 結合使用;HTTP2 目前主要是結合 gRPC 協議使用,后續也會支持 Thrift。
- 多消息類型:支持 PingPong、Oneway、雙向 Streaming。其中 Oneway 目前只對 Thrift 協議支持,雙向 Streaming 只對 gRPC 支持,后續會考慮支持 Thrift 的雙向 Streaming。
- 服務治理:支持服務注冊/發現、負載均衡、熔斷、限流、重試、監控、鏈路跟蹤、日志、診斷等服務治理模塊,大部分均已提供默認擴展,使用者可選擇集成。
- 代碼生成工具:Kitex 內置代碼生成工具,可支持生成 Thrift、Protobuf 以及腳手架代碼。
Netpoll
Netpoll 是字節跳動內部的 Golang 高性能、I/O 非阻塞的網絡庫,專注于 RPC 場景。
RPC 通常有較重的處理邏輯(業務邏輯、編解碼),耗時長,不能像 redis 一樣采用串行處理(必須異步)。而 Go 的標準庫 net 設計了 BIO(Blocking I/O) 模式的 API,為了保證異步處理,RPC 框架設計上需要為每個連接都分配一個 goroutine,這在空閑連接較多時,產生大量的空閑 goroutine,增加調度開銷。此外,net.Conn 沒有提供檢查連接活性的 API,很難設計出高效的連接池,池中的失效連接無法及時清理,復用低效。開源社區目前缺少專注于 RPC 方案的 Go 網絡庫。類似的項目如:evio、gnet 等,均面向 Redis、Haproxy 這樣的場景。
因此 Netpoll 應運而生,它借鑒了 evio 和 Netty 的優秀設計,具有出色的性能,更適用于微服務架構。
Thriftgo
Thriftgo 是 Go 語言實現的 Thrift IDL 解析和代碼生成器,支持完善的 Thrift IDL 語法和語義檢查,相較 Apache Thrift 官方的 Golang 生成代碼,Thriftgo 做了一些問題修復且支持插件機制,用戶可根據需求自定義生成代碼。
Kitex 的代碼生成工具就是 Thriftgo 的插件,CloudWeGo 近期也會開源另一個 Thriftgo 的插件 thrift-gen-validator,支持 IDL Validator,用于字段值校驗,解決開發者需要自行實現代碼校驗邏輯的負擔,彌補 Thrift 缺失的能力。
Thriftgo 目前雖然僅支持生成 Golang Thrift 代碼,但其定位是可支持各語言的 Thrift 代碼生成,未來如果有需求,我們會考慮生成其他語言的代碼。同時我們也會嘗試將其回饋至 Apache Thrift 社區。
Netpoll-http2
Netpoll-http2 基于 Golang 標準庫 golang.org/x/net/http2 的源碼替換 go net 為 Netpoll,目前用于 Kitex 對 gRPC 協議的支持,對 HTTP2 有需求的外部開發者也可以使用此庫。
內外版本維護
完整的微服務體系離不開底層云計算生態,無論是公有云、私有云還是本地基礎設施等環境,開發者要搭建微服務,離不開配套的微服務治理,如治理平臺、監控、鏈路跟蹤、注冊/發現、配置中心、服務網格等,此外還存在一些定制的規范。
字節跳動自然也有完善的內部服務支持微服務體系,但這些服務短期內無法開源。為了遵守長期投入承諾,內外維護一套代碼、統一迭代,基礎架構團隊已經將與內部生態沒有耦合的項目,如 Netpoll,直接遷移到 CloudWeGo 開源庫,并將內部依賴調整為開源庫。
而對于需要集成治理能力融入微服務體系的 Kitex,我們基于其擴展性,對內外部代碼做了拆分,把 Kitex 的核心代碼遷移到開源庫,內部庫封裝一層殼保證內部用戶無感知升級,而集成內部治理特性的模塊則作為 Kitex 的擴展保留在內部庫。未來,我們也會持續把已經在字節跳動內部經過穩定性驗證的新特性,遷移到開源庫。
對于使用 CloudWeGo 的開發者,大家同樣可以對 Kitex 進行擴展,將 Kitex 融入自己所在組織的微服務體系中。我們也誠摯歡迎開發者能貢獻自己的擴展到 https://github.com/kitex-contrib,為更多用戶提供便利。
RoadMap
對于基礎架構團隊,CloudWeGo 不僅僅是一個開源項目,它也是一個真實的超大規模企業級實踐項目。通過開源,我們希望 CloudWeGo 能豐富云原生社區的 Golang 工具體系,為更多開發者和企業搭建云原生化的大規模分布式系統,提供一種現代的、資源高效的的技術方案。
如前文所述,目前 CloudWeGo 只開源了第一批項目,未來,我們會進一步推動其走向完善:
- 繼續開源其他內部項目。我們會開源更多字節跳動常用 Golang 項目,如 HTTP 框架 Hertz、基于共享內存的 IPC 通信庫 ShmIPC 等,為開發者提供更多場景的微服務需求支持。此前,我們已將部分 Golang 基礎工具庫開源,統一在 bytedance/gopkg 維護,感興趣的開發者也可以關注。
- 逐步開源經驗證的、穩定的特性。CloudWeGo 的主要項目均為字節內部微服務提供支持,許多新特性仍在內部驗證,相對成熟后我們會逐步開源,如對 ShmIPC 的集成、無序列化、無生成代碼的支持等。
- 結合內外部用戶需求,持續迭代。項目開源后,我們也會根據開發者需求開展迭代。例如近一個月來,我們收到了來自開發者的大量關于 Protobuf 的訴求,為了提供良好的支持,我們已經在籌備開展 Kitex 對 Protobuf 支持的性能優化。
歡迎大家向 CloudWeGo 提交 issue 和 PR 共建 CloudWeGo。我們誠心期待更多的開發者加入,也期待 CloudWeGo 助力越來越多的企業快速構建云原生架構。如果企業客戶想內部試用,我們可以排期提供專項技術支持和交流,歡迎入群咨詢。
相關鏈接
- 項目地址:
- https://github.com/cloudwego
- 項目官網:www.cloudwego.io