go-micro 框架初探

得益於Go語言的編譯快性能高特色,在雲原生時代其做爲服務端編程語言發展迅速,尤爲是微服務領域,已逐漸造成一個良好的生態,基於Golang的微服務框架現在有不少,如go-kit、go-micro、kite、gizmo等,每一種都自有其優勢。今天就來探一探go-micro框架。

1、go-micro 是什麼

go-micro是基於Go語言實現的插件化RPC微服務框架,與go-kit,kite等微服務框架相比,它具備易上手、部署簡單、工具插件化等優勢。html

go-micro框架提供了服務發現、負載均衡、同步傳輸、異步通訊以及事件驅動等機制,它嘗試去簡化分佈式系統間的通訊,讓咱們能夠專一於自身業務邏輯的開發。因此對於新手而言,go-micro是個不錯的微服務實踐的開始。node

2、go-micro 架構

2.1 分層架構

下圖爲官方博客提供的go-micro架構圖:git

clipboard.png

go-micro是組件化的框架,每個基礎功能都是一個interface,方便擴展。同時,組件又是分層的,上層基於下層功能向上提供服務,總體構成go-micro框架。
go-micro的組件包括:github

  • Registry組件:服務發現組件,提供服務發現機制:解析服務名字至服務地址。目前支持的註冊中心有consul、etcd、 zookeeper、dns、gossip等
  • Selector組件:構建在Registry之上的客戶端智能負載均衡組件,用於Client組件對Registry返回的服務進行智能選擇。
  • Broker組件:發佈/訂閱組件,服務之間基於消息中間件的異步通訊方式,默認使用http方式,線上一般使用消息中間件,如Kafka、RabbitMQ等。
  • Transport組件:服務之間同步通訊方式。
  • Codec組件:服務之間消息的編碼/解碼。
  • Server組件:服務主體,該組件基於上面的Registry/Selector/Transport/Broker組件,對外提供一個統一的服務請求入口。
  • Client組件:提供訪問微服務的客戶端。相似Server組件,它也是經過Registry/Selector/Transport/Broker組件實現查找服務、負載均衡、同步通訊、異步消息等功能。

全部以上組件功能共同構成一個go-micro微服務。編程

2.2 微服務之間通訊

兩個微服務之間的通訊是基於C/S模型,即服務發請求方充當Client,服務接收方充當Server。
其通訊過程大體以下圖:
clipboard.pngwindows

上圖大體描繪了go-micro服務內各組件的職責與交互。架構

3、實現一個簡單的微服務

紙上得來終覺淺,下面就來搭建環境,實現一個簡單的基於go-micro的微服務。
爲簡單起見,client與server之間咱們使用點對點的同步方式(Transport),即無需消息中間件(Broker),註冊中心採用consul系統。負載均衡

3.1 安裝consul - 註冊中心

服務註冊中心咱們選擇consul:框架

運行consul:啓動Consul agent的開發模式:異步

consul agent -dev

該命令快速啓動一個單節點的consul,且爲集羣的領袖

查看Consul集羣的成員:打開另外一個終端執行:

consul members

中止Agent:使用 Ctrl-C,優雅的關閉Agent

也能夠經過WebUI來查看各service狀態:http://localhost:8500/

3.2 安裝micro:微服務管理工具

micro是以go-micro框架爲核心的微服務管理工具,經過它能夠方便查看go-micro服務狀況。

在$GOPATH目錄下,執行go get github.com/micro/micro,該命令會在bin目錄($GOBIN)下生成micro(.exe)工具
micro命令行工具能夠提供諸如服務列表查看、服務詳情查看、調用服務接口等功能。

3.3 安裝goprotobuf相關工具:GRPC相關工具

  • protoc:Protobuf(Protocol Buffers - Google's data interchange format)編譯器:

    • windows下直接下載 相關win的zip壓縮文件(內含protoc.exe)
    • mac: brew install protobuf
  • protoc-gen-go:goprotobuf 提供的 Protobuf 插件:在$GOPATH目錄下執行go get github.com/micro/protobuf/{proto,protoc-gen-go},該命令會在bin目錄下生成protoc-gen-go(.exe)工具,protoc編譯器利用protoc-gen-go插件將.proto文件轉換爲Golang源文件
  • protoc-gen-micro(Protobuf code generation for micro):在$GOPATH目錄下執行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的文件的包名,最右邊的斜線前的字符會被忽略

3.4 編寫一個簡單的Hello服務

至此,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)
}

3.5 運行Hello服務

啓動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 ^_^

References

https://github.com/micro/go-m...
https://micro.mu/docs/go-micr...
https://lixiangyun.gitbooks.i...
https://github.com/hb-go/micro

相關文章
相關標籤/搜索