無縫連線 dubbo-go 與 gRPC
最近我們dubbogo
社群裡面,呼聲很大的一個feature
就是對grpc
的支援。在某位大佬的不懈努力之下,終於弄出來了。
今天我就給大家分析一下大佬是怎麼連線dubbogo
和grpc
。
grpc
先來簡單介紹一下grpc
。它是google
推出來的一個RPC
框架。grpc
是通過IDL(Interface Definition Language)
——介面定義語言——編譯成不同語言的客戶端來實現的。可以說是RPC
理論的一個非常非常標準的實現。
因而grpc
天然就支援多語言。這幾年,它幾乎成為了跨語言RPC
框架的標準實現方式了,很多優秀的rpc
框架,如Spring Cloud
和dubbo
,都支援grpc
。
server 端
在go
裡面,server
端的用法是:
它的關鍵部分是:s := grpc.NewServer()
和pb.RegisterGreeterServer(s, &server{})
兩個步驟。第一個步驟很容易,唯獨第二個步驟RegisterGreeterServer
有點麻煩。為什麼呢?
因為pb.RegisterGreeterServer(s, &server{})
這個方法是通過使用者定義的protobuf
編譯出來的。
好在,這個編譯出來的方法,本質上是:
也就是說,如果我們在dubbogo
裡面拿到這個_Greeter_serviceDesc
,就可以實現這個server
的註冊。因此,可以看到,在dubbogo
裡面,要解決的一個關鍵問題就是如何拿到這個serviceDesc
。
client 端
client
端的用法是:
這個東西要複雜一點:
- 建立連線:
conn, err := grpc.Dial(address, grpc.WithInsecure(), grpc.WithBlock())
- 建立
client
:c := pb.NewGreeterClient(conn)
- 呼叫方法:
r, err := c.SayHello(ctx, &pb.HelloRequest{Name: name})
第一個問題其實挺好解決的,畢竟我們可以從使用者的配置裡面讀出address
;
第二個問題就是最難的地方了。如同RegisterGreeterServer
是被編譯出來的那樣,這個NewGreeterClient
也是被編譯出來的。
而第三個問題,乍一看是用反射就能解決,但是我們開啟SayHello
就能看到:
結合greetClient
的定義,很容易看到,我們的關鍵就在於err := c.cc.Invoke(ctx, "/helloworld.Greeter/SayHello", in, out, opts...)
。換言之,我們只需要建立出來連線,並且拿到方法、引數就能通過類似的呼叫來模擬出c.SayHello
。
通過對grpc
的簡單分析,我們大概知道要怎麼弄了。還剩下一個問題,就是我們的解決方案怎麼和dubbogo
結合起來呢?
設計
我們先來看一下dubbogo
的整體設計,思考一下,如果我們要做grpc
的適配,應該是在哪個層次上做適配。
我們根據前面介紹的grpc
的相關特性可以看出來,grpc
已經解決了codec
和transport
兩層的問題。
而從cluster
往上,顯然grpc
沒有涉及。於是,從這個圖裡面我們就可以看出來,要做這種適配,那麼protocol
這一層是最合適的。即,我們可以如同dubbo protocol
那般,擴充套件出來一個grpc protocol
。
這個grpc protocol
大體上相當於一個介面卡,將底層的grpc
的實現和我們自身的dubbogo
連線在一起。
實現
在dubbogo
裡面,和grpc
相關的主要是:
我們直接進去看看在grpc
小節裡面提到的要點是如何實現的。
server 端
這樣看起來,還是很清晰的。如同dubbogo
其它的protoco
一樣,先拿到service
,而後通過service
來拿到serviceDesc
,完成服務的註冊。
注意一下上圖我紅線標準的ds, ok := service.(DubboGrpcService)
這一句。
為什麼我說這個地方有點奇怪呢?是因為理論上來說,我們這裡註冊的這個service
實際上就是protobuf
編譯之後生成的grpc
服務端的那個service
——很顯然,單純的編譯一個protobuf
介面,它肯定不會實現DubboGrpcService
介面:
那麼ds, ok := service.(DubboGrpcService)
這一句,究竟怎麼才能讓它能夠執行成功呢?
我會在後面給大家揭曉這個謎底。
client 端
dubbogo
設計了自身的Client
,作為對grpc
裡面client
的一種模擬與封裝:
注意看,這個Client
的定義與前面greetClient
的定義及其相似。再看下面的NewClient
方法,裡面也無非就是建立了連線conn
,而後利用conn
裡建立了一個Client
例項。
注意的是,這裡面維護的invoker
實際上是一個stub
。
當真正發起呼叫的時候:
紅色框框框住的就是關鍵步驟。利用反射從invoker
——也就是stub
——裡面拿到呼叫的方法,而後通過反射呼叫。
程式碼生成
前面提到過ds, ok := service.(DubboGrpcService)
這一句,面臨的問題是如何讓protobuf
編譯生成的程式碼能夠實現DubboGrpcService
介面呢?
有些小夥伴可能也注意到,在我貼出來的一些程式碼裡面,反射操作會根據名字來獲取method
例項,比如NewClint
方法裡面的method := reflect.ValueOf(impl).MethodByName("GetDubboStub")
這一句。這一句的impl
,即指服務的實現,也是protobuf
裡面編譯出來的,怎麼讓protobuf
編譯出來的程式碼裡面含有這個GetDubboStub
方法呢?
到這裡,答案已經呼之欲出了:修改protobuf
編譯生成程式碼的邏輯!
慶幸的是,在protobuf
裡面允許我們通過外掛的形式擴充套件我們自己的程式碼生成的邏輯。
所以我們只需要註冊一個我們自己的外掛:
然後這個外掛會把我們所需要的程式碼給嵌入進去。比如說嵌入GetDubboStub
方法:
還有DubboGrpcService
介面:
這個東西,屬於難者不會會者不難。就是如果你不知道可以通過plugin
的形式來修改生成的程式碼,那就是真難;但是如果知道了,這個東西就很簡單了——無非就是水磨工夫罷了。
歡迎加入 dubbo-go 社群
目前 dubbo-go 已經到了一個比較穩定成熟的狀態。在接下來的版本里面,我們將集中精力在雲原生上。下一個版本,我們將首先實現應用維度的服務註冊,這是一個和現有註冊模型完全不同的新的註冊模型。也是我們朝著雲原生努力的一個關鍵版本。
dubbo-go 釘釘群 23331795 歡迎你的加入。
- 加微信實戰群請加微信(註明:實戰群):gocnio
相關文章
- 如何從 InfluxDB/OpenTSDB 無縫連線到 TDengineUX
- 1+1>2,Paddle Lite與EdgeBoard無縫連線,快速實現部署應用
- 關於面向連線與面向無連線
- Microsoft Remote Desktop for Mac: 跨越界限,無縫連線,實現遠端辦公與學習ROSREMMac
- 機械行業ERP系統生產委外管理:內外無縫連線行業
- gRPC-go原始碼(1):連線管理RPCGo原始碼
- Kubernetes 與 OpenYurt 無縫轉換(命令式)
- 構建無縫整合的gRPC-Web和Istio的雲原生應用教程RPCWeb
- Akka-CQRS(10)- gRPC on SSL/TLS 安全連線RPCTLS
- 無縫輪播
- ShardingSphere如何完成與Spring家族無縫整合的?Spring
- Android 無縫換膚深入瞭解與使用Android
- gRPC(五)進階:透過TLS建立安全連線RPCTLS
- js無縫滾動JS
- 用於 PLC 與乙太網建立無線連線的模組
- gRPC學習記錄(六)--客戶端連線池RPC客戶端
- 使用iwctl連線無線網路
- 微軟無線滑鼠怎麼連線_win10系統怎麼連線無線滑鼠微軟Win10
- 無線印表機怎麼連線電腦 WIN10連線無線印表機的方法Win10
- 無線滑鼠怎麼連線電腦沒反應 無線滑鼠連線電腦步驟
- Http持久連線與HttpClient連線池HTTPclient
- fasterWhisper和MoneyPrinterPlus無縫整合AST
- win10無線網路連線步驟_win10怎麼連線無線網路Win10
- RestCloud API閘道器,無縫與原微服務框架整合RESTCloudAPI微服務框架
- 聯想無線滑鼠怎麼連線電腦連線藍芽藍芽
- mysql 遠端無法連線MySql
- bitbucket無法使用ssh連線
- centos無法建立ssl連線CentOS
- milvus 異常——無法連線
- mysql連線無許可權MySql
- AVPlayerde 無縫快進和倒放.
- CSS水平無縫滾動效果CSS
- js-字幕無縫滾動JS
- JavaScript無縫滾動 記錄JavaScript
- win10電腦如何連線無線鍵盤_win10連線無線鍵盤的步驟Win10
- 吉客雲與用友BIP資料無縫對接案例分享
- 光纖貓怎麼連線無線路由器?光纖貓連線無線路由器的方法教程路由器
- VirtualBox 本地網路連線無線狀態下連線虛擬機器虛擬機