TarsGo支援Protocol Buffer
Tars是騰訊從2008年到今天一直在使用的後臺邏輯層的統一應用框架TAF(Total Application Framework),目前支援C++,Java,PHP,Nodejs,Golang語言。該框架為使用者提供了涉及到開發、運維、以及測試的一整套解決方案,幫助一個產品或者服務快速開發、部署、測試、上線。 它集可擴充套件協議編解碼、高效能RPC通訊框架、名字路由與發現、釋出監控、日誌統計、配置管理等於一體,透過它可以快速用微服務的方式構建自己的穩定可靠的分散式應用,並實現完整有效的服務治理。目前該框架在騰訊內部,各大核心業務都在使用,頗受歡迎,基於該框架部署執行的服務節點規模達到上萬個。
Tars 於2017年4月開源,並於2018年6月加入Linux 基金會,專案地址 。
TarsGo 是Tars 的Go語言實現版本, 於2018年9月開源, 專案地址
Tars協議是一種類c++識別符號的語言,用於生成具體的服務介面檔案,Tars檔案是Tars框架中客戶端和服務端的通訊介面,透過Tars的對映實現遠端物件呼叫。 Tars 協議是和語言無關,基於IDL介面描述語言的二進位制編碼協議。
詳見
Protocol Buffers (簡稱 PB )是 Google 的一種資料交換的格式,它獨立於語言,獨立於平臺,最早公佈於 2008年7月。隨著微服務架構的發展及自身的優異表現,ProtoBuf 可用於諸如網路傳輸、配置檔案、資料儲存等諸多領域,目前在網際網路上有著大量應用。
PB協議是單獨的協議,如果要支援RPC,可以定義service欄位,並且基於protoc-gen-go 的grpc 外掛生成相應的grpc編碼。
以下面的 proto 檔案為例
syntax = "proto3"; package helloworld;// The greeting service definition.service Greeter { // Sends a greeting rpc SayHello (HelloRequest) returns (HelloReply) {} }// The request message containing the user's name.message HelloRequest { string name = 1; }// The response message containing the greetingsmessage HelloReply { string message = 1; }
使用protoc生成相應的介面程式碼,以Go語言為例:
protoc --go_out=plugins=grpc:. helloworld.proto
如果對於現有已使用grpc,使用proto,想轉換成tars協議的使用者而言,需要將上面的proto檔案翻譯成Tars檔案。對於Tars而言,Tars是編寫tars檔案,然後用相應的工具tars2xxx, 比如tars2go生成相應的介面程式碼。上面的proto檔案翻譯成tars檔案是:
module helloworld{ struct HelloRequest { 1 require string name ; }; struct HelloReply { 1 require string message ; }; interface Greeter { int SayHello(HelloRequest req, out HelloReply resp); }; }
然後呼叫tars2go生成 相應的tarsgo介面:
tars2go --outdir ./ helloworld.tars
這種翻譯會比較繁瑣,而且容易出錯。 為此我們決定編寫外掛支援proto直接生成tars的rpc邏輯。
有兩種方案,一種是寫protoc外掛,直接讀取protoc解析proto檔案的二進位制流,對service相應的欄位進行解析,以便生成相應的rpc邏輯,其他交由protoc-gen-go處理
另外一種是直接編寫protoc-gen-go的外掛,類似gRPC外掛,
這裡決定採用方案2 。
protoc-gen-go 並沒有外掛編寫的相關說明,但protoc-gen-go的程式碼邏輯裡面是預留了外掛編寫的規範的,參照grpc,主要有 grpc/grpc.go 和一個導致外掛包的link_grpc.go 。 這裡我們編寫 tarsrpc/tarsrpc.go 和 link_tarsrpc.go
程式碼邏輯基本上就是繼承 generator.Generator,註冊外掛, 獲取相應的service,method,和method的input和output,再呼叫P方法將要生成的程式碼輸出即可
func init() { generator.RegisterPlugin(new(tarsrpc)) }// tarsrpc is an implementation of the Go protocol buffer compiler's// plugin architecture. It generates bindings for tars rpc support.type tarsrpc struct { gen *generator.Generator } func (t *tarsrpc) generateService(file *generator.FileDescriptor, service *pb.ServiceDescriptorProto, index int) { originServiceName := service.GetName() serviceName := upperFirstLatter(originServiceName) t.P("// This following code was generated by tarsrpc") t.P(fmt.Sprintf("// Gernerated from %s", file.GetName())) t.P(fmt.Sprintf(`type %s struct { s model.Servant } `, serviceName)) t.P() ... ... }
這裡主要是生成 service 轉成相應的interface,然後interface裡面有定義的rpc method, 使用者可以實現自己真正業務邏輯的method,其餘的都是tars相應的發包收包邏輯。Tars的請求包體:
type RequestPacket struct { IVersion int16 `json:"iVersion"` CPacketType int8 `json:"cPacketType"` IMessageType int32 `json:"iMessageType"` IRequestId int32 `json:"iRequestId"` SServantName string `json:"sServantName"` SFuncName string `json:"sFuncName"` SBuffer []uint8 `json:"sBuffer"` ITimeout int32 `json:"iTimeout"` Context map[string]string `json:"context"` Status map[string]string `json:"status"` }
我們只需要將rpc method的名字,放入RequestPacket 的SFuncName ,然後將請求引數呼叫proto的Marshal序列化後放到 SBuffer。
而對於回包,Tars的回包結構體:
type ResponsePacket struct { IVersion int16 `json:"iVersion"` CPacketType int8 `json:"cPacketType"` IRequestId int32 `json:"iRequestId"` IMessageType int32 `json:"iMessageType"` IRet int32 `json:"iRet"` SBuffer []uint8 `json:"sBuffer"` Status map[string]string `json:"status"` SResultDesc string `json:"sResultDesc"` Context map[string]string `json:"context"` }
同樣,我們只需要將返回的結果,呼叫Marshal 將請求放入 SBuffer ,其他邏輯和tars保持一致。
編寫完外掛,就可以透過和grpc生成程式碼相同的方式,將proto 檔案轉化成tars的介面檔案:
protoc --go_out=plugins=tarsrpc:. helloworld.proto
下面是簡單的服務端例子
package mainimport ( "github.com/TarsCloud/TarsGo/tars" "helloworld" //上面工具生成的package)type GreeterImp struct { } func (imp *GreeterImp) SayHello(input helloworld.HelloRequest)(output helloworld.HelloReply, err error) { output.Message = "hello" + input.GetName() return output, nil }func main() { //Init servant imp := new(GreeterImp) //New Imp app := new(helloworld.Greeter) //New init the A JCE cfg := tars.GetServerConfig() //Get Config File Object app.AddServant(imp, cfg.App+"."+cfg.Server+".GreeterTestObj") //Register Servant tars.Run() }
簡單的客戶端呼叫例子
package mainimport ( "fmt" "github.com/TarsCloud/TarsGo/tars" "helloworld")func main() { comm := tars.NewCommunicator() obj := fmt.Sprintf("StressTest.HelloPbServer.GreeterTestObj@tcp -h 127.0.0.1 -p 10014 -t 60000") app := new(helloworld.Greeter) comm.StringToProxy(obj, app) input := helloworld.HelloRequest{Name: "sandyskies"} output, err := app.SayHello(input) if err != nil { fmt.Println("err: ", err) } fmt.Println("result is:", output.Message) }
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31557424/viewspace-2220416/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- TarsGo 支援 protocol bufferGoProtocol
- protocol bufferProtocol
- 解密gRPC: Protocol Buffer解密RPCProtocol
- Protocol Buffer 使用指北Protocol
- Spring Cloud OpenFeign整合Protocol BufferSpringCloudProtocol
- protocol buffer的高效編碼方式Protocol
- Protocol Buffer序列化Java框架-ProtostuffProtocolJava框架
- Protocol buffer---Protobuf3開發指南Protocol
- gRPC in ASP.NET Core 3.0 -- Protocol Buffer(1)RPCASP.NETProtocol
- google protocol buffer——protobuf的編碼原理二GoProtocol
- google protocol buffer——protobuf的基本使用和模型分析GoProtocol模型
- TensorFlow中結構化資料工具Protocol BufferProtocol
- google protocol buffer——protobuf的使用特性及編碼原理GoProtocol
- google protocol buffer——protobuf的問題及改進一GoProtocol
- google protocol buffer——protobuf的問題和改進2GoProtocol
- Google Protocol buffer 學習筆記.下篇-動態編譯GoProtocol筆記編譯
- 前端後臺以及遊戲中使用Google Protocol Buffer詳解前端遊戲GoProtocol
- TarsGo新版本釋出,支援protobuf,zipkin和自定義外掛Go
- Netty使用Google Protocol Buffer完成伺服器高效能資料傳輸NettyGoProtocol伺服器
- 谷歌將在 Kotlin 中支援 Protocol Buffers 資料格式谷歌KotlinProtocol
- Android序列化:Google出品的序列化神器Protocol Buffer不瞭解一下?AndroidGoProtocol
- 11 種序列化庫對比 DSL、fastjson、gson、jackson、protocol buffer、Thrift、Hession、Kryo、Fst、Messagepack、Jboss MarshalingASTJSONProtocol
- No appropriate protocolAPPProtocol
- 讓SAE支援支付寶“確認發貨”介面,完美解決"protocol error"ProtocolError
- Protocol Buffers 系列 (1) - 什麼是Protocol Buffers?Protocol
- 聊聊SWIM ProtocolSWIMProtocol
- location.protocolProtocol
- Jaeger TChannel ——protocolProtocol
- IO之核心buffer----"buffer cache"
- Dubbo on x-protocol——SOFAMesh中的x-protocol示例演示Protocol
- 【node】Buffer
- CPSC 471 HTTP protocolHTTPProtocol
- URL protocol 屬性Protocol
- Buffer Cache以及buffer busy waits/gc相關事件AIGC事件
- 【BUFFER】Oracle buffer cache之 latch 學習記錄Oracle
- Buffer和Channel
- bytes.Buffer
- Java NIO - BufferJava