前言
每次技術調研總會發(fā)現(xiàn)自己學不動了怎么辦?用已有的知識來拓展要學習的新知識就好了~ by LinkinStar
最近需要調研使用 dubbo,之前完全是 0 基礎,對于 dubbo 只存在于聽說,今天上手實戰(zhàn)一把,告訴你如何快速用 go 上手 dubbo
PS:以下的學習方式適用于很多新技術
基本概念
首先學習一個技術首先要看看它的整體架構和基本概念,每個技術都有著自己的名詞解釋和實現(xiàn)方式,如果文檔齊全就簡單很多。
http://dubbo.apache.org/zh-cn/docs/user/preface/background.html
大致瀏覽了背景、需求、架構之后基本上有一個大致概念

其實整體架構和很多微服務的架構都是類似的,就是有一個注冊中心管理所有的服務列表,服務提供方先向注冊中心注冊,而消費方向注冊中心請求服務列表,通過服務列表調用最終的服務。總的來說 dubbo 將整個過程封裝在了里面,而作為使用者的我們來說更加關心業(yè)務實現(xiàn),它幫我們做好了治理的工作。
然后我抓住了幾個我想要知道的重點:
- 注冊中心可替換,官方推薦的是 zk
- 如果有變更,注冊中心將基于長連接推送變更數(shù)據(jù)給消費者,注冊中心,服務提供者,服務消費者三者之間均為長連接
- 基于軟負載均衡算法,選一臺提供者進行調用,如果調用失敗,再選另一臺調用
- 消費者在本地緩存了提供者列表
實際上手
官網文檔中也給出如果使用 golang 開發(fā),那么有 https://github.com/apache/dubbo-go 可以用,那么廢話不多說,上手實踐一把先。因為你看再多,都比不上實踐一把來學的快。
環(huán)境搭建
大多數(shù)教程就會跟你說,一個 helloWorld 需要 zookeeper 環(huán)境,但是不告訴你如何搭建,因為這對于他們來說太簡單了,而我不一樣,我是 0 基礎,那如何快速搭建一個需要調研項目的環(huán)境呢?最好的方式就是 docker。
version: '3'
services:
zookeeper:
image: zookeeper
ports:
- 2181:2181
admin:
image: apache/dubbo-admin
depends_on:
- zookeeper
ports:
- 8080:8080
environment:
- admin.registry.address=zookeeper://zookeeper:2181
- admin.config-center=zookeeper://zookeeper:2181
- admin.metadata-report.address=zookeeper://zookeeper:2181
version: '3'
services:
zookeeper:
image: zookeeper
ports:
- 2181:2181
admin:
image: chenchuxin/dubbo-admin
depends_on:
- zookeeper
ports:
- 8080:8080
environment:
- dubbo.registry.address=zookeeper://zookeeper:2181
- dubbo.admin.root.password=root
- dubbo.admin.guest.password=guest
上面兩個 docker-compose 文件一個是官方提供的管理工具,一個包含的是個人修改之后的管理工具,記住這里有個用戶名密碼是 root-root,看你喜歡
廢話不多說,直接創(chuàng)建 docker-compose.yaml 然后 docker-compose up 你就得到了一個環(huán)境,棒??
樣例下載
有的技術會給出官方的實驗樣例,dubbo-go 也不例外
https://github.com/apache/dubbo-samples
里面包含了 go 和 java 的樣例,有了它你就能快速上手了,把它下載到本地
樣例運行
首先要做的第一步就是把 helloworld 給跑起來,進入 golang 目錄,里面有個 README.md 看一下。然后開搞。
打開一個終端運行服務方
export ARCH=mac
export ENV=dev
cd helloworld/dubbo/go-server
sh ./assembly/$ARCH/$ENV.sh
cd ./target/linux/user_info_server-0.3.1-20190517-0930-release
sh ./bin/load.sh start
打開另一個終端運行客戶端
export ARCH=mac
export ENV=dev
cd helloworld/dubbo/go-client
sh ./assembly/$ARCH/$ENV.sh
cd ./target/linux/user_info_client-0.3.1-20190517-0921-release
sh ./bin/load_user_info_client.sh start
啟動過程中會出現(xiàn)一些警告,問題不大,如果成功,那么客戶端會有一個調用服務端的請求,并在控制臺中以白色底色進行打印

java 的服務也有相對應的啟動方式,按照 README 中所說明的也可以進行注冊和調用,并且 java 和 go 之間是可以互相調用的
查看服務
因為我們部署的時候有一個 dubbo-admin 用于管理 zk 上注冊的服務,我們可以訪問本地的 8080 端口看到對應的服務情況

