TarsGo新版本釋出,支援protobuf,zipkin和自定義外掛
#TarsGo 新版本釋出,支援 protobuf,zipkin 和自定義外掛
Tars 是騰訊從 2008 年到今天一直在使用的後臺邏輯層的統一應用框架,目前支援 C++,Java,PHP,Nodejs,Golang 語言。該框架為使用者提供了涉及到開發、運維、以及測試的一整套解決方案,幫助一個產品或者服務快速開發、部署、測試、上線。 它集可擴充套件協議編解碼、高效能 RPC 通訊框架、名字路由與發現、釋出監控、日誌統計、配置管理等於一體,通過它可以快速用微服務的方式構建自己的穩定可靠的分散式應用,並實現完整有效的服務治理。目前該框架在騰訊內部,各大核心業務都在使用,頗受歡迎,基於該框架部署執行的服務節點規模達到上萬個。 Tars 於 2017 年 4 月開源,並於 2018 年 6 月加入 Linux 基金會。 TarsGo 是 Tars 的 Go 語言實現版本, 於 2018 年 9 月開源, 專案地址 https://github.com/TarsCloud/TarsGo ,歡迎 star 。
##TarsGo 新版本釋出 在上次開源之後,有些使用者反饋了一些需求,基於使用者反饋的需求,我們進行了實現,併發布了 1.1.0 版本。 本次釋出新增了:支援 pb、支援 zipkin 分散式追蹤、支援 filter(自定義外掛編寫)、支援 context 等,除此之外還做了一系列優化和 bugfix。
新功能:PB 支援
Protocol Buffers (簡稱 PB ) 是 Google 的一種資料交換的格式,它獨立於語言,獨立於平臺,最早公佈於 2008 年 7 月。隨著微服務架構的發展及自身的優異表現,ProtoBuf 可用於諸如網路傳輸、配置檔案、資料儲存等諸多領域,目前在網際網路上有著大量應用。 如果對於現有已使用 grpc,使用 proto 檔案,想轉換成 tars 協議的使用者而言,需要將上面的 proto 檔案翻譯成 Tars 檔案。這種翻譯會比較繁瑣,而且容易出錯。 為此我們決定編寫外掛支援 proto 檔案直接生成 tars 的 rpc 邏輯。protoc-gen-go 的程式碼邏輯裡面是預留了外掛編寫的規範的,參照 grpc,主要有 grpc/grpc.go 和一個匯入外掛的 link_grpc.go 。 這裡我們編寫 tarsrpc/tarsrpc.go 和 link_tarsrpc.go 使用方面:
將這兩個檔案放到 protoc-gen-go 下面,go install 重新生成 protoc-gen-go 二進位制
定義 proto 檔案
使用重新編譯安裝的 protoc-gen-go 生成序列化和 rpc 相關介面程式碼
protoc --go_out=plugins=tarsrpc:. helloworld.proto
編寫 tars 客戶端和服務端程式碼,引數使用 pb 生成的結構體,其餘程式碼邏輯和正常的 tars 服務一致。
詳細原理和使用文件,閱讀 騰訊雲社群文章
新功能: filter 機制, 支援 zipkin 分散式追蹤
為了支援使用者編寫外掛,我們支援了 filter 機制,分為服務端的過濾器和客戶端過濾器,使用者可以基於這個機制,實現自己的 TarsGo 外掛。
//服務端過濾器, 傳入dispatch,和f, 用於呼叫使用者程式碼, req, 和resp為傳入的使用者請求和服務端相應包體
type ServerFilter func(ctx context.Context, d Dispatch, f interface{}, req *requestf.RequestPacket, resp *requestf.ResponsePacket, withContext bool) (err error)
//客戶端過濾器, 傳入msg(包含obj資訊,adapter資訊,req和resp包體), 還有使用者設定的呼叫超時
type ClientFilter func(ctx context.Context, msg *Message, invoke Invoke, timeout time.Duration) (err error)
//註冊服務端過濾器
//func RegisterServerFilter(f ServerFilter)
//註冊客戶端過濾器
//func RegisterClientFilter(f ClientFilter)
有了過濾器,我們就能對服務端和客戶端的請求做一些過濾,比如使用 hook 用於分散式追蹤的 opentracing 的 span。 我們來看下客戶端 filter 的例子:
//生成客戶端tars filter,通過註冊這個filter來實現span的注入
func ZipkinClientFilter() tars.ClientFilter {
return func(ctx context.Context, msg *tars.Message, invoke tars.Invoke, timeout time.Duration) (err error) {
var pCtx opentracing.SpanContext
req := msg.Req
//先從客戶端呼叫的context 裡面看下有沒有傳遞來呼叫鏈的資訊,
//如果有,則以這個做為父span,如果沒有,則起一個新的span,span名字是RPC請求的函式名
if parent := opentracing.SpanFromContext(ctx); parent != nil {
pCtx = parent.Context()
}
cSpan := opentracing.GlobalTracer().StartSpan(
req.SFuncName,
opentracing.ChildOf(pCtx),
ext.SpanKindRPCClient,
)
defer cSpan.Finish()
cfg := tars.GetServerConfig()
//設定span的資訊,比如我們呼叫的客戶端的ip地址,請求的介面,方法,協議,客戶端版本等資訊
cSpan.SetTag("client.ipv4", cfg.LocalIP)
cSpan.SetTag("tars.interface", req.SServantName)
cSpan.SetTag("tars.method", req.SFuncName)
cSpan.SetTag("tars.protocol", "tars")
cSpan.SetTag("tars.client.version", tars.TarsVersion)
//將span注入到 請求包體的 Status裡面,status 是一個map[strint]string 的結構體
if req.Status != nil {
err = opentracing.GlobalTracer().Inject(cSpan.Context(), opentracing.TextMap, opentracing.TextMapCarrier(req.Status))
if err != nil {
logger.Error("inject span to status error:", err)
}
} else {
s := make(map[string]string)
err = opentracing.GlobalTracer().Inject(cSpan.Context(), opentracing.TextMap, opentracing.TextMapCarrier(s))
if err != nil {
logger.Error("inject span to status error:", err)
} else {
req.Status = s
}
}
//沒什麼其他需要修改的,就進行客戶端呼叫
err = invoke(ctx, msg, timeout)
if err != nil {
//呼叫錯誤,則記錄span的錯誤資訊
ext.Error.Set(cSpan, true)
cSpan.LogFields(oplog.String("event", "error"), oplog.String("message", err.Error()))
}
return err
}
服務端也會註冊一個 filter,主要功能就是從 request 包體的 status 提取呼叫鏈的上下文,以這個作為父 span,進行呼叫資訊的記錄。 整體的一個效果:
詳細程式碼參見 TarsGo/tars/plugin/zipkintracing 完整的 zipkin tracing 的客戶端和服務端例子,詳見 TarsGo/examples 下面的 ZipkinTraceClient 和 ZipkinTraceServer
新功能: 支援 context
TarsGo 之前在生成的客戶端程式碼,或者使用者傳入的實現程式碼裡面,都沒有使用 context。 這使得我們想傳遞一些框架的資訊,比如客戶端 ip,埠等,或者使用者傳遞一些呼叫鏈的資訊給框架,都很難於實現。 通過介面的一次重構,支援了 context,這些上下文的資訊,將都通過 context 來實現。 這次重構為了相容老的使用者行為,採用了完全相容的設計。
服務端使用 context
type ContextTestImp struct {
}
//只需在介面上新增 ctx context.Context引數
func (imp *ContextTestImp) Add(ctx context.Context, a int32, b int32, c *int32) (int32, error) {
//我們可以通過context 獲取框架傳遞的資訊,比如下面的獲取ip, 甚至返回一些資訊給框架,詳見tars/util/current下面的介面
ip, ok := current.GetClientIPFromContext(ctx)
if !ok {
logger.Error("Error getting ip from context")
}
return 0, nil
}
//以前使用AddServant ,現在只需改成AddServantWithContext
app.AddServantWithContext(imp, cfg.App+"."+cfg.Server+".ContextTestObj")
客戶端使用 context
ctx := context.Background()
c := make(map[string]string)
c["a"] = "b"
//以前使用app.Add 進行客戶端呼叫,這裡只要變成app.AddWithContext ,就可以傳遞context給框架,如果要設定給tars請求的context
//可以多傳入引數,比如c,引數c是可選的,格式是 ...[string]string
ret, err := app.AddWithContext(ctx, i, i*2, &out, c)
服務端和客戶端的完整例子,詳見 TarGo/examples
其他優化和修復
- 將 request package 的 Sbuffer 欄位由 vector<unsigned byte> 改成 vector<byte>,解決和其他語言通訊問題
- 修復 stat 監控上報問題
- 日誌級別從遠端更新
- 修復路由重新整理協程極端情況下死鎖問題
- 優化協程池方案,並新增協程池方案
- 修復 go 協程啟動順序導致 panic 問題
- golint 大部分程式碼
- 加微信實戰群請加微信(註明:實戰群):gocnio
相關文章
- APISIX Ingress 如何支援自定義外掛API
- gradle自定義任務和外掛Gradle
- gradle自定義外掛Gradle
- mybatis 自定義外掛MyBatis
- 新版本釋出,新增監控外掛與驅動
- laravel Modules外掛內定時任務執行,自定義命令註冊,外掛內資源釋出Laravel
- vue自定義全域性元件(或自定義外掛)Vue元件
- es 自定義分詞外掛分詞
- apisix~自定義外掛的部署API
- 自定義Gradle-Plugin 外掛GradlePlugin
- Qt自定義外掛plugin的開發和呼叫QTPlugin
- IDE 外掛新版本釋出,開發效率 “biu” 起來了IDE
- protobuf 生成 Go 程式碼外掛 gogo/protobufGo
- Audacity 3.2 釋出,增加了 VST3 外掛和 Apple 晶片支援APP晶片
- JMeter 擴充套件外掛實現對自定義協議的支援JMeter套件協議
- 【django學習-24】自定義外掛Django
- Kube-Scheduler外掛的自定義
- Cordova學習--iOS自定義外掛iOS
- TarsGo支援Protocol BufferGoProtocol
- TarsGo 支援 protocol bufferGoProtocol
- apisix~自定義檔案上傳代理外掛~支援form-data檔案和kv引數APIORM
- apisix-dashboard上新增自定義外掛API
- 二 阿里大模型接入:自定義外掛阿里大模型
- mybaits原始碼分析--自定義外掛(七)AI原始碼
- 快速自定義Cordova外掛(-配置檔案)
- ChatGPT for SegmentFault 外掛釋出!ChatGPT
- [-Flutter外掛篇 1-] 從自定義外掛開始說起Flutter
- 如何編寫 ProtoBuf 外掛 (一) ?
- 如何編寫 ProtoBuf 外掛 (二) ?
- 如何編寫 ProtoBuf 外掛 (三) ?
- [外掛擴充套件]onethink自定義欄位外掛 百度地圖定位 外掛套件地圖
- Springboot+Mybatis+Mybatisplus 框架中增加自定義分頁外掛和sql 佔位符修改外掛Spring BootMyBatis框架SQL
- svelte元件:Svelte3自定義Navbar+Tabbr元件|svelte自定義外掛元件
- Apache Maven Assembly自定義打包外掛的使用ApacheMaven
- Higress 基於自定義外掛訪問 RedisRedis
- Java整合系列:高效構建自定義外掛Java
- JMeter自定義取樣器外掛開發JMeter
- iOS持續整合(三)——fastlane 自定義外掛iOSAST