Go chassis 微服務開發框架實戰系列(二)

tianxiaoliang發表於2020-09-06

本章節我將專注於開發第一個微服務系統,我們將學會如何用 go chassis 開發微服務並完成微服務之間的呼叫

開發你的第一個微服務

啟動註冊中心

docker run -d -p 30100:30100 servicecomb/service-center

強烈推薦直接使用 all in one 的 docker compose 模板啟動,因為可以使用視覺化的 UI 介面。

https://github.com/go-chassis/go-chassis/blob/master/examples/docker-compose.yaml

初始化 Go 工程

go mod init github.com/go-chassis/go-chassis-examples/hello
go get github.com/go-chassis/go-chassis/v2

工程目錄規劃

可以建立一個 server(名稱任意)資料夾,這個就是一個微服務的目錄

mkdir server

目錄結構

server

+-- main.go

+-- conf

    +-- chassis.yaml

    +-- microservice.yaml

最小化配置

在 chassis.yaml 中涵蓋了幾乎所有的配置,不過想要啟動只需要 2 個簡單的配置

servicecomb:
  registry:
     address: http://127.0.0.1:30100
  protocols:
     rest:
       listenAddress: 127.0.0.1:9000

也就是服務監聽地址和註冊中心地址

在 microservice.yaml 裡定義微服務資訊,只需要一個簡單的微服務名即可,它還有大量的其他高階特性,我們將後續在高階特性中介紹

servicecomb:
  service:
    name: HelloServer

編寫業務邏輯

是時候編寫自己的 API 了

//通常持有一批API,並定義API Patterns
type HelloResource struct {
}

//業務API
func (r *HelloResource) SayHi(b *rf.Context) {
    b.Write([]byte("hello, go chassis"))
    return
}

//定義所有的API Patterns,用於API路由
func (r *HelloResource) URLPatterns() []rf.Route {
    return []rf.Route{
        {Method: http.MethodGet, Path: "/hello", ResourceFunc: r.SayHi},
    }
}

之後僅需要註冊即可

chassis.RegisterSchema("rest", &HelloResource{})

啟動服務

啟動很簡單,只需要編寫如下內容

if err := chassis.Init(); err != nil {
    openlog.Fatal("Init failed." + err.Error())
    return
}
chassis.Run()

編譯執行

go build main.go
./main

驗證:訪問 UIhttp://127.0.0.1:30103 額外可以看到自動生成的 open API 文件 直接訪問服務

curl http://127.0.0.1:9000/hello

呼叫服務

接著我們需要呼叫這個服務 建立一個新的微服務

mkdir client

定義微服務

在 chassis.yaml 中定義另一個監聽地址

servicecomb:
  registry:
      address: http://127.0.0.1:30100
  protocols:
    rest:
      listenAddress: 127.0.0.1:8000

在 microservice.yaml 中定義微服務名

servicecomb:
  service:
    name: HelloClient

# 編寫客戶端 為了簡單這裡只需要簡單的轉發即可,這裡給出完整邏輯

type SimpleResource struct {
}
//在這個方法中,呼叫上面編寫的服務
func (r *SimpleResource) SayHi(b *rf.Context) {
    req, _ := rest.NewRequest(http.MethodGet, "http://HelloServer/hello", nil)//這裡要填寫需要呼叫哪個服務,填寫服務名即可,然後就是他的api路徑
    restInvoker := core.NewRestInvoker()//併發安全,可全域性使用
    resp, err := restInvoker.ContextDo(context.TODO(), req)//執行呼叫,這時go chassis介入,執行一些列使用者不可見的計算和操作
    if err != nil {
        log.Println(err)
        return
    }
    b.Write(httputil.ReadBody(resp))//讀出服務端body體並直接透傳返回
    return
}

func (r *SimpleResource) URLPatterns() []rf.Route {
    return []rf.Route{
        {Method: http.MethodGet, Path: "/hi", ResourceFunc: r.SayHi},
    }
}

func main() {
    chassis.RegisterSchema("rest", &SimpleResource{})
    if err := chassis.Init(); err != nil {
        openlog.Fatal("Init failed." + err.Error())
        return
    }
    chassis.Run()
}

驗證:

go build main.go
./main
## 開啟另一個終端,執行
curl http://127.0.0.1:8000/hi

將返回 HelloServer 的返回結果

此時 2 個微服務例項應該同時線上

完整例子

https://github.com/go-chassis/go-chassis-examples/tree/master/hello

小知識

為了提高系統的可用性,我們通常可以通過簡單的擴容例項來達成。從概率來說這切實有效。假設一個例項的可用度為 0.995. 那麼 2 個例項並聯後,他們的可用性為

1-(1-0.995)的平方=0.999975

在訪問量大的情況下,我們也期望通過擴容來獲得線性的吞吐增長。然而吞吐能力並非隨著例項的數量呈線性增長。 通常在給定一個例項的規格後,需要進行 benchmark 測試找到該規格下,到底多大的例項數量能達到最佳價效比。後續就要通過優化程式碼來去提升吞吐了。這也是降成本的一種手法。

總結

本次,我們學會了開發簡單的微服務,並且完成了 2 者的一次呼叫。

在實際使用中,可以啟動數個服務端例項,提升服務可用性。

go chassis 通過客戶端負載均衡與註冊中新幫助遮蔽了網路拓撲的複雜性,只需要理解服務名即可。

擴充套件閱讀

註冊中心設計:https://www.jianshu.com/p/c676a69771bd

更多原創文章乾貨分享,請關注公眾號
  • Go chassis 微服務開發框架實戰系列(二)
  • 加微信實戰群請加微信(註明:實戰群):gocnio

相關文章