至此你應該已經對于整體的鏈路調用有一個大致的認識,結合之前官網文檔的中的架構圖,應該也清晰了。
如何使用
那么現(xiàn)在你已經運行起來了,那么勢必就要來看看具體是如何進行使用的了。
服務端
服務端,也就是服務提供者;
位置在:dubbo-samples/golang/helloworld/dubbo/go-server/app
// 將服務進行注冊
config.SetProviderService(new(UserProvider))
// 注冊對象的hessian序列化
hessian.RegisterPOJO(&User{})
是不是看起來其實很簡單,其實重點就是上面兩句代碼了
對于服務本身來說
type UserProvider struct {
}
func (u *UserProvider) GetUser(ctx context.Context, req []interface{}) (*User, error) {
println("req:%#v", req)
rsp := User{"A001", "Alex Stocks", 18, time.Now()}
println("rsp:%#v", rsp)
return &rsp, nil
}
func (u *UserProvider) Reference() string {
return "UserProvider"
}
其實就是需要實現(xiàn)下面那個接口就可以了
// rpc service interface
type RPCService interface {
Reference() string // rpc service id or reference id
}
其中有一步驟不要忘記了是config.Load(),會加載配置文件的相關配置,不然你以為注冊中心的地址等等是在哪里配置的呢?
客戶端
看了服務端,其實客戶端也就很簡單了
config.SetConsumerService(userProvider)
hessian.RegisterPOJO(&User{})
其實也是差不多的,也需要注冊一個消費服務,并將序列化方式給注冊上去
user := &User{}
err := userProvider.GetUser(context.TODO(), []interface{}{"A001"}, user)
使用也就很簡單了,同樣的也需要實現(xiàn) Reference 接口
type UserProvider struct {
GetUser func(ctx context.Context, req []interface{}, rsp *User) error
}
func (u *UserProvider) Reference() string {
return "UserProvider"
}
回頭想想
當我們看完了代碼的上的使用,再回頭想想 dubbo 的作用,你就會發(fā)現(xiàn)其實 dubbo 幫你做的事情真的屏蔽了很多。
- 你不需要關心服務是怎么注冊的
- 你不需要關心服務是怎么獲取的
- 你不需要關系服務是怎么調用的
- 甚至序列化的過程都是基本透明的
想對比來說,如果讓你自己去是實現(xiàn)微服務,那是不是說,你需要實現(xiàn)服務的拉取,服務的負載均衡,服務的發(fā)現(xiàn),序列化.....
這下你應該明白了 dubbo 是做什么的也就明白了它為什么會出現(xiàn)了
其他能力
當你學習了一個技術的基本使用之后,要學習其他的能力,以便在使用的過程中不會出現(xiàn)自己重復造輪子或者說有輪子沒用到的情況,https://github.com/apache/dubbo-samples 不止有 helloworld 還要很多別的案例供你參考,你可以繼續(xù)看看并進行試驗。
支持擴展
https://github.com/apache/dubbo-go
在 Feature list 中列舉了 dubbo-go 所支持的相關功能,比如序列化,比如注冊中心,在比如過濾器。
也就是說,在使用 dubbo-go 的時候相關功能都是插件化的,想用什么就看你自己了,比如注冊中心我想用 etcd,比如調用的協(xié)議我想換成 grpc 都可以。
相關問題
對于一個技術調研,那么肯定會有相關問題等著你去發(fā)現(xiàn)去考慮。
下面是我能想到的一些問題:
- 當前 dubbo-go 的版本最高在 1.4,所對應的 dubbo 版本應該是 2.6.x,如果調用更高版本的服務是否會有問題
- java 和 go 之間互相調用,各種類型轉換之間是否存在問題,是否容易出現(xiàn)無法正確反序列化的問題
- ....
后續(xù)學習
那么上面只是說能讓你上手 dubbo-go,但是實際使用可能存在距離。為什么這么說呢?如果你在不動里面任何的原理情況下,那么如果遇到問題,你很可能就束手無策了。比如如果線上服務無法正常發(fā)現(xiàn),你應該如何排查?調用過程中出現(xiàn)問題如何定位?
所以后續(xù)你需要做的是:
- 看看整體設計架構和思路,明白整條鏈路調用過程和規(guī)則
- 學習它的接口設計,為什么別人設計的接口能兼容那么多的注冊中心?如果讓你來設計你怎么設計呢?
- 性能也很重要,網上說性能很不錯,為什么呢?什么地方做了優(yōu)化,負載均衡的算法是怎么樣的,你能自定義嗎?
總結
總的來說,對于 dubbo-go 整體的使用上還是非常好上手的,自己想了一下,如果當前項目想要接入的話,主要是服務的暴露、序列化方式、鑒權調整等存在開發(fā)工作。
上面磚頭也拋的差不多了,對于你快速上手應該沒有問題了,剩下的就要靠你自己了。