得益於Go語言的編譯快性能高特色,在雲原生時代其做爲服務端編程語言發展迅速,尤爲是微服務領域,已逐漸造成一個良好的生態,基於Golang的微服務框架現在有不少,如go-kit、go-micro、kite、gizmo等,每一種都自有其優勢。今天就來探一探go-micro框架。
go-micro是基於Go語言實現的插件化RPC微服務框架,與go-kit,kite等微服務框架相比,它具備易上手、部署簡單、工具插件化等優勢。html
go-micro框架提供了服務發現、負載均衡、同步傳輸、異步通訊以及事件驅動等機制,它嘗試去簡化分佈式系統間的通訊,讓咱們能夠專一於自身業務邏輯的開發。因此對於新手而言,go-micro是個不錯的微服務實踐的開始。node
下圖爲官方博客提供的go-micro架構圖:git
go-micro是組件化的框架,每個基礎功能都是一個interface,方便擴展。同時,組件又是分層的,上層基於下層功能向上提供服務,總體構成go-micro框架。
go-micro的組件包括:github
全部以上組件功能共同構成一個go-micro微服務。編程
兩個微服務之間的通訊是基於C/S模型,即服務發請求方充當Client,服務接收方充當Server。
其通訊過程大體以下圖:
windows
上圖大體描繪了go-micro服務內各組件的職責與交互。架構
紙上得來終覺淺,下面就來搭建環境,實現一個簡單的基於go-micro的微服務。
爲簡單起見,client與server之間咱們使用點對點的同步方式(Transport),即無需消息中間件(Broker),註冊中心採用consul系統。負載均衡
服務註冊中心咱們選擇consul:框架
brew install consul
運行consul:啓動Consul agent的開發模式:異步
consul agent -dev
該命令快速啓動一個單節點的consul,且爲集羣的領袖
查看Consul集羣的成員:打開另外一個終端執行:
consul members
中止Agent:使用 Ctrl-C,優雅的關閉Agent
也能夠經過WebUI來查看各service狀態:http://localhost:8500/
micro是以go-micro框架爲核心的微服務管理工具,經過它能夠方便查看go-micro服務狀況。
在$GOPATH目錄下,執行go get github.com/micro/micro
,該命令會在bin目錄($GOBIN)下生成micro(.exe)工具
micro命令行工具能夠提供諸如服務列表查看、服務詳情查看、調用服務接口等功能。
protoc:Protobuf(Protocol Buffers - Google's data interchange format)編譯器:
brew install protobuf
go get github.com/micro/protobuf/{proto,protoc-gen-go}
,該命令會在bin目錄下生成protoc-gen-go(.exe)工具,protoc編譯器利用protoc-gen-go插件將.proto文件轉換爲Golang源文件go get github.com/micro/protoc-gen-micro
,該命令會在bin目錄下生成protoc-gen-micro(.exe),protoc編譯器利用protoc-gen-micro插件將.proto文件轉換爲micro代碼風格文件goprotobuf編譯參數:
-I
參數:指定import路徑,能夠指定多個-I
參數,編譯時按照順序查找,不指定時默認查找當前目錄--go_out
:Golang編譯支持,支持如下參數
- `plugins=plugin1+plugin2`:指定插件,支持grpc/micro,即:plugins=grpc+micro - `M`參數:指定導入的.proto文件路徑編譯後對應的goalng包名(不指定默認.proto文件中import語句路徑) - `import_prefix=xxx`:爲全部import路徑添加前綴,主要用於編譯子目錄內的多個proto文件 - `import_path=foo/bar`:指定未聲明package或go_package的文件的包名,最右邊的斜線前的字符會被忽略
至此,go-micro框架的編程環境已基本搭建好,接下來就是寫代碼了。
下面實現一個Hello服務:它接收一個字符串類型參數請求,返回一個字符串問候語:Hello 『參數值』。
1)定義API
建立proto/hello.proto文件:
使用protobuf文件來定義服務API接口
syntax = "proto3"; service Hello { rpc Ping(Request) returns (Response) {} } message Request { string name = 1; } message Response { string msg = 1; }
執行protoc
命令,生成當前pb文件的go實現:
protoc --go_out=plugins=micro:. ./proto/hello.proto
2)建立service
建立services/hello.go文件:
package main import ( "context" "fmt" proto "winmicro/proto" micro "github.com/micro/go-micro" ) type Hello struct{} func (h *Hello) Ping(ctx context.Context, req *proto.Request, res *proto.Response) error { res.Msg = "Hello " + req.Name return nil } func main() { service := micro.NewService( micro.Name("hellooo"), // 服務名稱 ) service.Init() proto.RegisterHelloHandler(service.Server(), new(Hello)) if err := service.Run(); err != nil { fmt.Println(err) } }
3)模擬client
建立Clients/helloclient.go文件:
package main import ( "context" "fmt" proto "winmicro/proto" micro "github.com/micro/go-micro" ) func main() { service := micro.NewService(micro.Name("hello.client")) // 客戶端服務名稱 service.Init() helloservice := proto.NewHelloService("hellooo", service.Client()) res, err := helloservice.Ping(context.TODO(), &proto.Request{Name: "World ^_^"}) if err != nil { fmt.Println(err) } fmt.Println(res.Msg) }
啓動consul以後
執行micro list services
查看當前已有服務:
> micro list services consul
執行go run services/hello.go
命令,啓動hellooo服務:
>go run services/hello.go 2018/11/29 20:18:08 Listening on [::]:61463 2018/11/29 20:18:08 Broker Listening on [::]:61464 2018/11/29 20:18:08 Registering node: hellooo-74122f56-4728-4449-a9d4-6c3c85ba2fcb ....
再次執行micro list services
查看當前已有服務:
> micro list services consul hellooo
即hellooo服務已啓動
注 經過WebUI來查看各service信息:http://localhost:8500/
請求服務
執行go run clients/helloclient.go
命令,向hellooo服務發起請求:
>go run clients/helloclient.go Hello World ^_^
https://github.com/micro/go-m...
https://micro.mu/docs/go-micr...
https://lixiangyun.gitbooks.i...
https://github.com/hb-go/micro